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
ansible/vars/manager.py CHANGED
@@ -19,38 +19,65 @@ from __future__ import annotations
19
19
 
20
20
  import os
21
21
  import sys
22
+ import typing as t
22
23
 
23
24
  from collections import defaultdict
24
- from collections.abc import Mapping, MutableMapping, Sequence
25
- from hashlib import sha1
26
-
27
- from jinja2.exceptions import UndefinedError
25
+ from collections.abc import Mapping, MutableMapping
28
26
 
29
27
  from ansible import constants as C
30
- from ansible.errors import AnsibleError, AnsibleParserError, AnsibleUndefinedVariable, AnsibleFileNotFound, AnsibleAssertionError
28
+ from ansible.module_utils._internal import _deprecator
29
+ from ansible.module_utils._internal._datatag import _tags
30
+ from ansible.errors import (AnsibleError, AnsibleParserError, AnsibleUndefinedVariable, AnsibleFileNotFound,
31
+ AnsibleAssertionError, AnsibleValueOmittedError)
31
32
  from ansible.inventory.host import Host
32
33
  from ansible.inventory.helpers import sort_groups, get_group_vars
33
- from ansible.module_utils.common.text.converters import to_text
34
+ from ansible.inventory.manager import InventoryManager
35
+ from ansible.module_utils.datatag import native_type_name
34
36
  from ansible.module_utils.six import text_type
35
- from ansible.vars.fact_cache import FactCache
36
- from ansible.template import Templar
37
+ from ansible.parsing.dataloader import DataLoader
38
+ from ansible._internal._templating._engine import TemplateEngine
39
+ from ansible.plugins.loader import cache_loader
37
40
  from ansible.utils.display import Display
38
41
  from ansible.utils.vars import combine_vars, load_extra_vars, load_options_vars
39
- from ansible.utils.unsafe_proxy import wrap_var
40
42
  from ansible.vars.clean import namespace_facts, clean_facts
43
+ from ansible.vars.hostvars import HostVars
41
44
  from ansible.vars.plugins import get_vars_from_inventory_sources, get_vars_from_path
42
45
  from ansible.vars.reserved import warn_if_reserved
43
46
 
47
+ if t.TYPE_CHECKING:
48
+ from ansible.playbook import Play
49
+ from ansible.playbook.task import Task
50
+
44
51
  display = Display()
45
52
 
53
+ # deprecated: description='enable top-level facts deprecation' core_version='2.20'
54
+ # _DEPRECATE_TOP_LEVEL_FACT_TAG = _tags.Deprecated(
55
+ # msg='Top-level facts are deprecated.',
56
+ # version='2.24',
57
+ # deprecator=_deprecator.ANSIBLE_CORE_DEPRECATOR,
58
+ # help_text='Use `ansible_facts` instead.',
59
+ # )
60
+
61
+
62
+ def _deprecate_top_level_fact(value: t.Any) -> t.Any:
63
+ """
64
+ Deprecate the given top-level fact value.
65
+ The inner values are shared to aid in message de-duplication across hosts/values, and reduce intra-process memory usage.
66
+ Unique tag instances are required to achieve the correct de-duplication within a top-level templating operation.
67
+ """
68
+ # deprecated: description='enable top-level facts deprecation' core_version='2.20'
69
+ # return _DEPRECATE_TOP_LEVEL_FACT_TAG.tag(value)
70
+ return value
71
+
46
72
 
47
73
  def preprocess_vars(a):
48
- '''
74
+ """
49
75
  Ensures that vars contained in the parameter passed in are
50
76
  returned as a list of dictionaries, to ensure for instance
51
77
  that vars loaded from a file conform to an expected state.
52
- '''
78
+ """
53
79
 
80
+ # FIXME: this does not properly handle omit, undefined, or dynamic structure from templated `vars` ; templating should be done earlier
54
81
  if a is None:
55
82
  return None
56
83
  elif not isinstance(a, list):
@@ -60,7 +87,11 @@ def preprocess_vars(a):
60
87
 
61
88
  for item in data:
62
89
  if not isinstance(item, MutableMapping):
63
- raise AnsibleError("variable files must contain either a dictionary of variables, or a list of dictionaries. Got: %s (%s)" % (a, type(a)))
90
+ raise AnsibleParserError(
91
+ message="Invalid variable file contents.",
92
+ obj=item,
93
+ help_text="Variable files must contain either a dictionary of variables, or a list of dictionaries.",
94
+ )
64
95
 
65
96
  return data
66
97
 
@@ -70,16 +101,19 @@ class VariableManager:
70
101
  _ALLOWED = frozenset(['plugins_by_group', 'groups_plugins_play', 'groups_plugins_inventory', 'groups_inventory',
71
102
  'all_plugins_play', 'all_plugins_inventory', 'all_inventory'])
72
103
 
73
- def __init__(self, loader=None, inventory=None, version_info=None):
74
- self._nonpersistent_fact_cache = defaultdict(dict)
75
- self._vars_cache = defaultdict(dict)
76
- self._extra_vars = defaultdict(dict)
77
- self._host_vars_files = defaultdict(dict)
78
- self._group_vars_files = defaultdict(dict)
104
+ _PLAY_HOSTS_DEPRECATED_TAG = _tags.Deprecated(
105
+ msg='The `play_hosts` magic variable is deprecated.',
106
+ version='2.23',
107
+ deprecator=_deprecator.ANSIBLE_CORE_DEPRECATOR,
108
+ help_text='Use `ansible_play_batch` instead.',
109
+ )
110
+
111
+ def __init__(self, loader: DataLoader | None = None, inventory: InventoryManager | None = None, version_info: dict[str, str] | None = None) -> None:
112
+ self._nonpersistent_fact_cache: defaultdict[str, dict] = defaultdict(dict)
113
+ self._vars_cache: defaultdict[str, dict] = defaultdict(dict)
79
114
  self._inventory = inventory
80
115
  self._loader = loader
81
- self._hostvars = None
82
- self._omit_token = '__omit_place_holder__%s' % sha1(os.urandom(64)).hexdigest()
116
+ self._hostvars: HostVars | None = None
83
117
 
84
118
  self._options_vars = load_options_vars(version_info)
85
119
 
@@ -93,41 +127,12 @@ class VariableManager:
93
127
 
94
128
  # load fact cache
95
129
  try:
96
- self._fact_cache = FactCache()
97
- except AnsibleError as e:
130
+ self._fact_cache = cache_loader.get(C.CACHE_PLUGIN)
131
+ except Exception as ex:
98
132
  # bad cache plugin is not fatal error
99
- # fallback to a dict as in memory cache
100
- display.warning(to_text(e))
101
- self._fact_cache = {}
102
-
103
- def __getstate__(self):
104
- data = dict(
105
- fact_cache=self._fact_cache,
106
- np_fact_cache=self._nonpersistent_fact_cache,
107
- vars_cache=self._vars_cache,
108
- extra_vars=self._extra_vars,
109
- host_vars_files=self._host_vars_files,
110
- group_vars_files=self._group_vars_files,
111
- omit_token=self._omit_token,
112
- options_vars=self._options_vars,
113
- inventory=self._inventory,
114
- safe_basedir=self.safe_basedir,
115
- )
116
- return data
117
-
118
- def __setstate__(self, data):
119
- self._fact_cache = data.get('fact_cache', defaultdict(dict))
120
- self._nonpersistent_fact_cache = data.get('np_fact_cache', defaultdict(dict))
121
- self._vars_cache = data.get('vars_cache', defaultdict(dict))
122
- self._extra_vars = data.get('extra_vars', dict())
123
- self._host_vars_files = data.get('host_vars_files', defaultdict(dict))
124
- self._group_vars_files = data.get('group_vars_files', defaultdict(dict))
125
- self._omit_token = data.get('omit_token', '__omit_place_holder__%s' % sha1(os.urandom(64)).hexdigest())
126
- self._inventory = data.get('inventory', None)
127
- self._options_vars = data.get('options_vars', dict())
128
- self.safe_basedir = data.get('safe_basedir', False)
129
- self._loader = None
130
- self._hostvars = None
133
+ # fallback to builtin memory cache plugin
134
+ display.error_as_warning(None, ex)
135
+ self._fact_cache = cache_loader.get('ansible.builtin.memory') # use FQCN to ensure the builtin version is used
131
136
 
132
137
  @property
133
138
  def extra_vars(self):
@@ -136,9 +141,18 @@ class VariableManager:
136
141
  def set_inventory(self, inventory):
137
142
  self._inventory = inventory
138
143
 
139
- def get_vars(self, play=None, host=None, task=None, include_hostvars=True, include_delegate_to=False, use_cache=True,
140
- _hosts=None, _hosts_all=None, stage='task'):
141
- '''
144
+ def get_vars(
145
+ self,
146
+ play: Play | None = None,
147
+ host: Host | None = None,
148
+ task: Task | None = None,
149
+ include_hostvars: bool = True,
150
+ use_cache: bool = True,
151
+ _hosts: list[str] | None = None,
152
+ _hosts_all: list[str] | None = None,
153
+ stage: str = 'task',
154
+ ) -> dict[str, t.Any]:
155
+ """
142
156
  Returns the variables, with optional "context" given via the parameters
143
157
  for the play, host, and task (which could possibly result in different
144
158
  sets of variables being returned due to the additional context).
@@ -146,7 +160,6 @@ class VariableManager:
146
160
  The order of precedence is:
147
161
  - play->roles->get_default_vars (if there is a play context)
148
162
  - group_vars_files[host] (if there is a host context)
149
- - host_vars_files[host] (if there is a host context)
150
163
  - host->get_vars (if there is a host context)
151
164
  - fact_cache[host] (if there is a host context)
152
165
  - play vars (if there is a play context)
@@ -159,16 +172,11 @@ class VariableManager:
159
172
  ``_hosts`` and ``_hosts_all`` should be considered private args, with only internal trusted callers relying
160
173
  on the functionality they provide. These arguments may be removed at a later date without a deprecation
161
174
  period and without warning.
162
- '''
163
- if include_delegate_to:
164
- display.deprecated(
165
- "`VariableManager.get_vars`'s argument `include_delegate_to` has no longer any effect.",
166
- version="2.19",
167
- )
175
+ """
168
176
 
169
177
  display.debug("in VariableManager get_vars()")
170
178
 
171
- all_vars = dict()
179
+ all_vars: dict[str, t.Any] = dict()
172
180
  magic_variables = self._get_magic_variables(
173
181
  play=play,
174
182
  host=host,
@@ -178,21 +186,11 @@ class VariableManager:
178
186
  _hosts_all=_hosts_all,
179
187
  )
180
188
 
181
- _vars_sources = {}
182
-
183
189
  def _combine_and_track(data, new_data, source):
184
- '''
185
- Wrapper function to update var sources dict and call combine_vars()
186
-
187
- See notes in the VarsWithSources docstring for caveats and limitations of the source tracking
188
- '''
190
+ # FIXME: this no longer does any tracking, only a slight optimization for empty new_data
189
191
  if new_data == {}:
190
192
  return data
191
193
 
192
- if C.DEFAULT_DEBUG:
193
- # Populate var sources dict
194
- for key in new_data:
195
- _vars_sources[key] = source
196
194
  return combine_vars(data, new_data)
197
195
 
198
196
  # default for all cases
@@ -226,33 +224,15 @@ class VariableManager:
226
224
  if host:
227
225
  # THE 'all' group and the rest of groups for a host, used below
228
226
  all_group = self._inventory.groups.get('all')
229
- host_groups = sort_groups([g for g in host.get_groups() if g.name not in ['all']])
230
-
231
- def _get_plugin_vars(plugin, path, entities):
232
- data = {}
233
- try:
234
- data = plugin.get_vars(self._loader, path, entities)
235
- except AttributeError:
236
- try:
237
- for entity in entities:
238
- if isinstance(entity, Host):
239
- data |= plugin.get_host_vars(entity.name)
240
- else:
241
- data |= plugin.get_group_vars(entity.name)
242
- except AttributeError:
243
- if hasattr(plugin, 'run'):
244
- raise AnsibleError("Cannot use v1 type vars plugin %s from %s" % (plugin._load_name, plugin._original_path))
245
- else:
246
- raise AnsibleError("Invalid vars plugin %s from %s" % (plugin._load_name, plugin._original_path))
247
- return data
227
+ host_groups = sort_groups([g for g in host.get_groups() if g.name != 'all'])
248
228
 
249
229
  # internal functions that actually do the work
250
230
  def _plugins_inventory(entities):
251
- ''' merges all entities by inventory source '''
231
+ """ merges all entities by inventory source """
252
232
  return get_vars_from_inventory_sources(self._loader, self._inventory._sources, entities, stage)
253
233
 
254
234
  def _plugins_play(entities):
255
- ''' merges all entities adjacent to play '''
235
+ """ merges all entities adjacent to play """
256
236
  data = {}
257
237
  for path in basedirs:
258
238
  data = _combine_and_track(data, get_vars_from_path(self._loader, path, entities, stage), "path '%s'" % path)
@@ -269,22 +249,22 @@ class VariableManager:
269
249
  return _plugins_play([all_group])
270
250
 
271
251
  def groups_inventory():
272
- ''' gets group vars from inventory '''
252
+ """ gets group vars from inventory """
273
253
  return get_group_vars(host_groups)
274
254
 
275
255
  def groups_plugins_inventory():
276
- ''' gets plugin sources from inventory for groups '''
256
+ """ gets plugin sources from inventory for groups """
277
257
  return _plugins_inventory(host_groups)
278
258
 
279
259
  def groups_plugins_play():
280
- ''' gets plugin sources from play for groups '''
260
+ """ gets plugin sources from play for groups """
281
261
  return _plugins_play(host_groups)
282
262
 
283
263
  def plugins_by_groups():
284
- '''
264
+ """
285
265
  merges all plugin sources by group,
286
266
  This should be used instead, NOT in combination with the other groups_plugins* functions
287
- '''
267
+ """
288
268
  data = {}
289
269
  for group in host_groups:
290
270
  data[group] = _combine_and_track(data[group], _plugins_inventory(group), "inventory group_vars for '%s'" % group)
@@ -308,15 +288,20 @@ class VariableManager:
308
288
  # finally, the facts caches for this host, if it exists
309
289
  # TODO: cleaning of facts should eventually become part of taskresults instead of vars
310
290
  try:
311
- facts = wrap_var(self._fact_cache.get(host.name, {}))
291
+ try:
292
+ facts = self._fact_cache.get(host.name)
293
+ except KeyError:
294
+ facts = {}
295
+
312
296
  all_vars |= namespace_facts(facts)
313
297
 
314
298
  # push facts to main namespace
315
299
  if C.INJECT_FACTS_AS_VARS:
316
- all_vars = _combine_and_track(all_vars, wrap_var(clean_facts(facts)), "facts")
300
+ deprecated_facts_vars = {k: _deprecate_top_level_fact(v) for k, v in clean_facts(facts).items()}
301
+ all_vars = _combine_and_track(all_vars, deprecated_facts_vars, "facts")
317
302
  else:
318
303
  # always 'promote' ansible_local
319
- all_vars = _combine_and_track(all_vars, wrap_var({'ansible_local': facts.get('ansible_local', {})}), "facts")
304
+ all_vars = _combine_and_track(all_vars, {'ansible_local': facts.get('ansible_local', {})}, "facts")
320
305
  except KeyError:
321
306
  pass
322
307
 
@@ -324,63 +309,68 @@ class VariableManager:
324
309
  all_vars = _combine_and_track(all_vars, play.get_vars(), "play vars")
325
310
 
326
311
  vars_files = play.get_vars_files()
327
- try:
328
- for vars_file_item in vars_files:
329
- # create a set of temporary vars here, which incorporate the extra
330
- # and magic vars so we can properly template the vars_files entries
331
- # NOTE: this makes them depend on host vars/facts so things like
332
- # ansible_facts['os_distribution'] can be used, ala include_vars.
333
- # Consider DEPRECATING this in the future, since we have include_vars ...
334
- temp_vars = combine_vars(all_vars, self._extra_vars)
335
- temp_vars = combine_vars(temp_vars, magic_variables)
336
- templar = Templar(loader=self._loader, variables=temp_vars)
337
-
338
- # we assume each item in the list is itself a list, as we
339
- # support "conditional includes" for vars_files, which mimics
340
- # the with_first_found mechanism.
341
- vars_file_list = vars_file_item
342
- if not isinstance(vars_file_list, list):
343
- vars_file_list = [vars_file_list]
344
-
345
- # now we iterate through the (potential) files, and break out
346
- # as soon as we read one from the list. If none are found, we
347
- # raise an error, which is silently ignored at this point.
348
- try:
349
- for vars_file in vars_file_list:
350
- vars_file = templar.template(vars_file)
351
- if not (isinstance(vars_file, Sequence)):
352
- raise AnsibleError(
353
- "Invalid vars_files entry found: %r\n"
354
- "vars_files entries should be either a string type or "
355
- "a list of string types after template expansion" % vars_file
356
- )
357
- try:
358
- play_search_stack = play.get_search_path()
359
- found_file = self._loader.path_dwim_relative_stack(play_search_stack, 'vars', vars_file)
360
- data = preprocess_vars(self._loader.load_from_file(found_file, unsafe=True, cache='vaulted'))
361
- if data is not None:
362
- for item in data:
363
- all_vars = _combine_and_track(all_vars, item, "play vars_files from '%s'" % vars_file)
364
- break
365
- except AnsibleFileNotFound:
366
- # we continue on loader failures
367
- continue
368
- except AnsibleParserError:
369
- raise
370
- except (UndefinedError, AnsibleUndefinedVariable):
371
- if host is not None and self._fact_cache.get(host.name, dict()).get('module_setup') and task is not None:
372
- raise AnsibleUndefinedVariable("an undefined variable was found when attempting to template the vars_files item '%s'"
373
- % vars_file_item, obj=vars_file_item)
374
- else:
375
- # we do not have a full context here, and the missing variable could be because of that
376
- # so just show a warning and continue
377
- display.vvv("skipping vars_file '%s' due to an undefined variable" % vars_file_item)
312
+
313
+ for vars_file_item in vars_files:
314
+ # create a set of temporary vars here, which incorporate the extra
315
+ # and magic vars so we can properly template the vars_files entries
316
+ # NOTE: this makes them depend on host vars/facts so things like
317
+ # ansible_facts['os_distribution'] can be used, ala include_vars.
318
+ # Consider DEPRECATING this in the future, since we have include_vars ...
319
+ temp_vars = combine_vars(all_vars, self._extra_vars)
320
+ temp_vars = combine_vars(temp_vars, magic_variables)
321
+ templar = TemplateEngine(loader=self._loader, variables=temp_vars)
322
+
323
+ # we assume each item in the list is itself a list, as we
324
+ # support "conditional includes" for vars_files, which mimics
325
+ # the with_first_found mechanism.
326
+ vars_file_list = vars_file_item
327
+ if not isinstance(vars_file_list, list):
328
+ vars_file_list = [vars_file_list]
329
+
330
+ # now we iterate through the (potential) files, and break out
331
+ # as soon as we read one from the list. If none are found, we
332
+ # raise an error, which is silently ignored at this point.
333
+ try:
334
+ for vars_file in vars_file_list:
335
+ vars_file = templar.template(vars_file)
336
+ if not (isinstance(vars_file, str)):
337
+ raise AnsibleParserError(
338
+ message=f"Invalid `vars_files` value of type {native_type_name(vars_file)!r}.",
339
+ obj=vars_file,
340
+ help_text="A `vars_files` value should either be a string or list of strings.",
341
+ )
342
+ try:
343
+ play_search_stack = play.get_search_path()
344
+ found_file = self._loader.path_dwim_relative_stack(play_search_stack, 'vars', vars_file)
345
+ data = preprocess_vars(self._loader.load_from_file(found_file, unsafe=True, cache='vaulted', trusted_as_template=True))
346
+ if data is not None:
347
+ for item in data:
348
+ all_vars = _combine_and_track(all_vars, item, "play vars_files from '%s'" % vars_file)
349
+ display.vvv(f"Read `vars_file` {found_file!r}.")
350
+ break
351
+ except AnsibleFileNotFound:
352
+ # we continue on loader failures
378
353
  continue
354
+ except AnsibleParserError:
355
+ raise
356
+ except AnsibleUndefinedVariable:
357
+ raise
358
+ except Exception as ex:
359
+ raise AnsibleParserError(f"Error reading `vars_files` file {vars_file!r}.", obj=vars_file) from ex
360
+
361
+ except AnsibleUndefinedVariable as ex:
362
+ if host is not None:
363
+ try:
364
+ facts = self._fact_cache.get(host.name)
365
+ except KeyError:
366
+ pass
367
+ else:
368
+ if facts.get('module_setup') and task is not None:
369
+ raise AnsibleUndefinedVariable("an undefined variable was found when attempting to template the vars_files item '%s'"
370
+ % vars_file_item, obj=vars_file_item) from ex
379
371
 
380
- display.vvv("Read vars_file '%s'" % vars_file_item)
381
- except TypeError:
382
- raise AnsibleParserError("Error while reading vars files - please supply a list of file names. "
383
- "Got '%s' of type %s" % (vars_files, type(vars_files)))
372
+ display.warning("skipping vars_file item due to an undefined variable", obj=vars_file_item)
373
+ continue
384
374
 
385
375
  # We now merge in all exported vars from all roles in the play (very high precedence)
386
376
  for role in play.roles:
@@ -417,7 +407,7 @@ class VariableManager:
417
407
  all_vars = _combine_and_track(all_vars, self._extra_vars, "extra vars")
418
408
 
419
409
  # before we add 'reserved vars', check we didn't add any reserved vars
420
- warn_if_reserved(all_vars.keys())
410
+ warn_if_reserved(all_vars)
421
411
 
422
412
  # magic variables
423
413
  all_vars = _combine_and_track(all_vars, magic_variables, "magic vars")
@@ -433,17 +423,21 @@ class VariableManager:
433
423
  all_vars['vars'] = all_vars.copy()
434
424
 
435
425
  display.debug("done with get_vars()")
436
- if C.DEFAULT_DEBUG:
437
- # Use VarsWithSources wrapper class to display var sources
438
- return VarsWithSources.new_vars_with_sources(all_vars, _vars_sources)
439
- else:
440
- return all_vars
426
+ return all_vars
427
+
428
+ def _facts_gathered_for_host(self, hostname) -> bool:
429
+ try:
430
+ facts = self._fact_cache.get(hostname)
431
+ except KeyError:
432
+ facts = {}
433
+
434
+ return bool(facts.get('_ansible_facts_gathered', False))
441
435
 
442
436
  def _get_magic_variables(self, play, host, task, include_hostvars, _hosts=None, _hosts_all=None):
443
- '''
437
+ """
444
438
  Returns a dictionary of so-called "magic" variables in Ansible,
445
439
  which are special variables we set internally for use.
446
- '''
440
+ """
447
441
 
448
442
  variables = {}
449
443
  variables['playbook_dir'] = os.path.abspath(self._loader.get_basedir())
@@ -480,13 +474,13 @@ class VariableManager:
480
474
  if self._inventory is not None:
481
475
  variables['groups'] = self._inventory.get_groups_dict()
482
476
  if play:
483
- templar = Templar(loader=self._loader)
484
- if not play.finalized and templar.is_template(play.hosts):
485
- pattern = 'all'
486
- else:
487
- pattern = play.hosts or 'all'
488
477
  # add the list of hosts in the play, as adjusted for limit/filters
489
478
  if not _hosts_all:
479
+ if not play.finalized and TemplateEngine().is_template(play.hosts):
480
+ pattern = 'all'
481
+ else:
482
+ pattern = play.hosts or 'all'
483
+
490
484
  _hosts_all = [h.name for h in self._inventory.get_hosts(pattern=pattern, ignore_restrictions=True)]
491
485
  if not _hosts:
492
486
  _hosts = [h.name for h in self._inventory.get_hosts()]
@@ -495,12 +489,9 @@ class VariableManager:
495
489
  variables['ansible_play_hosts'] = [x for x in variables['ansible_play_hosts_all'] if x not in play._removed_hosts]
496
490
  variables['ansible_play_batch'] = [x for x in _hosts if x not in play._removed_hosts]
497
491
 
498
- # DEPRECATED: play_hosts should be deprecated in favor of ansible_play_batch,
499
- # however this would take work in the templating engine, so for now we'll add both
500
- variables['play_hosts'] = variables['ansible_play_batch']
492
+ # use a static tag instead of `deprecate_value` to avoid stackwalk in a hot code path
493
+ variables['play_hosts'] = self._PLAY_HOSTS_DEPRECATED_TAG.tag(variables['ansible_play_batch'])
501
494
 
502
- # the 'omit' value allows params to be left out if the variable they are based on is undefined
503
- variables['omit'] = self._omit_token
504
495
  # Set options vars
505
496
  for option, option_value in self._options_vars.items():
506
497
  variables[option] = option_value
@@ -517,56 +508,65 @@ class VariableManager:
517
508
  Not used directly be VariableManager, but used primarily within TaskExecutor
518
509
  """
519
510
  delegated_vars = {}
520
- delegated_host_name = None
521
- if task.delegate_to:
522
- delegated_host_name = templar.template(task.delegate_to, fail_on_undefined=False)
511
+ delegated_host_name = ... # sentinel value distinct from empty/None, which are errors
523
512
 
524
- # no need to do work if omitted
525
- if delegated_host_name != self._omit_token:
526
-
527
- if not delegated_host_name:
528
- raise AnsibleError('Empty hostname produced from delegate_to: "%s"' % task.delegate_to)
513
+ if task.delegate_to:
514
+ try:
515
+ delegated_host_name = templar.template(task.delegate_to)
516
+ except AnsibleValueOmittedError:
517
+ pass
529
518
 
530
- delegated_host = self._inventory.get_host(delegated_host_name)
531
- if delegated_host is None:
532
- for h in self._inventory.get_hosts(ignore_limits=True, ignore_restrictions=True):
533
- # check if the address matches, or if both the delegated_to host
534
- # and the current host are in the list of localhost aliases
535
- if h.address == delegated_host_name:
536
- delegated_host = h
537
- break
538
- else:
539
- delegated_host = Host(name=delegated_host_name)
540
-
541
- delegated_vars['ansible_delegated_vars'] = {
542
- delegated_host_name: self.get_vars(
543
- play=task.get_play(),
544
- host=delegated_host,
545
- task=task,
546
- include_hostvars=True,
547
- )
548
- }
549
- delegated_vars['ansible_delegated_vars'][delegated_host_name]['inventory_hostname'] = variables.get('inventory_hostname')
519
+ # bypass for unspecified value/omit
520
+ if delegated_host_name is ...:
521
+ return delegated_vars, None
522
+
523
+ if not delegated_host_name:
524
+ raise AnsibleError('Empty hostname produced from delegate_to: "%s"' % task.delegate_to)
525
+
526
+ delegated_host = self._inventory.get_host(delegated_host_name)
527
+ if delegated_host is None:
528
+ for h in self._inventory.get_hosts(ignore_limits=True, ignore_restrictions=True):
529
+ # check if the address matches, or if both the delegated_to host
530
+ # and the current host are in the list of localhost aliases
531
+ if h.address == delegated_host_name:
532
+ delegated_host = h
533
+ break
534
+ else:
535
+ delegated_host = Host(name=delegated_host_name)
536
+
537
+ delegated_vars['ansible_delegated_vars'] = {
538
+ delegated_host_name: self.get_vars(
539
+ play=task.get_play(),
540
+ host=delegated_host,
541
+ task=task,
542
+ include_hostvars=True,
543
+ )
544
+ }
545
+ delegated_vars['ansible_delegated_vars'][delegated_host_name]['inventory_hostname'] = variables.get('inventory_hostname')
550
546
 
551
547
  return delegated_vars, delegated_host_name
552
548
 
553
549
  def clear_facts(self, hostname):
554
- '''
550
+ """
555
551
  Clears the facts for a host
556
- '''
557
- self._fact_cache.pop(hostname, None)
552
+ """
553
+ try:
554
+ self._fact_cache.delete(hostname)
555
+ except KeyError:
556
+ pass
558
557
 
559
558
  def set_host_facts(self, host, facts):
560
- '''
559
+ """
561
560
  Sets or updates the given facts for a host in the fact cache.
562
- '''
561
+ """
563
562
 
564
563
  if not isinstance(facts, Mapping):
565
564
  raise AnsibleAssertionError("the type of 'facts' to set for host_facts should be a Mapping but is a %s" % type(facts))
566
565
 
567
- warn_if_reserved(facts.keys())
566
+ warn_if_reserved(facts)
567
+
568
568
  try:
569
- host_cache = self._fact_cache[host]
569
+ host_cache = self._fact_cache.get(host)
570
570
  except KeyError:
571
571
  # We get to set this as new
572
572
  host_cache = facts
@@ -578,17 +578,18 @@ class VariableManager:
578
578
  host_cache |= facts
579
579
 
580
580
  # Save the facts back to the backing store
581
- self._fact_cache[host] = host_cache
581
+ self._fact_cache.set(host, host_cache)
582
582
 
583
583
  def set_nonpersistent_facts(self, host, facts):
584
- '''
584
+ """
585
585
  Sets or updates the given facts for a host in the fact cache.
586
- '''
586
+ """
587
587
 
588
588
  if not isinstance(facts, Mapping):
589
589
  raise AnsibleAssertionError("the type of 'facts' to set for nonpersistent_facts should be a Mapping but is a %s" % type(facts))
590
590
 
591
- warn_if_reserved(facts.keys())
591
+ warn_if_reserved(facts)
592
+
592
593
  try:
593
594
  self._nonpersistent_fact_cache[host] |= facts
594
595
  except KeyError:
@@ -600,77 +601,11 @@ class VariableManager:
600
601
  """
601
602
 
602
603
  warn_if_reserved([varname])
604
+
603
605
  if host not in self._vars_cache:
604
606
  self._vars_cache[host] = dict()
607
+
605
608
  if varname in self._vars_cache[host] and isinstance(self._vars_cache[host][varname], MutableMapping) and isinstance(value, MutableMapping):
606
609
  self._vars_cache[host] = combine_vars(self._vars_cache[host], {varname: value})
607
610
  else:
608
611
  self._vars_cache[host][varname] = value
609
-
610
-
611
- class VarsWithSources(MutableMapping):
612
- '''
613
- Dict-like class for vars that also provides source information for each var
614
-
615
- This class can only store the source for top-level vars. It does no tracking
616
- on its own, just shows a debug message with the information that it is provided
617
- when a particular var is accessed.
618
- '''
619
- def __init__(self, *args, **kwargs):
620
- ''' Dict-compatible constructor '''
621
- self.data = dict(*args, **kwargs)
622
- self.sources = {}
623
-
624
- @classmethod
625
- def new_vars_with_sources(cls, data, sources):
626
- ''' Alternate constructor method to instantiate class with sources '''
627
- v = cls(data)
628
- v.sources = sources
629
- return v
630
-
631
- def get_source(self, key):
632
- return self.sources.get(key, None)
633
-
634
- def __getitem__(self, key):
635
- val = self.data[key]
636
- # See notes in the VarsWithSources docstring for caveats and limitations of the source tracking
637
- display.debug("variable '%s' from source: %s" % (key, self.sources.get(key, "unknown")))
638
- return val
639
-
640
- def __setitem__(self, key, value):
641
- self.data[key] = value
642
-
643
- def __delitem__(self, key):
644
- del self.data[key]
645
-
646
- def __iter__(self):
647
- return iter(self.data)
648
-
649
- def __len__(self):
650
- return len(self.data)
651
-
652
- # Prevent duplicate debug messages by defining our own __contains__ pointing at the underlying dict
653
- def __contains__(self, key):
654
- return self.data.__contains__(key)
655
-
656
- def copy(self):
657
- return VarsWithSources.new_vars_with_sources(self.data.copy(), self.sources.copy())
658
-
659
- def __or__(self, other):
660
- if isinstance(other, MutableMapping):
661
- c = self.data.copy()
662
- c.update(other)
663
- return c
664
- return NotImplemented
665
-
666
- def __ror__(self, other):
667
- if isinstance(other, MutableMapping):
668
- c = self.__class__()
669
- c.update(other)
670
- c.update(self.data)
671
- return c
672
- return NotImplemented
673
-
674
- def __ior__(self, other):
675
- self.data.update(other)
676
- return self.data