ansible-core 2.18.5rc1__py3-none-any.whl → 2.19.0b2__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.
Files changed (710) hide show
  1. ansible/_internal/__init__.py +53 -0
  2. ansible/_internal/_ansiballz.py +265 -0
  3. ansible/_internal/_collection_proxy.py +47 -0
  4. ansible/_internal/_datatag/__init__.py +0 -0
  5. ansible/_internal/_datatag/_tags.py +130 -0
  6. ansible/_internal/_datatag/_utils.py +19 -0
  7. ansible/_internal/_datatag/_wrappers.py +33 -0
  8. ansible/_internal/_errors/__init__.py +0 -0
  9. ansible/_internal/_errors/_captured.py +128 -0
  10. ansible/_internal/_errors/_handler.py +91 -0
  11. ansible/_internal/_errors/_utils.py +310 -0
  12. ansible/_internal/_json/__init__.py +203 -0
  13. ansible/_internal/_json/_legacy_encoder.py +34 -0
  14. ansible/_internal/_json/_profiles/__init__.py +0 -0
  15. ansible/_internal/_json/_profiles/_cache_persistence.py +55 -0
  16. ansible/_internal/_json/_profiles/_inventory_legacy.py +40 -0
  17. ansible/_internal/_json/_profiles/_legacy.py +197 -0
  18. ansible/_internal/_locking.py +21 -0
  19. ansible/_internal/_plugins/__init__.py +0 -0
  20. ansible/_internal/_plugins/_cache.py +57 -0
  21. ansible/_internal/_task.py +78 -0
  22. ansible/_internal/_templating/__init__.py +10 -0
  23. ansible/_internal/_templating/_access.py +86 -0
  24. ansible/_internal/_templating/_chain_templar.py +63 -0
  25. ansible/_internal/_templating/_datatag.py +95 -0
  26. ansible/_internal/_templating/_engine.py +588 -0
  27. ansible/_internal/_templating/_errors.py +28 -0
  28. ansible/_internal/_templating/_jinja_bits.py +1066 -0
  29. ansible/_internal/_templating/_jinja_common.py +332 -0
  30. ansible/_internal/_templating/_jinja_patches.py +44 -0
  31. ansible/_internal/_templating/_jinja_plugins.py +345 -0
  32. ansible/_internal/_templating/_lazy_containers.py +633 -0
  33. ansible/_internal/_templating/_marker_behaviors.py +103 -0
  34. ansible/_internal/_templating/_transform.py +63 -0
  35. ansible/_internal/_templating/_utils.py +107 -0
  36. ansible/_internal/_wrapt.py +1052 -0
  37. ansible/_internal/_yaml/__init__.py +0 -0
  38. ansible/_internal/_yaml/_constructor.py +240 -0
  39. ansible/_internal/_yaml/_dumper.py +62 -0
  40. ansible/_internal/_yaml/_errors.py +166 -0
  41. ansible/_internal/_yaml/_loader.py +66 -0
  42. ansible/_internal/ansible_collections/ansible/_protomatter/README.md +11 -0
  43. ansible/_internal/ansible_collections/ansible/_protomatter/plugins/action/debug.py +36 -0
  44. ansible/_internal/ansible_collections/ansible/_protomatter/plugins/filter/apply_trust.py +19 -0
  45. ansible/_internal/ansible_collections/ansible/_protomatter/plugins/filter/dump_object.py +18 -0
  46. ansible/_internal/ansible_collections/ansible/_protomatter/plugins/filter/finalize.py +16 -0
  47. ansible/_internal/ansible_collections/ansible/_protomatter/plugins/filter/origin.py +18 -0
  48. ansible/_internal/ansible_collections/ansible/_protomatter/plugins/filter/python_literal_eval.py +24 -0
  49. ansible/_internal/ansible_collections/ansible/_protomatter/plugins/filter/python_literal_eval.yml +33 -0
  50. ansible/_internal/ansible_collections/ansible/_protomatter/plugins/filter/tag_names.py +16 -0
  51. ansible/_internal/ansible_collections/ansible/_protomatter/plugins/filter/true_type.py +17 -0
  52. ansible/_internal/ansible_collections/ansible/_protomatter/plugins/filter/unmask.py +49 -0
  53. ansible/_internal/ansible_collections/ansible/_protomatter/plugins/lookup/config.py +21 -0
  54. ansible/_internal/ansible_collections/ansible/_protomatter/plugins/lookup/config.yml +2 -0
  55. ansible/_internal/ansible_collections/ansible/_protomatter/plugins/test/tagged.py +15 -0
  56. ansible/_internal/ansible_collections/ansible/_protomatter/plugins/test/tagged.yml +19 -0
  57. ansible/_internal/ansible_collections/ansible/_protomatter/plugins/test/tagged_with.py +18 -0
  58. ansible/_internal/ansible_collections/ansible/_protomatter/plugins/test/tagged_with.yml +19 -0
  59. ansible/cli/__init__.py +159 -89
  60. ansible/cli/_ssh_askpass.py +47 -0
  61. ansible/cli/adhoc.py +14 -7
  62. ansible/cli/arguments/option_helpers.py +154 -7
  63. ansible/cli/config.py +43 -68
  64. ansible/cli/console.py +10 -8
  65. ansible/cli/doc.py +62 -53
  66. ansible/cli/galaxy.py +27 -20
  67. ansible/cli/inventory.py +28 -26
  68. ansible/cli/playbook.py +4 -12
  69. ansible/cli/pull.py +51 -11
  70. ansible/cli/scripts/ansible_connection_cli_stub.py +7 -7
  71. ansible/cli/vault.py +12 -11
  72. ansible/compat/__init__.py +2 -2
  73. ansible/config/base.yml +166 -112
  74. ansible/config/manager.py +52 -49
  75. ansible/constants.py +3 -4
  76. ansible/errors/__init__.py +277 -235
  77. ansible/executor/interpreter_discovery.py +28 -149
  78. ansible/executor/module_common.py +426 -493
  79. ansible/executor/play_iterator.py +22 -27
  80. ansible/executor/playbook_executor.py +11 -11
  81. ansible/executor/powershell/async_watchdog.ps1 +97 -102
  82. ansible/executor/powershell/async_wrapper.ps1 +202 -151
  83. ansible/executor/powershell/become_wrapper.ps1 +89 -144
  84. ansible/executor/powershell/bootstrap_wrapper.ps1 +24 -9
  85. ansible/executor/powershell/coverage_wrapper.ps1 +82 -135
  86. ansible/executor/powershell/exec_wrapper.ps1 +462 -196
  87. ansible/executor/powershell/module_manifest.py +417 -265
  88. ansible/executor/powershell/module_wrapper.ps1 +169 -186
  89. ansible/executor/powershell/psrp_fetch_file.ps1 +41 -0
  90. ansible/executor/powershell/psrp_put_file.ps1 +122 -0
  91. ansible/executor/powershell/winrm_fetch_file.ps1 +46 -0
  92. ansible/executor/powershell/winrm_put_file.ps1 +36 -0
  93. ansible/executor/process/worker.py +161 -96
  94. ansible/executor/stats.py +5 -5
  95. ansible/executor/task_executor.py +268 -258
  96. ansible/executor/task_queue_manager.py +124 -90
  97. ansible/executor/task_result.py +183 -78
  98. ansible/galaxy/__init__.py +2 -2
  99. ansible/galaxy/api.py +22 -18
  100. ansible/galaxy/collection/__init__.py +1 -1
  101. ansible/galaxy/collection/concrete_artifact_manager.py +8 -11
  102. ansible/galaxy/dependency_resolution/dataclasses.py +14 -4
  103. ansible/galaxy/dependency_resolution/providers.py +1 -1
  104. ansible/galaxy/dependency_resolution/reporters.py +81 -0
  105. ansible/galaxy/role.py +4 -8
  106. ansible/galaxy/token.py +28 -21
  107. ansible/inventory/data.py +47 -57
  108. ansible/inventory/group.py +44 -72
  109. ansible/inventory/helpers.py +9 -0
  110. ansible/inventory/host.py +32 -54
  111. ansible/inventory/manager.py +78 -34
  112. ansible/keyword_desc.yml +1 -1
  113. ansible/module_utils/_internal/__init__.py +55 -0
  114. ansible/module_utils/_internal/_ambient_context.py +58 -0
  115. ansible/module_utils/_internal/_ansiballz.py +133 -0
  116. ansible/module_utils/_internal/_concurrent/_daemon_threading.py +1 -0
  117. ansible/module_utils/_internal/_dataclass_annotation_patch.py +64 -0
  118. ansible/module_utils/_internal/_dataclass_validation.py +217 -0
  119. ansible/module_utils/_internal/_datatag/__init__.py +928 -0
  120. ansible/module_utils/_internal/_datatag/_tags.py +38 -0
  121. ansible/module_utils/_internal/_debugging.py +31 -0
  122. ansible/module_utils/_internal/_errors.py +30 -0
  123. ansible/module_utils/_internal/_json/__init__.py +63 -0
  124. ansible/module_utils/_internal/_json/_legacy_encoder.py +26 -0
  125. ansible/module_utils/_internal/_json/_profiles/__init__.py +410 -0
  126. ansible/module_utils/_internal/_json/_profiles/_fallback_to_str.py +73 -0
  127. ansible/module_utils/_internal/_json/_profiles/_module_legacy_c2m.py +31 -0
  128. ansible/module_utils/_internal/_json/_profiles/_module_legacy_m2c.py +35 -0
  129. ansible/module_utils/_internal/_json/_profiles/_module_modern_c2m.py +35 -0
  130. ansible/module_utils/_internal/_json/_profiles/_module_modern_m2c.py +33 -0
  131. ansible/module_utils/_internal/_json/_profiles/_tagless.py +50 -0
  132. ansible/module_utils/_internal/_patches/__init__.py +66 -0
  133. ansible/module_utils/_internal/_patches/_dataclass_annotation_patch.py +55 -0
  134. ansible/module_utils/_internal/_patches/_socket_patch.py +34 -0
  135. ansible/module_utils/_internal/_patches/_sys_intern_patch.py +34 -0
  136. ansible/module_utils/_internal/_plugin_exec_context.py +49 -0
  137. ansible/module_utils/_internal/_testing.py +0 -0
  138. ansible/module_utils/_internal/_traceback.py +89 -0
  139. ansible/module_utils/ansible_release.py +2 -2
  140. ansible/module_utils/api.py +1 -2
  141. ansible/module_utils/basic.py +152 -120
  142. ansible/module_utils/common/_utils.py +24 -28
  143. ansible/module_utils/common/collections.py +1 -2
  144. ansible/module_utils/common/dict_transformations.py +2 -2
  145. ansible/module_utils/common/file.py +2 -2
  146. ansible/module_utils/common/json.py +90 -84
  147. ansible/module_utils/common/locale.py +2 -2
  148. ansible/module_utils/common/messages.py +108 -0
  149. ansible/module_utils/common/parameters.py +27 -24
  150. ansible/module_utils/common/process.py +2 -2
  151. ansible/module_utils/common/respawn.py +41 -19
  152. ansible/module_utils/common/sentinel.py +66 -0
  153. ansible/module_utils/common/sys_info.py +8 -8
  154. ansible/module_utils/common/text/converters.py +16 -37
  155. ansible/module_utils/common/validation.py +35 -24
  156. ansible/module_utils/common/warnings.py +86 -25
  157. ansible/module_utils/common/yaml.py +29 -3
  158. ansible/module_utils/compat/datetime.py +33 -21
  159. ansible/module_utils/compat/paramiko.py +21 -10
  160. ansible/module_utils/compat/typing.py +6 -5
  161. ansible/module_utils/connection.py +2 -2
  162. ansible/module_utils/csharp/Ansible.Basic.cs +14 -11
  163. ansible/module_utils/csharp/Ansible.Become.cs +1 -0
  164. ansible/module_utils/csharp/Ansible._Async.cs +517 -0
  165. ansible/module_utils/datatag.py +46 -0
  166. ansible/module_utils/distro/__init__.py +2 -2
  167. ansible/module_utils/facts/ansible_collector.py +4 -5
  168. ansible/module_utils/facts/collector.py +13 -14
  169. ansible/module_utils/facts/compat.py +4 -4
  170. ansible/module_utils/facts/default_collectors.py +1 -1
  171. ansible/module_utils/facts/hardware/aix.py +34 -0
  172. ansible/module_utils/facts/hardware/base.py +1 -1
  173. ansible/module_utils/facts/hardware/darwin.py +1 -3
  174. ansible/module_utils/facts/hardware/freebsd.py +2 -2
  175. ansible/module_utils/facts/hardware/linux.py +4 -4
  176. ansible/module_utils/facts/namespace.py +1 -1
  177. ansible/module_utils/facts/network/base.py +1 -1
  178. ansible/module_utils/facts/network/fc_wwn.py +1 -2
  179. ansible/module_utils/facts/network/iscsi.py +1 -2
  180. ansible/module_utils/facts/network/nvme.py +1 -2
  181. ansible/module_utils/facts/other/facter.py +1 -2
  182. ansible/module_utils/facts/other/ohai.py +2 -3
  183. ansible/module_utils/facts/system/apparmor.py +1 -2
  184. ansible/module_utils/facts/system/caps.py +1 -1
  185. ansible/module_utils/facts/system/chroot.py +1 -2
  186. ansible/module_utils/facts/system/cmdline.py +1 -2
  187. ansible/module_utils/facts/system/date_time.py +5 -3
  188. ansible/module_utils/facts/system/distribution.py +9 -8
  189. ansible/module_utils/facts/system/dns.py +1 -1
  190. ansible/module_utils/facts/system/env.py +1 -2
  191. ansible/module_utils/facts/system/fips.py +7 -20
  192. ansible/module_utils/facts/system/loadavg.py +1 -2
  193. ansible/module_utils/facts/system/local.py +1 -2
  194. ansible/module_utils/facts/system/lsb.py +1 -2
  195. ansible/module_utils/facts/system/pkg_mgr.py +1 -2
  196. ansible/module_utils/facts/system/platform.py +1 -2
  197. ansible/module_utils/facts/system/python.py +1 -2
  198. ansible/module_utils/facts/system/selinux.py +1 -1
  199. ansible/module_utils/facts/system/service_mgr.py +1 -2
  200. ansible/module_utils/facts/system/ssh_pub_keys.py +1 -1
  201. ansible/module_utils/facts/system/systemd.py +1 -1
  202. ansible/module_utils/facts/system/user.py +1 -2
  203. ansible/module_utils/facts/utils.py +3 -3
  204. ansible/module_utils/facts/virtual/base.py +1 -1
  205. ansible/module_utils/facts/virtual/sunos.py +3 -15
  206. ansible/module_utils/facts/virtual/sysctl.py +3 -16
  207. ansible/module_utils/json_utils.py +2 -2
  208. ansible/module_utils/parsing/convert_bool.py +1 -1
  209. ansible/module_utils/service.py +18 -21
  210. ansible/module_utils/splitter.py +7 -7
  211. ansible/module_utils/testing.py +31 -0
  212. ansible/module_utils/urls.py +60 -31
  213. ansible/modules/add_host.py +4 -4
  214. ansible/modules/apt.py +60 -46
  215. ansible/modules/apt_key.py +19 -12
  216. ansible/modules/apt_repository.py +19 -16
  217. ansible/modules/assemble.py +6 -6
  218. ansible/modules/assert.py +4 -4
  219. ansible/modules/async_status.py +10 -12
  220. ansible/modules/async_wrapper.py +8 -3
  221. ansible/modules/blockinfile.py +6 -7
  222. ansible/modules/command.py +10 -17
  223. ansible/modules/copy.py +57 -144
  224. ansible/modules/cron.py +20 -15
  225. ansible/modules/deb822_repository.py +8 -9
  226. ansible/modules/debconf.py +5 -5
  227. ansible/modules/debug.py +4 -4
  228. ansible/modules/dnf.py +8 -8
  229. ansible/modules/dnf5.py +39 -13
  230. ansible/modules/dpkg_selections.py +4 -4
  231. ansible/modules/expect.py +8 -10
  232. ansible/modules/fail.py +4 -4
  233. ansible/modules/fetch.py +4 -4
  234. ansible/modules/file.py +174 -133
  235. ansible/modules/find.py +19 -17
  236. ansible/modules/gather_facts.py +3 -3
  237. ansible/modules/get_url.py +59 -53
  238. ansible/modules/getent.py +7 -9
  239. ansible/modules/git.py +28 -25
  240. ansible/modules/group.py +6 -6
  241. ansible/modules/group_by.py +4 -4
  242. ansible/modules/hostname.py +13 -29
  243. ansible/modules/import_playbook.py +6 -6
  244. ansible/modules/import_role.py +6 -6
  245. ansible/modules/import_tasks.py +6 -6
  246. ansible/modules/include_role.py +6 -6
  247. ansible/modules/include_tasks.py +6 -6
  248. ansible/modules/include_vars.py +6 -6
  249. ansible/modules/iptables.py +86 -73
  250. ansible/modules/known_hosts.py +10 -10
  251. ansible/modules/lineinfile.py +5 -5
  252. ansible/modules/meta.py +4 -4
  253. ansible/modules/mount_facts.py +2 -2
  254. ansible/modules/package.py +4 -4
  255. ansible/modules/package_facts.py +22 -10
  256. ansible/modules/pause.py +6 -6
  257. ansible/modules/ping.py +6 -6
  258. ansible/modules/pip.py +10 -11
  259. ansible/modules/raw.py +4 -4
  260. ansible/modules/reboot.py +6 -6
  261. ansible/modules/replace.py +9 -13
  262. ansible/modules/rpm_key.py +7 -8
  263. ansible/modules/script.py +4 -4
  264. ansible/modules/service.py +7 -8
  265. ansible/modules/service_facts.py +87 -10
  266. ansible/modules/set_fact.py +5 -5
  267. ansible/modules/set_stats.py +4 -4
  268. ansible/modules/setup.py +2 -2
  269. ansible/modules/shell.py +6 -6
  270. ansible/modules/slurp.py +6 -6
  271. ansible/modules/stat.py +9 -23
  272. ansible/modules/subversion.py +15 -15
  273. ansible/modules/systemd.py +6 -6
  274. ansible/modules/systemd_service.py +6 -6
  275. ansible/modules/sysvinit.py +6 -6
  276. ansible/modules/tempfile.py +5 -6
  277. ansible/modules/template.py +6 -6
  278. ansible/modules/unarchive.py +32 -11
  279. ansible/modules/uri.py +33 -26
  280. ansible/modules/user.py +53 -34
  281. ansible/modules/validate_argument_spec.py +10 -7
  282. ansible/modules/wait_for.py +32 -27
  283. ansible/modules/wait_for_connection.py +6 -6
  284. ansible/modules/yum_repository.py +6 -6
  285. ansible/parsing/ajson.py +14 -32
  286. ansible/parsing/dataloader.py +99 -54
  287. ansible/parsing/mod_args.py +28 -44
  288. ansible/parsing/plugin_docs.py +21 -86
  289. ansible/parsing/quoting.py +1 -1
  290. ansible/parsing/splitter.py +27 -12
  291. ansible/parsing/utils/addresses.py +24 -24
  292. ansible/parsing/utils/jsonify.py +5 -1
  293. ansible/parsing/utils/yaml.py +32 -61
  294. ansible/parsing/vault/__init__.py +319 -87
  295. ansible/parsing/yaml/__init__.py +0 -18
  296. ansible/parsing/yaml/dumper.py +6 -120
  297. ansible/parsing/yaml/loader.py +6 -39
  298. ansible/parsing/yaml/objects.py +43 -335
  299. ansible/playbook/__init__.py +1 -1
  300. ansible/playbook/attribute.py +8 -3
  301. ansible/playbook/base.py +182 -132
  302. ansible/playbook/block.py +26 -24
  303. ansible/playbook/collectionsearch.py +1 -15
  304. ansible/playbook/conditional.py +3 -77
  305. ansible/playbook/handler.py +8 -2
  306. ansible/playbook/helpers.py +41 -53
  307. ansible/playbook/included_file.py +31 -27
  308. ansible/playbook/loop_control.py +2 -2
  309. ansible/playbook/play.py +85 -44
  310. ansible/playbook/play_context.py +12 -17
  311. ansible/playbook/playbook_include.py +14 -15
  312. ansible/playbook/role/__init__.py +24 -26
  313. ansible/playbook/role/definition.py +15 -17
  314. ansible/playbook/role/include.py +2 -4
  315. ansible/playbook/role/metadata.py +10 -11
  316. ansible/playbook/role_include.py +3 -3
  317. ansible/playbook/taggable.py +13 -8
  318. ansible/playbook/task.py +188 -118
  319. ansible/playbook/task_include.py +5 -5
  320. ansible/plugins/__init__.py +68 -21
  321. ansible/plugins/action/__init__.py +209 -176
  322. ansible/plugins/action/add_host.py +1 -1
  323. ansible/plugins/action/assemble.py +1 -1
  324. ansible/plugins/action/assert.py +54 -66
  325. ansible/plugins/action/copy.py +7 -11
  326. ansible/plugins/action/debug.py +37 -31
  327. ansible/plugins/action/dnf.py +3 -4
  328. ansible/plugins/action/fail.py +1 -1
  329. ansible/plugins/action/fetch.py +4 -5
  330. ansible/plugins/action/gather_facts.py +7 -6
  331. ansible/plugins/action/group_by.py +1 -1
  332. ansible/plugins/action/include_vars.py +10 -11
  333. ansible/plugins/action/package.py +3 -6
  334. ansible/plugins/action/pause.py +2 -2
  335. ansible/plugins/action/script.py +15 -8
  336. ansible/plugins/action/service.py +6 -11
  337. ansible/plugins/action/set_fact.py +3 -12
  338. ansible/plugins/action/set_stats.py +3 -8
  339. ansible/plugins/action/template.py +35 -59
  340. ansible/plugins/action/unarchive.py +1 -1
  341. ansible/plugins/action/validate_argument_spec.py +5 -5
  342. ansible/plugins/action/wait_for_connection.py +1 -1
  343. ansible/plugins/become/__init__.py +31 -8
  344. ansible/plugins/become/runas.py +71 -0
  345. ansible/plugins/become/su.py +13 -8
  346. ansible/plugins/become/sudo.py +19 -0
  347. ansible/plugins/cache/__init__.py +35 -44
  348. ansible/plugins/cache/base.py +8 -0
  349. ansible/plugins/cache/jsonfile.py +10 -16
  350. ansible/plugins/cache/memory.py +6 -12
  351. ansible/plugins/callback/__init__.py +284 -179
  352. ansible/plugins/callback/default.py +99 -92
  353. ansible/plugins/callback/junit.py +44 -39
  354. ansible/plugins/callback/minimal.py +28 -25
  355. ansible/plugins/callback/oneline.py +28 -21
  356. ansible/plugins/callback/tree.py +16 -11
  357. ansible/plugins/connection/__init__.py +47 -34
  358. ansible/plugins/connection/local.py +150 -54
  359. ansible/plugins/connection/paramiko_ssh.py +21 -18
  360. ansible/plugins/connection/psrp.py +76 -165
  361. ansible/plugins/connection/ssh.py +301 -78
  362. ansible/plugins/connection/winrm.py +58 -140
  363. ansible/plugins/doc_fragments/action_common_attributes.py +14 -14
  364. ansible/plugins/doc_fragments/action_core.py +6 -6
  365. ansible/plugins/doc_fragments/backup.py +2 -2
  366. ansible/plugins/doc_fragments/checksum_common.py +27 -0
  367. ansible/plugins/doc_fragments/constructed.py +6 -2
  368. ansible/plugins/doc_fragments/decrypt.py +2 -2
  369. ansible/plugins/doc_fragments/default_callback.py +2 -2
  370. ansible/plugins/doc_fragments/files.py +2 -2
  371. ansible/plugins/doc_fragments/inventory_cache.py +2 -2
  372. ansible/plugins/doc_fragments/result_format_callback.py +2 -2
  373. ansible/plugins/doc_fragments/return_common.py +2 -2
  374. ansible/plugins/doc_fragments/template_common.py +4 -4
  375. ansible/plugins/doc_fragments/url.py +17 -1
  376. ansible/plugins/doc_fragments/url_windows.py +2 -2
  377. ansible/plugins/doc_fragments/validate.py +2 -2
  378. ansible/plugins/doc_fragments/vars_plugin_staging.py +2 -2
  379. ansible/plugins/filter/__init__.py +6 -2
  380. ansible/plugins/filter/b64decode.yml +22 -0
  381. ansible/plugins/filter/b64encode.yml +22 -0
  382. ansible/plugins/filter/bool.yml +11 -4
  383. ansible/plugins/filter/core.py +225 -108
  384. ansible/plugins/filter/encryption.py +32 -32
  385. ansible/plugins/filter/flatten.yml +3 -2
  386. ansible/plugins/filter/human_to_bytes.yml +1 -1
  387. ansible/plugins/filter/mathstuff.py +30 -37
  388. ansible/plugins/filter/password_hash.yml +8 -0
  389. ansible/plugins/filter/regex_search.yml +1 -4
  390. ansible/plugins/filter/split.yml +1 -1
  391. ansible/plugins/filter/to_nice_yaml.yml +0 -4
  392. ansible/plugins/filter/to_yaml.yml +0 -4
  393. ansible/plugins/filter/unvault.yml +1 -1
  394. ansible/plugins/filter/urls.py +1 -1
  395. ansible/plugins/filter/urlsplit.py +8 -9
  396. ansible/plugins/filter/vault.yml +14 -9
  397. ansible/plugins/filter/win_basename.yml +6 -1
  398. ansible/plugins/filter/win_dirname.yml +5 -0
  399. ansible/plugins/inventory/__init__.py +97 -77
  400. ansible/plugins/inventory/advanced_host_list.py +7 -5
  401. ansible/plugins/inventory/auto.py +11 -4
  402. ansible/plugins/inventory/constructed.py +21 -24
  403. ansible/plugins/inventory/generator.py +16 -11
  404. ansible/plugins/inventory/host_list.py +7 -5
  405. ansible/plugins/inventory/ini.py +78 -44
  406. ansible/plugins/inventory/script.py +189 -119
  407. ansible/plugins/inventory/toml.py +16 -126
  408. ansible/plugins/inventory/yaml.py +10 -8
  409. ansible/plugins/list.py +3 -3
  410. ansible/plugins/loader.py +197 -82
  411. ansible/plugins/lookup/__init__.py +21 -4
  412. ansible/plugins/lookup/config.py +21 -35
  413. ansible/plugins/lookup/csvfile.py +3 -2
  414. ansible/plugins/lookup/dict.py +1 -6
  415. ansible/plugins/lookup/env.py +12 -9
  416. ansible/plugins/lookup/file.py +5 -8
  417. ansible/plugins/lookup/first_found.py +86 -55
  418. ansible/plugins/lookup/indexed_items.py +1 -10
  419. ansible/plugins/lookup/ini.py +14 -13
  420. ansible/plugins/lookup/items.py +1 -1
  421. ansible/plugins/lookup/lines.py +8 -1
  422. ansible/plugins/lookup/list.py +1 -1
  423. ansible/plugins/lookup/nested.py +2 -18
  424. ansible/plugins/lookup/password.py +5 -5
  425. ansible/plugins/lookup/pipe.py +5 -7
  426. ansible/plugins/lookup/sequence.py +18 -8
  427. ansible/plugins/lookup/subelements.py +1 -4
  428. ansible/plugins/lookup/template.py +42 -36
  429. ansible/plugins/lookup/together.py +0 -12
  430. ansible/plugins/lookup/unvault.py +1 -5
  431. ansible/plugins/lookup/url.py +2 -8
  432. ansible/plugins/lookup/vars.py +16 -24
  433. ansible/plugins/shell/__init__.py +2 -2
  434. ansible/plugins/shell/cmd.py +2 -2
  435. ansible/plugins/shell/powershell.py +39 -22
  436. ansible/plugins/shell/sh.py +3 -2
  437. ansible/plugins/strategy/__init__.py +159 -184
  438. ansible/plugins/strategy/debug.py +2 -2
  439. ansible/plugins/strategy/free.py +16 -31
  440. ansible/plugins/strategy/host_pinned.py +2 -2
  441. ansible/plugins/strategy/linear.py +41 -41
  442. ansible/plugins/terminal/__init__.py +4 -4
  443. ansible/plugins/test/__init__.py +7 -2
  444. ansible/plugins/test/core.py +55 -21
  445. ansible/plugins/test/files.py +1 -1
  446. ansible/plugins/test/mathstuff.py +3 -3
  447. ansible/plugins/test/uri.py +3 -3
  448. ansible/plugins/vars/host_group_vars.py +7 -14
  449. ansible/release.py +2 -2
  450. ansible/template/__init__.py +370 -944
  451. ansible/utils/__init__.py +0 -18
  452. ansible/utils/_ssh_agent.py +657 -0
  453. ansible/utils/collection_loader/__init__.py +52 -5
  454. ansible/utils/collection_loader/_collection_config.py +5 -6
  455. ansible/utils/collection_loader/_collection_finder.py +79 -93
  456. ansible/utils/collection_loader/_collection_meta.py +13 -8
  457. ansible/utils/display.py +433 -63
  458. ansible/utils/encrypt.py +27 -19
  459. ansible/utils/fqcn.py +2 -2
  460. ansible/utils/hashing.py +2 -2
  461. ansible/utils/helpers.py +2 -2
  462. ansible/utils/listify.py +8 -8
  463. ansible/utils/lock.py +2 -2
  464. ansible/utils/path.py +4 -4
  465. ansible/utils/plugin_docs.py +14 -13
  466. ansible/utils/sentinel.py +4 -62
  467. ansible/utils/singleton.py +2 -0
  468. ansible/utils/ssh_functions.py +1 -1
  469. ansible/utils/unsafe_proxy.py +23 -332
  470. ansible/utils/vars.py +51 -8
  471. ansible/utils/version.py +2 -2
  472. ansible/vars/clean.py +5 -5
  473. ansible/vars/hostvars.py +60 -90
  474. ansible/vars/manager.py +206 -282
  475. ansible/vars/reserved.py +8 -9
  476. ansible_core-2.19.0b2.dist-info/BSD-3-Clause.txt +28 -0
  477. {ansible_core-2.18.5rc1.dist-info → ansible_core-2.19.0b2.dist-info}/METADATA +5 -4
  478. ansible_core-2.19.0b2.dist-info/RECORD +1072 -0
  479. {ansible_core-2.18.5rc1.dist-info → ansible_core-2.19.0b2.dist-info}/WHEEL +1 -1
  480. ansible_test/_data/completion/docker.txt +7 -7
  481. ansible_test/_data/completion/remote.txt +6 -6
  482. ansible_test/_data/completion/windows.txt +1 -0
  483. ansible_test/_data/requirements/ansible.txt +2 -2
  484. ansible_test/_data/requirements/sanity.ansible-doc.txt +3 -3
  485. ansible_test/_data/requirements/sanity.changelog.txt +1 -1
  486. ansible_test/_data/requirements/sanity.import.plugin.txt +2 -2
  487. ansible_test/_data/requirements/sanity.pylint.txt +4 -4
  488. ansible_test/_data/requirements/sanity.validate-modules.txt +2 -2
  489. ansible_test/_data/requirements/sanity.yamllint.txt +1 -1
  490. ansible_test/_data/requirements/units.txt +1 -0
  491. ansible_test/_internal/__init__.py +1 -0
  492. ansible_test/_internal/ansible_util.py +2 -0
  493. ansible_test/_internal/become.py +1 -0
  494. ansible_test/_internal/bootstrap.py +1 -0
  495. ansible_test/_internal/cache.py +1 -0
  496. ansible_test/_internal/cgroup.py +1 -0
  497. ansible_test/_internal/ci/__init__.py +1 -0
  498. ansible_test/_internal/ci/azp.py +1 -0
  499. ansible_test/_internal/ci/local.py +1 -0
  500. ansible_test/_internal/classification/__init__.py +1 -0
  501. ansible_test/_internal/classification/common.py +1 -0
  502. ansible_test/_internal/classification/csharp.py +1 -0
  503. ansible_test/_internal/classification/powershell.py +1 -0
  504. ansible_test/_internal/classification/python.py +1 -0
  505. ansible_test/_internal/cli/__init__.py +1 -0
  506. ansible_test/_internal/cli/actions.py +1 -0
  507. ansible_test/_internal/cli/argparsing/__init__.py +1 -0
  508. ansible_test/_internal/cli/argparsing/actions.py +1 -0
  509. ansible_test/_internal/cli/argparsing/argcompletion.py +1 -0
  510. ansible_test/_internal/cli/argparsing/parsers.py +1 -0
  511. ansible_test/_internal/cli/commands/__init__.py +11 -0
  512. ansible_test/_internal/cli/commands/coverage/__init__.py +1 -0
  513. ansible_test/_internal/cli/commands/coverage/analyze/__init__.py +1 -0
  514. ansible_test/_internal/cli/commands/coverage/analyze/targets/__init__.py +1 -0
  515. ansible_test/_internal/cli/commands/coverage/analyze/targets/combine.py +1 -0
  516. ansible_test/_internal/cli/commands/coverage/analyze/targets/expand.py +1 -0
  517. ansible_test/_internal/cli/commands/coverage/analyze/targets/filter.py +1 -0
  518. ansible_test/_internal/cli/commands/coverage/analyze/targets/generate.py +1 -0
  519. ansible_test/_internal/cli/commands/coverage/analyze/targets/missing.py +1 -0
  520. ansible_test/_internal/cli/commands/coverage/combine.py +1 -0
  521. ansible_test/_internal/cli/commands/coverage/erase.py +1 -0
  522. ansible_test/_internal/cli/commands/coverage/html.py +1 -0
  523. ansible_test/_internal/cli/commands/coverage/report.py +1 -0
  524. ansible_test/_internal/cli/commands/coverage/xml.py +1 -0
  525. ansible_test/_internal/cli/commands/env.py +1 -0
  526. ansible_test/_internal/cli/commands/integration/__init__.py +1 -0
  527. ansible_test/_internal/cli/commands/integration/network.py +1 -0
  528. ansible_test/_internal/cli/commands/integration/posix.py +1 -0
  529. ansible_test/_internal/cli/commands/integration/windows.py +1 -0
  530. ansible_test/_internal/cli/commands/sanity.py +9 -0
  531. ansible_test/_internal/cli/commands/shell.py +1 -0
  532. ansible_test/_internal/cli/commands/units.py +1 -0
  533. ansible_test/_internal/cli/compat.py +1 -0
  534. ansible_test/_internal/cli/completers.py +1 -0
  535. ansible_test/_internal/cli/converters.py +1 -0
  536. ansible_test/_internal/cli/environments.py +1 -0
  537. ansible_test/_internal/cli/epilog.py +1 -0
  538. ansible_test/_internal/cli/parsers/__init__.py +1 -0
  539. ansible_test/_internal/cli/parsers/base_argument_parsers.py +1 -0
  540. ansible_test/_internal/cli/parsers/helpers.py +1 -0
  541. ansible_test/_internal/cli/parsers/host_config_parsers.py +1 -0
  542. ansible_test/_internal/cli/parsers/key_value_parsers.py +1 -0
  543. ansible_test/_internal/cli/parsers/value_parsers.py +1 -0
  544. ansible_test/_internal/commands/__init__.py +1 -0
  545. ansible_test/_internal/commands/coverage/__init__.py +2 -1
  546. ansible_test/_internal/commands/coverage/analyze/__init__.py +1 -0
  547. ansible_test/_internal/commands/coverage/analyze/targets/__init__.py +1 -0
  548. ansible_test/_internal/commands/coverage/analyze/targets/combine.py +1 -0
  549. ansible_test/_internal/commands/coverage/analyze/targets/expand.py +1 -0
  550. ansible_test/_internal/commands/coverage/analyze/targets/filter.py +1 -0
  551. ansible_test/_internal/commands/coverage/analyze/targets/generate.py +1 -0
  552. ansible_test/_internal/commands/coverage/analyze/targets/missing.py +1 -0
  553. ansible_test/_internal/commands/coverage/combine.py +2 -1
  554. ansible_test/_internal/commands/coverage/erase.py +1 -0
  555. ansible_test/_internal/commands/coverage/html.py +1 -0
  556. ansible_test/_internal/commands/coverage/report.py +1 -0
  557. ansible_test/_internal/commands/coverage/xml.py +1 -0
  558. ansible_test/_internal/commands/env/__init__.py +2 -0
  559. ansible_test/_internal/commands/integration/__init__.py +4 -0
  560. ansible_test/_internal/commands/integration/cloud/__init__.py +1 -0
  561. ansible_test/_internal/commands/integration/cloud/acme.py +2 -1
  562. ansible_test/_internal/commands/integration/cloud/aws.py +1 -0
  563. ansible_test/_internal/commands/integration/cloud/azure.py +1 -0
  564. ansible_test/_internal/commands/integration/cloud/cs.py +1 -0
  565. ansible_test/_internal/commands/integration/cloud/digitalocean.py +1 -0
  566. ansible_test/_internal/commands/integration/cloud/galaxy.py +3 -2
  567. ansible_test/_internal/commands/integration/cloud/hcloud.py +1 -0
  568. ansible_test/_internal/commands/integration/cloud/httptester.py +2 -1
  569. ansible_test/_internal/commands/integration/cloud/nios.py +2 -1
  570. ansible_test/_internal/commands/integration/cloud/opennebula.py +1 -0
  571. ansible_test/_internal/commands/integration/cloud/openshift.py +1 -0
  572. ansible_test/_internal/commands/integration/cloud/scaleway.py +1 -0
  573. ansible_test/_internal/commands/integration/cloud/vcenter.py +1 -0
  574. ansible_test/_internal/commands/integration/cloud/vultr.py +1 -0
  575. ansible_test/_internal/commands/integration/coverage.py +1 -0
  576. ansible_test/_internal/commands/integration/filters.py +1 -0
  577. ansible_test/_internal/commands/integration/network.py +1 -0
  578. ansible_test/_internal/commands/integration/posix.py +1 -0
  579. ansible_test/_internal/commands/integration/windows.py +1 -0
  580. ansible_test/_internal/commands/sanity/__init__.py +16 -1
  581. ansible_test/_internal/commands/sanity/ansible_doc.py +1 -0
  582. ansible_test/_internal/commands/sanity/bin_symlinks.py +1 -0
  583. ansible_test/_internal/commands/sanity/compile.py +1 -0
  584. ansible_test/_internal/commands/sanity/ignores.py +1 -0
  585. ansible_test/_internal/commands/sanity/import.py +1 -0
  586. ansible_test/_internal/commands/sanity/integration_aliases.py +1 -0
  587. ansible_test/_internal/commands/sanity/pep8.py +1 -0
  588. ansible_test/_internal/commands/sanity/pslint.py +1 -0
  589. ansible_test/_internal/commands/sanity/pylint.py +24 -26
  590. ansible_test/_internal/commands/sanity/shellcheck.py +1 -0
  591. ansible_test/_internal/commands/sanity/validate_modules.py +1 -0
  592. ansible_test/_internal/commands/sanity/yamllint.py +1 -0
  593. ansible_test/_internal/commands/shell/__init__.py +1 -0
  594. ansible_test/_internal/commands/units/__init__.py +1 -0
  595. ansible_test/_internal/compat/__init__.py +1 -0
  596. ansible_test/_internal/compat/packaging.py +1 -0
  597. ansible_test/_internal/compat/yaml.py +1 -0
  598. ansible_test/_internal/completion.py +1 -0
  599. ansible_test/_internal/config.py +2 -0
  600. ansible_test/_internal/connections.py +1 -0
  601. ansible_test/_internal/constants.py +1 -0
  602. ansible_test/_internal/containers.py +1 -0
  603. ansible_test/_internal/content_config.py +1 -0
  604. ansible_test/_internal/core_ci.py +1 -0
  605. ansible_test/_internal/coverage_util.py +11 -10
  606. ansible_test/_internal/data.py +1 -0
  607. ansible_test/_internal/delegation.py +1 -0
  608. ansible_test/_internal/dev/__init__.py +1 -0
  609. ansible_test/_internal/dev/container_probe.py +1 -0
  610. ansible_test/_internal/diff.py +3 -2
  611. ansible_test/_internal/docker_util.py +2 -1
  612. ansible_test/_internal/encoding.py +1 -0
  613. ansible_test/_internal/executor.py +1 -0
  614. ansible_test/_internal/git.py +1 -0
  615. ansible_test/_internal/host_configs.py +1 -0
  616. ansible_test/_internal/host_profiles.py +1 -0
  617. ansible_test/_internal/http.py +1 -0
  618. ansible_test/_internal/init.py +1 -0
  619. ansible_test/_internal/inventory.py +35 -3
  620. ansible_test/_internal/io.py +1 -0
  621. ansible_test/_internal/metadata.py +1 -0
  622. ansible_test/_internal/payload.py +1 -0
  623. ansible_test/_internal/provider/__init__.py +1 -0
  624. ansible_test/_internal/provider/layout/__init__.py +1 -0
  625. ansible_test/_internal/provider/layout/ansible.py +1 -0
  626. ansible_test/_internal/provider/layout/collection.py +1 -0
  627. ansible_test/_internal/provider/layout/unsupported.py +1 -0
  628. ansible_test/_internal/provider/source/__init__.py +1 -0
  629. ansible_test/_internal/provider/source/git.py +1 -0
  630. ansible_test/_internal/provider/source/installed.py +1 -0
  631. ansible_test/_internal/provider/source/unsupported.py +1 -0
  632. ansible_test/_internal/provider/source/unversioned.py +1 -0
  633. ansible_test/_internal/provisioning.py +1 -0
  634. ansible_test/_internal/pypi_proxy.py +6 -5
  635. ansible_test/_internal/python_requirements.py +1 -0
  636. ansible_test/_internal/ssh.py +1 -0
  637. ansible_test/_internal/target.py +1 -0
  638. ansible_test/_internal/test.py +3 -2
  639. ansible_test/_internal/thread.py +1 -0
  640. ansible_test/_internal/timeout.py +1 -0
  641. ansible_test/_internal/util.py +1 -0
  642. ansible_test/_internal/util_common.py +5 -2
  643. ansible_test/_internal/venv.py +1 -0
  644. ansible_test/_util/controller/sanity/code-smell/action-plugin-docs.py +1 -0
  645. ansible_test/_util/controller/sanity/code-smell/changelog/sphinx.py +1 -0
  646. ansible_test/_util/controller/sanity/code-smell/changelog.py +1 -0
  647. ansible_test/_util/controller/sanity/code-smell/empty-init.py +1 -0
  648. ansible_test/_util/controller/sanity/code-smell/line-endings.py +1 -0
  649. ansible_test/_util/controller/sanity/code-smell/no-assert.py +1 -0
  650. ansible_test/_util/controller/sanity/code-smell/no-get-exception.py +1 -0
  651. ansible_test/_util/controller/sanity/code-smell/no-illegal-filenames.py +1 -0
  652. ansible_test/_util/controller/sanity/code-smell/no-smart-quotes.py +1 -0
  653. ansible_test/_util/controller/sanity/code-smell/replace-urlopen.py +1 -0
  654. ansible_test/_util/controller/sanity/code-smell/runtime-metadata.py +28 -1
  655. ansible_test/_util/controller/sanity/code-smell/shebang.py +1 -0
  656. ansible_test/_util/controller/sanity/code-smell/symlinks.py +1 -0
  657. ansible_test/_util/controller/sanity/code-smell/use-argspec-type-path.py +1 -0
  658. ansible_test/_util/controller/sanity/code-smell/use-compat-six.py +1 -0
  659. ansible_test/_util/controller/sanity/integration-aliases/yaml_to_json.py +2 -1
  660. ansible_test/_util/controller/sanity/pep8/current-ignore.txt +4 -0
  661. ansible_test/_util/controller/sanity/pylint/config/ansible-test-target.cfg +7 -5
  662. ansible_test/_util/controller/sanity/pylint/config/ansible-test.cfg +7 -5
  663. ansible_test/_util/controller/sanity/pylint/config/code-smell.cfg +7 -5
  664. ansible_test/_util/controller/sanity/pylint/config/collection.cfg +3 -5
  665. ansible_test/_util/controller/sanity/pylint/config/default.cfg +7 -7
  666. ansible_test/_util/controller/sanity/pylint/plugins/deprecated.py +1 -13
  667. ansible_test/_util/controller/sanity/pylint/plugins/hide_unraisable.py +1 -0
  668. ansible_test/_util/controller/sanity/pylint/plugins/string_format.py +1 -8
  669. ansible_test/_util/controller/sanity/pylint/plugins/unwanted.py +1 -8
  670. ansible_test/_util/controller/sanity/validate-modules/validate_modules/main.py +55 -28
  671. ansible_test/_util/controller/sanity/validate-modules/validate_modules/module_args.py +12 -5
  672. ansible_test/_util/controller/sanity/validate-modules/validate_modules/schema.py +13 -2
  673. ansible_test/_util/controller/sanity/validate-modules/validate_modules/utils.py +1 -0
  674. ansible_test/_util/controller/sanity/yamllint/yamllinter.py +35 -17
  675. ansible_test/_util/controller/tools/collection_detail.py +1 -0
  676. ansible_test/_util/controller/tools/yaml_to_json.py +2 -1
  677. ansible_test/_util/target/pytest/plugins/ansible_forked.py +6 -1
  678. ansible_test/_util/target/pytest/plugins/ansible_pytest_collections.py +2 -1
  679. ansible_test/_util/target/pytest/plugins/ansible_pytest_coverage.py +1 -0
  680. ansible_test/_util/target/sanity/compile/compile.py +1 -0
  681. ansible_test/_util/target/sanity/import/importer.py +15 -16
  682. ansible_test/_util/target/setup/bootstrap.sh +9 -20
  683. ansible_test/_util/target/setup/probe_cgroups.py +1 -0
  684. ansible_test/_util/target/setup/quiet_pip.py +1 -0
  685. ansible_test/_util/target/setup/requirements.py +35 -27
  686. ansible_test/_util/target/tools/virtualenvcheck.py +2 -1
  687. ansible_test/_util/target/tools/yamlcheck.py +2 -1
  688. ansible/compat/selectors.py +0 -32
  689. ansible/errors/yaml_strings.py +0 -138
  690. ansible/executor/action_write_locks.py +0 -44
  691. ansible/executor/discovery/python_target.py +0 -47
  692. ansible/executor/powershell/module_powershell_wrapper.ps1 +0 -86
  693. ansible/executor/powershell/module_script_wrapper.ps1 +0 -22
  694. ansible/module_utils/compat/importlib.py +0 -26
  695. ansible/module_utils/compat/selectors.py +0 -32
  696. ansible/module_utils/pycompat24.py +0 -73
  697. ansible/parsing/yaml/constructor.py +0 -178
  698. ansible/template/native_helpers.py +0 -251
  699. ansible/template/template.py +0 -43
  700. ansible/template/vars.py +0 -77
  701. ansible/utils/native_jinja.py +0 -11
  702. ansible/vars/fact_cache.py +0 -71
  703. ansible_core-2.18.5rc1.dist-info/RECORD +0 -992
  704. {ansible_core-2.18.5rc1.dist-info → ansible_core-2.19.0b2.dist-info}/Apache-License.txt +0 -0
  705. {ansible_core-2.18.5rc1.dist-info → ansible_core-2.19.0b2.dist-info}/COPYING +0 -0
  706. {ansible_core-2.18.5rc1.dist-info → ansible_core-2.19.0b2.dist-info}/MIT-license.txt +0 -0
  707. {ansible_core-2.18.5rc1.dist-info → ansible_core-2.19.0b2.dist-info}/PSF-license.txt +0 -0
  708. {ansible_core-2.18.5rc1.dist-info → ansible_core-2.19.0b2.dist-info}/entry_points.txt +0 -0
  709. {ansible_core-2.18.5rc1.dist-info → ansible_core-2.19.0b2.dist-info}/simplified_bsd.txt +0 -0
  710. {ansible_core-2.18.5rc1.dist-info → ansible_core-2.19.0b2.dist-info}/top_level.txt +0 -0
ansible/playbook/base.py CHANGED
@@ -9,24 +9,27 @@ import itertools
9
9
  import operator
10
10
  import os
11
11
 
12
+ import typing as t
13
+
12
14
  from copy import copy as shallowcopy
13
15
  from functools import cache
14
16
 
15
- from jinja2.exceptions import UndefinedError
16
-
17
17
  from ansible import constants as C
18
18
  from ansible import context
19
- from ansible.errors import AnsibleError, AnsibleParserError, AnsibleUndefinedVariable, AnsibleAssertionError
19
+ from ansible.errors import AnsibleError, AnsibleParserError, AnsibleAssertionError, AnsibleValueOmittedError, AnsibleFieldAttributeError
20
+ from ansible.module_utils.datatag import native_type_name
21
+ from ansible._internal._datatag._tags import Origin
20
22
  from ansible.module_utils.six import string_types
21
23
  from ansible.module_utils.parsing.convert_bool import boolean
24
+ from ansible.module_utils.common.sentinel import Sentinel
22
25
  from ansible.module_utils.common.text.converters import to_text
23
26
  from ansible.parsing.dataloader import DataLoader
24
27
  from ansible.playbook.attribute import Attribute, FieldAttribute, ConnectionFieldAttribute, NonInheritableFieldAttribute
25
28
  from ansible.plugins.loader import module_loader, action_loader
26
29
  from ansible.utils.collection_loader._collection_finder import _get_collection_metadata, AnsibleCollectionRef
27
30
  from ansible.utils.display import Display
28
- from ansible.utils.sentinel import Sentinel
29
- from ansible.utils.vars import combine_vars, isidentifier, get_unique_id
31
+ from ansible.utils.vars import combine_vars, get_unique_id, validate_variable_name
32
+ from ansible._internal._templating._engine import TemplateEngine
30
33
 
31
34
  display = Display()
32
35
 
@@ -96,12 +99,13 @@ class FieldAttributeBase:
96
99
  fattributes[attr.alias] = attr
97
100
  return fattributes
98
101
 
99
- def __init__(self):
102
+ def __init__(self) -> None:
100
103
 
101
104
  # initialize the data loader and variable manager, which will be provided
102
105
  # later when the object is actually loaded
103
106
  self._loader = None
104
107
  self._variable_manager = None
108
+ self._origin: Origin | None = None
105
109
 
106
110
  # other internal params
107
111
  self._validated = False
@@ -111,15 +115,12 @@ class FieldAttributeBase:
111
115
  # every object gets a random uuid:
112
116
  self._uuid = get_unique_id()
113
117
 
114
- # init vars, avoid using defaults in field declaration as it lives across plays
115
- self.vars = dict()
116
-
117
118
  @property
118
119
  def finalized(self):
119
120
  return self._finalized
120
121
 
121
122
  def dump_me(self, depth=0):
122
- ''' this is never called from production code, it is here to be used when debugging as a 'complex print' '''
123
+ """ this is never called from production code, it is here to be used when debugging as a 'complex print' """
123
124
  if depth == 0:
124
125
  display.debug("DUMPING OBJECT ------------------------------------------------------")
125
126
  display.debug("%s- %s (%s, id=%s)" % (" " * depth, self.__class__.__name__, self, id(self)))
@@ -133,11 +134,11 @@ class FieldAttributeBase:
133
134
  self._play.dump_me(depth + 2)
134
135
 
135
136
  def preprocess_data(self, ds):
136
- ''' infrequently used method to do some pre-processing of legacy terms '''
137
+ """ infrequently used method to do some pre-processing of legacy terms """
137
138
  return ds
138
139
 
139
140
  def load_data(self, ds, variable_manager=None, loader=None):
140
- ''' walk the input datastructure and assign any values '''
141
+ """ walk the input datastructure and assign any values """
141
142
 
142
143
  if ds is None:
143
144
  raise AnsibleAssertionError('ds (%s) should not be None but it is.' % ds)
@@ -148,6 +149,7 @@ class FieldAttributeBase:
148
149
  # the variable manager class is used to manage and merge variables
149
150
  # down to a single dictionary for reference in templating, etc.
150
151
  self._variable_manager = variable_manager
152
+ self._origin = Origin.get_tag(ds)
151
153
 
152
154
  # the data loader class is used to parse data from strings and files
153
155
  if loader is not None:
@@ -191,25 +193,29 @@ class FieldAttributeBase:
191
193
  return self._variable_manager
192
194
 
193
195
  def _post_validate_debugger(self, attr, value, templar):
194
- value = templar.template(value)
196
+ try:
197
+ value = templar.template(value)
198
+ except AnsibleValueOmittedError:
199
+ value = self.set_to_context(attr.name)
200
+
195
201
  valid_values = frozenset(('always', 'on_failed', 'on_unreachable', 'on_skipped', 'never'))
196
202
  if value and isinstance(value, string_types) and value not in valid_values:
197
203
  raise AnsibleParserError("'%s' is not a valid value for debugger. Must be one of %s" % (value, ', '.join(valid_values)), obj=self.get_ds())
198
204
  return value
199
205
 
200
206
  def _validate_attributes(self, ds):
201
- '''
207
+ """
202
208
  Ensures that there are no keys in the datastructure which do
203
209
  not map to attributes for this object.
204
- '''
210
+ """
205
211
 
206
212
  valid_attrs = frozenset(self.fattributes)
207
213
  for key in ds:
208
214
  if key not in valid_attrs:
209
- raise AnsibleParserError("'%s' is not a valid attribute for a %s" % (key, self.__class__.__name__), obj=ds)
215
+ raise AnsibleParserError("'%s' is not a valid attribute for a %s" % (key, self.__class__.__name__), obj=key)
210
216
 
211
217
  def validate(self, all_vars=None):
212
- ''' validation that is done at parse time, not load time '''
218
+ """ validation that is done at parse time, not load time """
213
219
  all_vars = {} if all_vars is None else all_vars
214
220
 
215
221
  if not self._validated:
@@ -244,7 +250,8 @@ class FieldAttributeBase:
244
250
  raise AnsibleParserError(
245
251
  "The field 'module_defaults' is supposed to be a dictionary or list of dictionaries, "
246
252
  "the keys of which must be static action, module, or group names. Only the values may contain "
247
- "templates. For example: {'ping': \"{{ ping_defaults }}\"}"
253
+ "templates. For example: {'ping': \"{{ ping_defaults }}\"}",
254
+ obj=defaults_dict,
248
255
  )
249
256
 
250
257
  validated_defaults_dict = {}
@@ -402,31 +409,32 @@ class FieldAttributeBase:
402
409
  display.vvvvv("Could not resolve action %s in module_defaults" % action_name)
403
410
 
404
411
  def squash(self):
405
- '''
412
+ """
406
413
  Evaluates all attributes and sets them to the evaluated version,
407
414
  so that all future accesses of attributes do not need to evaluate
408
415
  parent attributes.
409
- '''
416
+ """
410
417
  if not self._squashed:
411
418
  for name in self.fattributes:
412
419
  setattr(self, name, getattr(self, name))
413
420
  self._squashed = True
414
421
 
415
422
  def copy(self):
416
- '''
423
+ """
417
424
  Create a copy of this object and return it.
418
- '''
425
+ """
419
426
 
420
427
  try:
421
428
  new_me = self.__class__()
422
- except RuntimeError as e:
423
- raise AnsibleError("Exceeded maximum object depth. This may have been caused by excessive role recursion", orig_exc=e)
429
+ except RecursionError as ex:
430
+ raise AnsibleError("Exceeded maximum object depth. This may have been caused by excessive role recursion.") from ex
424
431
 
425
432
  for name in self.fattributes:
426
433
  setattr(new_me, name, shallowcopy(getattr(self, f'_{name}', Sentinel)))
427
434
 
428
435
  new_me._loader = self._loader
429
436
  new_me._variable_manager = self._variable_manager
437
+ new_me._origin = self._origin
430
438
  new_me._validated = self._validated
431
439
  new_me._finalized = self._finalized
432
440
  new_me._uuid = self._uuid
@@ -438,6 +446,12 @@ class FieldAttributeBase:
438
446
  return new_me
439
447
 
440
448
  def get_validated_value(self, name, attribute, value, templar):
449
+ try:
450
+ return self._get_validated_value(name, attribute, value, templar)
451
+ except (TypeError, ValueError):
452
+ raise AnsibleError(f"The value {value!r} could not be converted to {attribute.isa!r}.", obj=value)
453
+
454
+ def _get_validated_value(self, name, attribute, value, templar):
441
455
  if attribute.isa == 'string':
442
456
  value = to_text(value)
443
457
  elif attribute.isa == 'int':
@@ -466,28 +480,23 @@ class FieldAttributeBase:
466
480
  if attribute.listof is not None:
467
481
  for item in value:
468
482
  if not isinstance(item, attribute.listof):
469
- raise AnsibleParserError("the field '%s' should be a list of %s, "
470
- "but the item '%s' is a %s" % (name, attribute.listof, item, type(item)), obj=self.get_ds())
471
- elif attribute.required and attribute.listof == string_types:
483
+ type_names = ' or '.join(f'{native_type_name(attribute_type)!r}' for attribute_type in attribute.listof)
484
+
485
+ raise AnsibleParserError(
486
+ message=f"Keyword {name!r} items must be of type {type_names}, not {native_type_name(item)!r}.",
487
+ obj=Origin.first_tagged_on(item, value, self.get_ds()),
488
+ )
489
+ elif attribute.required and attribute.listof == (str,):
472
490
  if item is None or item.strip() == "":
473
- raise AnsibleParserError("the field '%s' is required, and cannot have empty values" % (name,), obj=self.get_ds())
474
- elif attribute.isa == 'set':
475
- if value is None:
476
- value = set()
477
- elif not isinstance(value, (list, set)):
478
- if isinstance(value, string_types):
479
- value = value.split(',')
480
- else:
481
- # Making a list like this handles strings of
482
- # text and bytes properly
483
- value = [value]
484
- if not isinstance(value, set):
485
- value = set(value)
491
+ raise AnsibleParserError(
492
+ message=f"Keyword {name!r} is required, and cannot have empty values.",
493
+ obj=Origin.first_tagged_on(item, value, self.get_ds()),
494
+ )
486
495
  elif attribute.isa == 'dict':
487
496
  if value is None:
488
497
  value = dict()
489
498
  elif not isinstance(value, dict):
490
- raise TypeError("%s is not a dictionary" % value)
499
+ raise AnsibleError(f"{value!r} is not a dictionary")
491
500
  elif attribute.isa == 'class':
492
501
  if not isinstance(value, attribute.class_type):
493
502
  raise TypeError("%s is not a valid %s (got a %s instead)" % (name, attribute.class_type, type(value)))
@@ -496,119 +505,132 @@ class FieldAttributeBase:
496
505
  raise AnsibleAssertionError(f"Unknown value for attribute.isa: {attribute.isa}")
497
506
  return value
498
507
 
499
- def set_to_context(self, name):
500
- ''' set to parent inherited value or Sentinel as appropriate'''
508
+ def set_to_context(self, name: str) -> t.Any:
509
+ """ set to parent inherited value or Sentinel as appropriate"""
501
510
 
502
511
  attribute = self.fattributes[name]
503
512
  if isinstance(attribute, NonInheritableFieldAttribute):
504
513
  # setting to sentinel will trigger 'default/default()' on getter
505
- setattr(self, name, Sentinel)
514
+ value = Sentinel
506
515
  else:
507
516
  try:
508
- setattr(self, name, self._get_parent_attribute(name, omit=True))
517
+ value = self._get_parent_attribute(name, omit=True)
509
518
  except AttributeError:
510
519
  # mostly playcontext as only tasks/handlers/blocks really resolve parent
511
- setattr(self, name, Sentinel)
520
+ value = Sentinel
521
+
522
+ setattr(self, name, value)
523
+ return value
512
524
 
513
525
  def post_validate(self, templar):
514
- '''
526
+ """
515
527
  we can't tell that everything is of the right type until we have
516
528
  all the variables. Run basic types (from isa) as well as
517
529
  any _post_validate_<foo> functions.
518
- '''
530
+ """
519
531
 
520
- # save the omit value for later checking
521
- omit_value = templar.available_variables.get('omit')
532
+ for name in self.fattributes:
533
+ value = self.post_validate_attribute(name, templar=templar)
522
534
 
523
- for (name, attribute) in self.fattributes.items():
524
- if attribute.static:
525
- value = getattr(self, name)
535
+ if value is not Sentinel:
536
+ # and assign the massaged value back to the attribute field
537
+ setattr(self, name, value)
526
538
 
527
- # we don't template 'vars' but allow template as values for later use
528
- if name not in ('vars',) and templar.is_template(value):
529
- display.warning('"%s" is not templatable, but we found: %s, '
530
- 'it will not be templated and will be used "as is".' % (name, value))
531
- continue
539
+ self._finalized = True
532
540
 
533
- if getattr(self, name) is None:
534
- if not attribute.required:
535
- continue
536
- else:
537
- raise AnsibleParserError("the field '%s' is required but was not set" % name)
538
- elif not attribute.always_post_validate and self.__class__.__name__ not in ('Task', 'Handler', 'PlayContext'):
539
- # Intermediate objects like Play() won't have their fields validated by
540
- # default, as their values are often inherited by other objects and validated
541
- # later, so we don't want them to fail out early
542
- continue
541
+ def post_validate_attribute(self, name: str, *, templar: TemplateEngine):
542
+ attribute: FieldAttribute = self.fattributes[name]
543
543
 
544
- try:
545
- # Run the post-validator if present. These methods are responsible for
546
- # using the given templar to template the values, if required.
547
- method = getattr(self, '_post_validate_%s' % name, None)
548
- if method:
549
- value = method(attribute, getattr(self, name), templar)
550
- elif attribute.isa == 'class':
551
- value = getattr(self, name)
552
- else:
544
+ # DTFIX-FUTURE: this can probably be used in many getattr cases below, but the value may be out-of-date in some cases
545
+ original_value = getattr(self, name) # we save this original (likely Origin-tagged) value to pass as `obj` for errors
546
+
547
+ if attribute.static:
548
+ value = getattr(self, name)
549
+
550
+ # we don't template 'vars' but allow template as values for later use
551
+ if name not in ('vars',) and templar.is_template(value):
552
+ display.warning('"%s" is not templatable, but we found: %s, '
553
+ 'it will not be templated and will be used "as is".' % (name, value))
554
+ return Sentinel
555
+
556
+ if getattr(self, name) is None:
557
+ if not attribute.required:
558
+ return Sentinel
559
+
560
+ raise AnsibleFieldAttributeError(f'The field {name!r} is required but was not set.', obj=self.get_ds())
561
+
562
+ from .role_include import IncludeRole
563
+
564
+ if not attribute.always_post_validate and isinstance(self, IncludeRole) and self.statically_loaded: # import_role
565
+ # normal field attributes should not go through post validation on import_role/import_tasks
566
+ # only import_role is checked here because import_tasks never reaches this point
567
+ return Sentinel
568
+
569
+ # FIXME: compare types, not strings
570
+ if not attribute.always_post_validate and self.__class__.__name__ not in ('Task', 'Handler', 'PlayContext', 'IncludeRole', 'TaskInclude'):
571
+ # Intermediate objects like Play() won't have their fields validated by
572
+ # default, as their values are often inherited by other objects and validated
573
+ # later, so we don't want them to fail out early
574
+ return Sentinel
575
+
576
+ try:
577
+ # Run the post-validator if present. These methods are responsible for
578
+ # using the given templar to template the values, if required.
579
+ method = getattr(self, '_post_validate_%s' % name, None)
580
+
581
+ if method:
582
+ value = method(attribute, getattr(self, name), templar)
583
+ elif attribute.isa == 'class':
584
+ value = getattr(self, name)
585
+ else:
586
+ try:
553
587
  # if the attribute contains a variable, template it now
554
588
  value = templar.template(getattr(self, name))
589
+ except AnsibleValueOmittedError:
590
+ # If this evaluated to the omit value, set the value back to inherited by context
591
+ # or default specified in the FieldAttribute and move on
592
+ value = self.set_to_context(name)
555
593
 
556
- # If this evaluated to the omit value, set the value back to inherited by context
557
- # or default specified in the FieldAttribute and move on
558
- if omit_value is not None and value == omit_value:
559
- self.set_to_context(name)
560
- continue
594
+ if value is Sentinel:
595
+ return value
561
596
 
562
- # and make sure the attribute is of the type it should be
563
- if value is not None:
564
- value = self.get_validated_value(name, attribute, value, templar)
597
+ # and make sure the attribute is of the type it should be
598
+ if value is not None:
599
+ value = self.get_validated_value(name, attribute, value, templar)
565
600
 
566
- # and assign the massaged value back to the attribute field
567
- setattr(self, name, value)
568
- except (TypeError, ValueError) as e:
569
- value = getattr(self, name)
570
- raise AnsibleParserError(f"the field '{name}' has an invalid value ({value!r}), and could not be converted to {attribute.isa}.",
571
- obj=self.get_ds(), orig_exc=e)
572
- except (AnsibleUndefinedVariable, UndefinedError) as e:
573
- if templar._fail_on_undefined_errors and name != 'name':
574
- if name == 'args':
575
- msg = "The task includes an option with an undefined variable."
576
- else:
577
- msg = f"The field '{name}' has an invalid value, which includes an undefined variable."
578
- raise AnsibleParserError(msg, obj=self.get_ds(), orig_exc=e)
601
+ # returning the value results in assigning the massaged value back to the attribute field
602
+ return value
603
+ except Exception as ex:
604
+ if name == 'args':
605
+ raise # no useful information to contribute, raise the original exception
579
606
 
580
- self._finalized = True
607
+ raise AnsibleFieldAttributeError(f'Error processing keyword {name!r}.', obj=original_value) from ex
581
608
 
582
609
  def _load_vars(self, attr, ds):
583
- '''
610
+ """
584
611
  Vars in a play must be specified as a dictionary.
585
- '''
586
-
587
- def _validate_variable_keys(ds):
588
- for key in ds:
589
- if not isidentifier(key):
590
- raise TypeError("'%s' is not a valid variable name" % key)
612
+ """
591
613
 
592
614
  try:
593
615
  if isinstance(ds, dict):
594
- _validate_variable_keys(ds)
616
+ for key in ds:
617
+ validate_variable_name(key)
595
618
  return combine_vars(self.vars, ds)
596
619
  elif ds is None:
597
620
  return {}
598
621
  else:
599
622
  raise ValueError
600
- except ValueError as e:
601
- raise AnsibleParserError("Vars in a %s must be specified as a dictionary" % self.__class__.__name__,
602
- obj=ds, orig_exc=e)
603
- except TypeError as e:
604
- raise AnsibleParserError("Invalid variable name in vars specified for %s: %s" % (self.__class__.__name__, e), obj=ds, orig_exc=e)
623
+ except ValueError as ex:
624
+ raise AnsibleParserError(f"Vars in a {self.__class__.__name__} must be specified as a dictionary.", obj=ds) from ex
625
+ except TypeError as ex:
626
+ raise AnsibleParserError(f"Invalid variable name in vars specified for {self.__class__.__name__}.", obj=ds) from ex
605
627
 
606
628
  def _extend_value(self, value, new_value, prepend=False):
607
- '''
629
+ """
608
630
  Will extend the value given with new_value (and will turn both
609
631
  into lists if they are not so already). The values are run through
610
632
  a set to remove duplicate values.
611
- '''
633
+ """
612
634
 
613
635
  if not isinstance(value, list):
614
636
  value = [value]
@@ -629,9 +651,9 @@ class FieldAttributeBase:
629
651
  return [i for i, dummy in itertools.groupby(combined) if i is not None]
630
652
 
631
653
  def dump_attrs(self):
632
- '''
654
+ """
633
655
  Dumps all attributes to a dictionary
634
- '''
656
+ """
635
657
  attrs = {}
636
658
  for (name, attribute) in self.fattributes.items():
637
659
  attr = getattr(self, name)
@@ -642,9 +664,9 @@ class FieldAttributeBase:
642
664
  return attrs
643
665
 
644
666
  def from_attrs(self, attrs):
645
- '''
667
+ """
646
668
  Loads attributes from a dictionary
647
- '''
669
+ """
648
670
  for (attr, value) in attrs.items():
649
671
  if attr in self.fattributes:
650
672
  attribute = self.fattributes[attr]
@@ -654,6 +676,8 @@ class FieldAttributeBase:
654
676
  setattr(self, attr, obj)
655
677
  else:
656
678
  setattr(self, attr, value)
679
+ else:
680
+ setattr(self, attr, value) # overridden dump_attrs in derived types may dump attributes which are not field attributes
657
681
 
658
682
  # from_attrs is only used to create a finalized task
659
683
  # from attrs from the Worker/TaskExecutor
@@ -663,13 +687,13 @@ class FieldAttributeBase:
663
687
  self._squashed = True
664
688
 
665
689
  def serialize(self):
666
- '''
690
+ """
667
691
  Serializes the object derived from the base object into
668
692
  a dictionary of values. This only serializes the field
669
693
  attributes for the object, so this may need to be overridden
670
694
  for any classes which wish to add additional items not stored
671
695
  as field attributes.
672
- '''
696
+ """
673
697
 
674
698
  repr = self.dump_attrs()
675
699
 
@@ -681,12 +705,12 @@ class FieldAttributeBase:
681
705
  return repr
682
706
 
683
707
  def deserialize(self, data):
684
- '''
708
+ """
685
709
  Given a dictionary of values, load up the field attributes for
686
710
  this object. As with serialize(), if there are any non-field
687
711
  attribute data members, this method will need to be overridden
688
712
  and extended.
689
- '''
713
+ """
690
714
 
691
715
  if not isinstance(data, dict):
692
716
  raise AnsibleAssertionError('data (%s) should be a dict but is a %s' % (data, type(data)))
@@ -713,7 +737,7 @@ class Base(FieldAttributeBase):
713
737
  remote_user = FieldAttribute(isa='string', default=context.cliargs_deferred_get('remote_user'))
714
738
 
715
739
  # variables
716
- vars = NonInheritableFieldAttribute(isa='dict', priority=100, static=True)
740
+ vars = NonInheritableFieldAttribute(isa='dict', priority=100, static=True, default=dict)
717
741
 
718
742
  # module default params
719
743
  module_defaults = FieldAttribute(isa='list', extend=True, prepend=True)
@@ -743,17 +767,43 @@ class Base(FieldAttributeBase):
743
767
  # used to hold sudo/su stuff
744
768
  DEPRECATED_ATTRIBUTES = [] # type: list[str]
745
769
 
746
- def get_path(self):
747
- ''' return the absolute path of the playbook object and its line number '''
770
+ def update_result_no_log(self, templar: TemplateEngine, result: dict[str, t.Any]) -> None:
771
+ """Set the post-validated no_log value for the result, falling back to a default on validation/templating failure with a warning."""
748
772
 
749
- path = ""
750
- try:
751
- path = "%s:%s" % (self._ds._data_source, self._ds._line_number)
752
- except AttributeError:
773
+ if self.finalized:
774
+ no_log = self.no_log
775
+ else:
753
776
  try:
754
- path = "%s:%s" % (self._parent._play._ds._data_source, self._parent._play._ds._line_number)
777
+ no_log = self.post_validate_attribute('no_log', templar=templar)
778
+ except Exception as ex:
779
+ display.error_as_warning('Invalid no_log value for task, output will be masked.', exception=ex)
780
+ no_log = True
781
+
782
+ result_no_log = result.get('_ansible_no_log', False)
783
+
784
+ if not isinstance(result_no_log, bool):
785
+ display.warning(f'Invalid _ansible_no_log value of type {type(result_no_log).__name__!r} in task result, output will be masked.')
786
+ no_log = True
787
+
788
+ no_log = no_log or result_no_log
789
+
790
+ result.update(_ansible_no_log=no_log)
791
+
792
+ def get_path(self) -> str:
793
+ """ return the absolute path of the playbook object and its line number """
794
+ origin = self._origin
795
+
796
+ if not origin:
797
+ try:
798
+ origin = self._parent._play._origin
755
799
  except AttributeError:
756
800
  pass
801
+
802
+ if origin and origin.path:
803
+ path = f"{origin.path}:{origin.line_num or 1}"
804
+ else:
805
+ path = ""
806
+
757
807
  return path
758
808
 
759
809
  def get_dep_chain(self):
@@ -764,10 +814,10 @@ class Base(FieldAttributeBase):
764
814
  return None
765
815
 
766
816
  def get_search_path(self):
767
- '''
817
+ """
768
818
  Return the list of paths you should search for files, in order.
769
819
  This follows role/playbook dependency chain.
770
- '''
820
+ """
771
821
  path_stack = []
772
822
 
773
823
  dep_chain = self.get_dep_chain()