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
File without changes
@@ -0,0 +1,240 @@
1
+ from __future__ import annotations
2
+
3
+ import abc
4
+ import copy
5
+ import typing as t
6
+
7
+ from yaml import Node
8
+ from yaml.constructor import SafeConstructor
9
+ from yaml.resolver import BaseResolver
10
+
11
+ from ansible import constants as C
12
+ from ansible.module_utils.common.text.converters import to_text
13
+ from ansible.module_utils._internal._datatag import AnsibleTagHelper
14
+ from ansible._internal._datatag._tags import Origin, TrustedAsTemplate
15
+ from ansible.parsing.vault import EncryptedString
16
+ from ansible.utils.display import Display
17
+
18
+ from ._errors import AnsibleConstructorError
19
+
20
+ display = Display()
21
+
22
+ _TRUSTED_AS_TEMPLATE: t.Final[TrustedAsTemplate] = TrustedAsTemplate()
23
+
24
+
25
+ class _BaseConstructor(SafeConstructor, metaclass=abc.ABCMeta):
26
+ """Base class for Ansible YAML constructors."""
27
+
28
+ @classmethod
29
+ @abc.abstractmethod
30
+ def _register_constructors(cls) -> None:
31
+ """Method used to register constructors to derived types during class initialization."""
32
+
33
+ def __init_subclass__(cls, **kwargs) -> None:
34
+ """Initialization for derived types."""
35
+ cls._register_constructors()
36
+
37
+
38
+ class AnsibleInstrumentedConstructor(_BaseConstructor):
39
+ """Ansible constructor which supports Ansible custom behavior such as `Origin` tagging, but no Ansible-specific YAML tags."""
40
+
41
+ name: t.Any # provided by the YAML parser, which retrieves it from the stream
42
+
43
+ def __init__(self, origin: Origin, trusted_as_template: bool) -> None:
44
+ if not origin.line_num:
45
+ origin = origin.replace(line_num=1)
46
+
47
+ self._origin = origin
48
+ self._trusted_as_template = trusted_as_template
49
+ self._duplicate_key_mode = C.config.get_config_value('DUPLICATE_YAML_DICT_KEY')
50
+
51
+ super().__init__()
52
+
53
+ @property
54
+ def trusted_as_template(self) -> bool:
55
+ return self._trusted_as_template
56
+
57
+ def construct_yaml_map(self, node):
58
+ data = self._node_position_info(node).tag({}) # always an ordered dictionary on py3.7+
59
+ yield data
60
+ value = self.construct_mapping(node)
61
+ data.update(value)
62
+
63
+ def construct_mapping(self, node, deep=False):
64
+ # Delegate to built-in implementation to construct the mapping.
65
+ # This is done before checking for duplicates to leverage existing error checking on the input node.
66
+ mapping = super().construct_mapping(node, deep)
67
+ keys = set()
68
+
69
+ # Now that the node is known to be a valid mapping, handle any duplicate keys.
70
+ for key_node, _value_node in node.value:
71
+ if (key := self.construct_object(key_node, deep=deep)) in keys:
72
+ msg = f'Found duplicate mapping key {key!r}.'
73
+
74
+ if self._duplicate_key_mode == 'error':
75
+ raise AnsibleConstructorError(problem=msg, problem_mark=key_node.start_mark)
76
+
77
+ if self._duplicate_key_mode == 'warn':
78
+ display.warning(msg=msg, obj=key, help_text='Using last defined value only.')
79
+
80
+ keys.add(key)
81
+
82
+ return mapping
83
+
84
+ def construct_yaml_int(self, node):
85
+ value = super().construct_yaml_int(node)
86
+ return self._node_position_info(node).tag(value)
87
+
88
+ def construct_yaml_float(self, node):
89
+ value = super().construct_yaml_float(node)
90
+ return self._node_position_info(node).tag(value)
91
+
92
+ def construct_yaml_timestamp(self, node):
93
+ value = super().construct_yaml_timestamp(node)
94
+ return self._node_position_info(node).tag(value)
95
+
96
+ def construct_yaml_omap(self, node):
97
+ origin = self._node_position_info(node)
98
+ display.deprecated(
99
+ msg='Use of the YAML `!!omap` tag is deprecated.',
100
+ version='2.23',
101
+ obj=origin,
102
+ help_text='Use a standard mapping instead, as key order is always preserved.',
103
+ )
104
+ items = list(super().construct_yaml_omap(node))[0]
105
+ items = [origin.tag(item) for item in items]
106
+ yield origin.tag(items)
107
+
108
+ def construct_yaml_pairs(self, node):
109
+ origin = self._node_position_info(node)
110
+ display.deprecated(
111
+ msg='Use of the YAML `!!pairs` tag is deprecated.',
112
+ version='2.23',
113
+ obj=origin,
114
+ help_text='Use a standard mapping instead.',
115
+ )
116
+ items = list(super().construct_yaml_pairs(node))[0]
117
+ items = [origin.tag(item) for item in items]
118
+ yield origin.tag(items)
119
+
120
+ def construct_yaml_str(self, node):
121
+ # Override the default string handling function
122
+ # to always return unicode objects
123
+ # DTFIX-FUTURE: is this to_text conversion still necessary under Py3?
124
+ value = to_text(self.construct_scalar(node))
125
+
126
+ tags = [self._node_position_info(node)]
127
+
128
+ if self.trusted_as_template:
129
+ # NB: since we're not context aware, this will happily add trust to dictionary keys; this is actually necessary for
130
+ # certain backward compat scenarios, though might be accomplished in other ways if we wanted to avoid trusting keys in
131
+ # the general scenario
132
+ tags.append(_TRUSTED_AS_TEMPLATE)
133
+
134
+ return AnsibleTagHelper.tag(value, tags)
135
+
136
+ def construct_yaml_binary(self, node):
137
+ value = super().construct_yaml_binary(node)
138
+
139
+ return AnsibleTagHelper.tag(value, self._node_position_info(node))
140
+
141
+ def construct_yaml_set(self, node):
142
+ data = AnsibleTagHelper.tag(set(), self._node_position_info(node))
143
+ yield data
144
+ value = self.construct_mapping(node)
145
+ data.update(value)
146
+
147
+ def construct_yaml_seq(self, node):
148
+ data = self._node_position_info(node).tag([])
149
+ yield data
150
+ data.extend(self.construct_sequence(node))
151
+
152
+ def _resolve_and_construct_object(self, node):
153
+ # use a copied node to avoid mutating existing node and tripping the recursion check in construct_object
154
+ copied_node = copy.copy(node)
155
+ # repeat implicit resolution process to determine the proper tag for the value in the unsafe node
156
+ copied_node.tag = t.cast(BaseResolver, self).resolve(type(node), node.value, (True, False))
157
+
158
+ # re-entrant call using the correct tag
159
+ # non-deferred construction of hierarchical nodes so the result is a fully realized object, and so our stateful unsafe propagation behavior works
160
+ return self.construct_object(copied_node, deep=True)
161
+
162
+ def _node_position_info(self, node) -> Origin:
163
+ # the line number where the previous token has ended (plus empty lines)
164
+ # Add one so that the first line is line 1 rather than line 0
165
+ return self._origin.replace(line_num=node.start_mark.line + self._origin.line_num, col_num=node.start_mark.column + 1)
166
+
167
+ @classmethod
168
+ def _register_constructors(cls) -> None:
169
+ constructors: dict[str, t.Callable] = {
170
+ 'tag:yaml.org,2002:binary': cls.construct_yaml_binary,
171
+ 'tag:yaml.org,2002:float': cls.construct_yaml_float,
172
+ 'tag:yaml.org,2002:int': cls.construct_yaml_int,
173
+ 'tag:yaml.org,2002:map': cls.construct_yaml_map,
174
+ 'tag:yaml.org,2002:omap': cls.construct_yaml_omap,
175
+ 'tag:yaml.org,2002:pairs': cls.construct_yaml_pairs,
176
+ 'tag:yaml.org,2002:python/dict': cls.construct_yaml_map,
177
+ 'tag:yaml.org,2002:python/unicode': cls.construct_yaml_str,
178
+ 'tag:yaml.org,2002:seq': cls.construct_yaml_seq,
179
+ 'tag:yaml.org,2002:set': cls.construct_yaml_set,
180
+ 'tag:yaml.org,2002:str': cls.construct_yaml_str,
181
+ 'tag:yaml.org,2002:timestamp': cls.construct_yaml_timestamp,
182
+ }
183
+
184
+ for tag, constructor in constructors.items():
185
+ cls.add_constructor(tag, constructor)
186
+
187
+
188
+ class AnsibleConstructor(AnsibleInstrumentedConstructor):
189
+ """Ansible constructor which supports Ansible custom behavior such as `Origin` tagging, as well as Ansible-specific YAML tags."""
190
+
191
+ def __init__(self, origin: Origin, trusted_as_template: bool) -> None:
192
+ self._unsafe_depth = 0 # volatile state var used during recursive construction of a value tagged unsafe
193
+
194
+ super().__init__(origin=origin, trusted_as_template=trusted_as_template)
195
+
196
+ @property
197
+ def trusted_as_template(self) -> bool:
198
+ return self._trusted_as_template and not self._unsafe_depth
199
+
200
+ def construct_yaml_unsafe(self, node):
201
+ self._unsafe_depth += 1
202
+
203
+ try:
204
+ return self._resolve_and_construct_object(node)
205
+ finally:
206
+ self._unsafe_depth -= 1
207
+
208
+ def construct_yaml_vault(self, node: Node) -> EncryptedString:
209
+ ciphertext = self._resolve_and_construct_object(node)
210
+
211
+ if not isinstance(ciphertext, str):
212
+ raise AnsibleConstructorError(problem=f"the {node.tag!r} tag requires a string value", problem_mark=node.start_mark)
213
+
214
+ encrypted_string = AnsibleTagHelper.tag_copy(ciphertext, EncryptedString(ciphertext=AnsibleTagHelper.untag(ciphertext)))
215
+
216
+ return encrypted_string
217
+
218
+ def construct_yaml_vault_encrypted(self, node: Node) -> EncryptedString:
219
+ origin = self._node_position_info(node)
220
+ display.deprecated(
221
+ msg='Use of the YAML `!vault-encrypted` tag is deprecated.',
222
+ version='2.23',
223
+ obj=origin,
224
+ help_text='Use the `!vault` tag instead.',
225
+ )
226
+
227
+ return self.construct_yaml_vault(node)
228
+
229
+ @classmethod
230
+ def _register_constructors(cls) -> None:
231
+ super()._register_constructors()
232
+
233
+ constructors: dict[str, t.Callable] = {
234
+ '!unsafe': cls.construct_yaml_unsafe,
235
+ '!vault': cls.construct_yaml_vault,
236
+ '!vault-encrypted': cls.construct_yaml_vault_encrypted,
237
+ }
238
+
239
+ for tag, constructor in constructors.items():
240
+ cls.add_constructor(tag, constructor)
@@ -0,0 +1,62 @@
1
+ from __future__ import annotations
2
+
3
+ import abc
4
+ import collections.abc as c
5
+ import typing as t
6
+
7
+ from yaml.representer import SafeRepresenter
8
+
9
+ from ansible.module_utils._internal._datatag import AnsibleTaggedObject, Tripwire, AnsibleTagHelper
10
+ from ansible.parsing.vault import VaultHelper
11
+ from ansible.module_utils.common.yaml import HAS_LIBYAML
12
+
13
+ if HAS_LIBYAML:
14
+ from yaml.cyaml import CSafeDumper as SafeDumper
15
+ else:
16
+ from yaml import SafeDumper # type: ignore[assignment]
17
+
18
+
19
+ class _BaseDumper(SafeDumper, metaclass=abc.ABCMeta):
20
+ """Base class for Ansible YAML dumpers."""
21
+
22
+ @classmethod
23
+ @abc.abstractmethod
24
+ def _register_representers(cls) -> None:
25
+ """Method used to register representers to derived types during class initialization."""
26
+
27
+ def __init_subclass__(cls, **kwargs) -> None:
28
+ """Initialization for derived types."""
29
+ cls._register_representers()
30
+
31
+
32
+ class AnsibleDumper(_BaseDumper):
33
+ """A simple stub class that allows us to add representers for our custom types."""
34
+
35
+ # DTFIX-RELEASE: need a better way to handle serialization controls during YAML dumping
36
+ def __init__(self, *args, dump_vault_tags: bool | None = None, **kwargs):
37
+ super().__init__(*args, **kwargs)
38
+
39
+ self._dump_vault_tags = dump_vault_tags
40
+
41
+ @classmethod
42
+ def _register_representers(cls) -> None:
43
+ cls.add_multi_representer(AnsibleTaggedObject, cls.represent_ansible_tagged_object)
44
+ cls.add_multi_representer(Tripwire, cls.represent_tripwire)
45
+ cls.add_multi_representer(c.Mapping, SafeRepresenter.represent_dict)
46
+ cls.add_multi_representer(c.Sequence, SafeRepresenter.represent_list)
47
+
48
+ def represent_ansible_tagged_object(self, data):
49
+ if self._dump_vault_tags is not False and (ciphertext := VaultHelper.get_ciphertext(data, with_tags=False)):
50
+ # deprecated: description='enable the deprecation warning below' core_version='2.23'
51
+ # if self._dump_vault_tags is None:
52
+ # Display().deprecated(
53
+ # msg="Implicit YAML dumping of vaulted value ciphertext is deprecated. Set `dump_vault_tags` to explicitly specify the desired behavior",
54
+ # version="2.27",
55
+ # )
56
+
57
+ return self.represent_scalar('!vault', ciphertext, style='|')
58
+
59
+ return self.represent_data(AnsibleTagHelper.as_native_type(data)) # automatically decrypts encrypted strings
60
+
61
+ def represent_tripwire(self, data: Tripwire) -> t.NoReturn:
62
+ data.trip()
@@ -0,0 +1,166 @@
1
+ from __future__ import annotations
2
+
3
+ import re
4
+
5
+ import typing as t
6
+
7
+ from yaml import MarkedYAMLError
8
+ from yaml.constructor import ConstructorError
9
+
10
+ from ansible._internal._errors import _utils
11
+ from ansible.errors import AnsibleParserError
12
+ from ansible._internal._datatag._tags import Origin
13
+
14
+
15
+ class AnsibleConstructorError(ConstructorError):
16
+ """Ansible-specific ConstructorError used to bypass exception analysis during wrapping in AnsibleYAMLParserError."""
17
+
18
+
19
+ class AnsibleYAMLParserError(AnsibleParserError):
20
+ """YAML-specific parsing failure wrapping an exception raised by the YAML parser."""
21
+
22
+ _default_message = 'YAML parsing failed.'
23
+
24
+ _include_cause_message = False # hide the underlying cause message, it's included by `handle_exception` as needed
25
+
26
+ _formatted_source_context_value: str | None = None
27
+
28
+ @property
29
+ def _formatted_source_context(self) -> str | None:
30
+ return self._formatted_source_context_value
31
+
32
+ @classmethod
33
+ def handle_exception(cls, exception: Exception, origin: Origin) -> t.NoReturn:
34
+ if isinstance(exception, MarkedYAMLError):
35
+ origin = origin.replace(line_num=exception.problem_mark.line + 1, col_num=exception.problem_mark.column + 1)
36
+
37
+ source_context = _utils.SourceContext.from_origin(origin)
38
+
39
+ target_line = source_context.target_line or '' # for these cases, we don't need to distinguish between None and empty string
40
+
41
+ message: str | None = None
42
+ help_text = None
43
+
44
+ # FIXME: Do all this by walking the parsed YAML doc stream. Using regexes is a dead-end; YAML's just too flexible to not have a
45
+ # raft of false-positives and corner cases. If we directly consume either the YAML parse stream or override the YAML composer, we can
46
+ # better catch these things without worrying about duplicating YAML's scalar parsing logic around quoting/escaping. At first, we can
47
+ # replace the regex logic below with tiny special-purpose parse consumers to catch specific issues, but ideally, we could do a lot of this
48
+ # inline with the actual doc parse, since our rules are a lot more strict than YAML's (eg, no support for non-scalar keys), and a lot of the
49
+ # problem cases where that comes into play are around expression quoting and Jinja {{ syntax looking like weird YAML values we don't support.
50
+ # Some common examples, where -> is "what YAML actually sees":
51
+ # foo: {{ bar }} -> {"foo": {{"bar": None}: None}} - a mapping with a mapping as its key (legal YAML, but not legal Python/Ansible)
52
+ #
53
+ # - copy: src=foo.txt # kv syntax (kv could be on following line(s), too- implicit multi-line block scalar)
54
+ # dest: bar.txt # orphaned mapping, since the value of `copy` is the scalar "src=foo.txt"
55
+ #
56
+ # - msg == "Error: 'dude' was not found" # unquoted scalar has a : in it -> {'msg == "Error"': 'dude'} [ was not found" ] is garbage orphan scalar
57
+
58
+ # noinspection PyUnboundLocalVariable
59
+ if not isinstance(exception, MarkedYAMLError):
60
+ pass # unexpected exception, don't use special analysis of exception
61
+
62
+ elif isinstance(exception, AnsibleConstructorError):
63
+ pass # raised internally by ansible code, don't use special analysis of exception
64
+
65
+ # Check for tabs.
66
+ # There may be cases where there is a valid tab in a line that has other errors.
67
+ # That's OK, users should "fix" their tab usage anyway -- at which point later error handling logic will hopefully find the real issue.
68
+ elif (tab_idx := target_line.find('\t')) >= 0:
69
+ source_context = _utils.SourceContext.from_origin(origin.replace(col_num=tab_idx + 1))
70
+ message = "Tabs are usually invalid in YAML."
71
+
72
+ # Check for unquoted templates.
73
+ elif match := re.search(r'^\s*(?:-\s+)*(?:[\w\s]+:\s+)?(?P<value>\{\{.*}})', target_line):
74
+ source_context = _utils.SourceContext.from_origin(origin.replace(col_num=match.start('value') + 1))
75
+ message = 'This may be an issue with missing quotes around a template block.'
76
+ # FIXME: Use the captured value to show the actual fix required.
77
+ help_text = """
78
+ For example:
79
+
80
+ raw: {{ some_var }}
81
+
82
+ Should be:
83
+
84
+ raw: "{{ some_var }}"
85
+ """
86
+
87
+ # Check for common unquoted colon mistakes.
88
+ elif (
89
+ # ignore lines starting with only whitespace and a colon
90
+ not target_line.lstrip().startswith(':')
91
+ # find the value after list/dict preamble
92
+ and (value_match := re.search(r'^\s*(?:-\s+)*(?:[\w\s\[\]{}]+:\s+)?(?P<value>.*)$', target_line))
93
+ # ignore properly quoted values
94
+ and (target_fragment := _replace_quoted_value(value_match.group('value')))
95
+ # look for an unquoted colon in the value
96
+ and (colon_match := re.search(r':($| )', target_fragment))
97
+ ):
98
+ source_context = _utils.SourceContext.from_origin(origin.replace(col_num=value_match.start('value') + colon_match.start() + 1))
99
+ message = 'Colons in unquoted values must be followed by a non-space character.'
100
+ # FIXME: Use the captured value to show the actual fix required.
101
+ help_text = """
102
+ For example:
103
+
104
+ raw: echo 'name: ansible'
105
+
106
+ Should be:
107
+
108
+ raw: "echo 'name: ansible'"
109
+ """
110
+
111
+ # Check for common quoting mistakes.
112
+ elif match := re.search(r'^\s*(?:-\s+)*(?:[\w\s]+:\s+)?(?P<value>[\"\'].*?\s*)$', target_line):
113
+ suspected_value = match.group('value')
114
+ first, last = suspected_value[0], suspected_value[-1]
115
+
116
+ if first != last: # "foo" in bar
117
+ source_context = _utils.SourceContext.from_origin(origin.replace(col_num=match.start('value') + 1))
118
+ message = 'Values starting with a quote must end with the same quote.'
119
+ # FIXME: Use the captured value to show the actual fix required, and use that same logic to improve the origin further.
120
+ help_text = """
121
+ For example:
122
+
123
+ raw: "foo" in bar
124
+
125
+ Should be:
126
+
127
+ raw: '"foo" in bar'
128
+ """
129
+ elif first == last and target_line.count(first) > 2: # "foo" and "bar"
130
+ source_context = _utils.SourceContext.from_origin(origin.replace(col_num=match.start('value') + 1))
131
+ message = 'Values starting with a quote must end with the same quote, and not contain that quote.'
132
+ # FIXME: Use the captured value to show the actual fix required, and use that same logic to improve the origin further.
133
+ help_text = """
134
+ For example:
135
+
136
+ raw: "foo" in "bar"
137
+
138
+ Should be:
139
+
140
+ raw: '"foo" in "bar"'
141
+ """
142
+
143
+ if not message:
144
+ if isinstance(exception, MarkedYAMLError):
145
+ # marked YAML error, pull out the useful messages while omitting the noise
146
+ message = ' '.join(filter(None, (exception.context, exception.problem, exception.note)))
147
+ message = message.strip()
148
+ message = f'{message[0].upper()}{message[1:]}'
149
+
150
+ if not message.endswith('.'):
151
+ message += '.'
152
+ else:
153
+ # unexpected error, use the exception message (normally hidden by overriding include_cause_message)
154
+ message = str(exception)
155
+
156
+ message = re.sub(r'\s+', ' ', message).strip()
157
+
158
+ error = cls(message, obj=source_context.origin)
159
+ error._formatted_source_context_value = str(source_context)
160
+ error._help_text = help_text
161
+
162
+ raise error from exception
163
+
164
+
165
+ def _replace_quoted_value(value: str, replacement='.') -> str:
166
+ return re.sub(r"""^\s*('[^']*'|"[^"]*")\s*$""", lambda match: replacement * len(match.group(0)), value)
@@ -0,0 +1,66 @@
1
+ from __future__ import annotations
2
+
3
+ import io as _io
4
+
5
+ from yaml.resolver import Resolver
6
+
7
+ from ansible.module_utils._internal._datatag import AnsibleTagHelper
8
+ from ansible.module_utils.common.yaml import HAS_LIBYAML
9
+ from ansible._internal._datatag import _tags
10
+
11
+ from ._constructor import AnsibleConstructor, AnsibleInstrumentedConstructor
12
+
13
+ if HAS_LIBYAML:
14
+ from yaml.cyaml import CParser
15
+
16
+ class _YamlParser(CParser):
17
+ def __init__(self, stream: str | bytes | _io.IOBase) -> None:
18
+ if isinstance(stream, (str, bytes)):
19
+ stream = AnsibleTagHelper.untag(stream) # PyYAML + libyaml barfs on str/bytes subclasses
20
+
21
+ CParser.__init__(self, stream)
22
+
23
+ self.name = getattr(stream, 'name', None) # provide feature parity with the Python implementation (yaml.reader.Reader provides name)
24
+
25
+ else:
26
+ from yaml.composer import Composer
27
+ from yaml.reader import Reader
28
+ from yaml.scanner import Scanner
29
+ from yaml.parser import Parser
30
+
31
+ class _YamlParser(Reader, Scanner, Parser, Composer): # type: ignore[no-redef]
32
+ def __init__(self, stream: str | bytes | _io.IOBase) -> None:
33
+ Reader.__init__(self, stream)
34
+ Scanner.__init__(self)
35
+ Parser.__init__(self)
36
+ Composer.__init__(self)
37
+
38
+
39
+ class AnsibleInstrumentedLoader(_YamlParser, AnsibleInstrumentedConstructor, Resolver):
40
+ """Ansible YAML loader which supports Ansible custom behavior such as `Origin` tagging, but no Ansible-specific YAML tags."""
41
+
42
+ def __init__(self, stream: str | bytes | _io.IOBase) -> None:
43
+ _YamlParser.__init__(self, stream)
44
+
45
+ AnsibleInstrumentedConstructor.__init__(
46
+ self,
47
+ origin=_tags.Origin.get_or_create_tag(stream, self.name),
48
+ trusted_as_template=_tags.TrustedAsTemplate.is_tagged_on(stream),
49
+ )
50
+
51
+ Resolver.__init__(self)
52
+
53
+
54
+ class AnsibleLoader(_YamlParser, AnsibleConstructor, Resolver):
55
+ """Ansible loader which supports Ansible custom behavior such as `Origin` tagging, as well as Ansible-specific YAML tags."""
56
+
57
+ def __init__(self, stream: str | bytes | _io.IOBase) -> None:
58
+ _YamlParser.__init__(self, stream)
59
+
60
+ AnsibleConstructor.__init__(
61
+ self,
62
+ origin=_tags.Origin.get_or_create_tag(stream, self.name),
63
+ trusted_as_template=_tags.TrustedAsTemplate.is_tagged_on(stream),
64
+ )
65
+
66
+ Resolver.__init__(self)
@@ -0,0 +1,11 @@
1
+ "Protomatter - an unstable substance which every ethical scientist in the galaxy has denounced as dangerously unpredictable."
2
+
3
+ "But it was the only way to solve certain problems..."
4
+
5
+ This Ansible Collection is embedded within ansible-core.
6
+ It contains plugins useful for ansible-core's own integration tests.
7
+ They have been made available, completely unsupported,
8
+ in case they prove useful for debugging and troubleshooting purposes.
9
+
10
+ > CAUTION: This collection is not supported, and may be changed or removed in any version without prior notice.
11
+ Use of these plugins outside ansible-core is highly discouraged.
@@ -0,0 +1,36 @@
1
+ from __future__ import annotations
2
+
3
+ import typing as t
4
+
5
+ from ansible.module_utils.common.validation import _check_type_str_no_conversion, _check_type_list_strict
6
+ from ansible.plugins.action import ActionBase
7
+ from ansible._internal._templating._engine import TemplateEngine
8
+ from ansible._internal._templating._marker_behaviors import ReplacingMarkerBehavior
9
+
10
+
11
+ class ActionModule(ActionBase):
12
+ TRANSFERS_FILES = False
13
+ _requires_connection = False
14
+
15
+ @classmethod
16
+ def finalize_task_arg(cls, name: str, value: t.Any, templar: TemplateEngine, context: t.Any) -> t.Any:
17
+ if name == 'expression':
18
+ return value
19
+
20
+ return super().finalize_task_arg(name, value, templar, context)
21
+
22
+ def run(self, tmp=None, task_vars=None):
23
+ # accepts a list of literal expressions (no templating), evaluates with no failure on undefined, returns all results
24
+ _vr, args = self.validate_argument_spec(
25
+ argument_spec=dict(
26
+ expression=dict(type=_check_type_list_strict, elements=_check_type_str_no_conversion, required=True),
27
+ ),
28
+ )
29
+
30
+ with ReplacingMarkerBehavior.warning_context() as replacing_behavior:
31
+ templar = self._templar._engine.extend(marker_behavior=replacing_behavior)
32
+
33
+ return dict(
34
+ _ansible_verbose_always=True,
35
+ expression_result=[templar.evaluate_expression(expression) for expression in args['expression']],
36
+ )
@@ -0,0 +1,19 @@
1
+ from __future__ import annotations
2
+
3
+ import typing as t
4
+
5
+ from ansible._internal._datatag._tags import TrustedAsTemplate
6
+
7
+
8
+ def apply_trust(value: object) -> object:
9
+ """
10
+ Filter that returns a tagged copy of the input string with TrustedAsTemplate.
11
+ Containers and other non-string values are returned unmodified.
12
+ """
13
+ return TrustedAsTemplate().tag(value) if isinstance(value, str) else value
14
+
15
+
16
+ class FilterModule:
17
+ @staticmethod
18
+ def filters() -> dict[str, t.Callable]:
19
+ return dict(apply_trust=apply_trust)
@@ -0,0 +1,18 @@
1
+ from __future__ import annotations
2
+
3
+ import dataclasses
4
+ import typing as t
5
+
6
+
7
+ def dump_object(value: t.Any) -> object:
8
+ """Internal filter to convert objects not supported by JSON to types which are."""
9
+ if dataclasses.is_dataclass(value):
10
+ return dataclasses.asdict(value) # type: ignore[arg-type]
11
+
12
+ return value
13
+
14
+
15
+ class FilterModule(object):
16
+ @staticmethod
17
+ def filters() -> dict[str, t.Callable]:
18
+ return dict(dump_object=dump_object)
@@ -0,0 +1,16 @@
1
+ from __future__ import annotations
2
+
3
+ import typing as t
4
+
5
+ from ansible._internal._templating._engine import _finalize_template_result, FinalizeMode
6
+
7
+
8
+ def finalize(value: t.Any) -> t.Any:
9
+ """Perform an explicit top-level template finalize operation on the supplied value."""
10
+ return _finalize_template_result(value, mode=FinalizeMode.TOP_LEVEL)
11
+
12
+
13
+ class FilterModule:
14
+ @staticmethod
15
+ def filters() -> dict[str, t.Callable]:
16
+ return dict(finalize=finalize)
@@ -0,0 +1,18 @@
1
+ from __future__ import annotations
2
+
3
+ import typing as t
4
+
5
+ from ansible._internal._datatag._tags import Origin
6
+
7
+
8
+ def origin(value: object) -> str | None:
9
+ """Return the origin of the value, if any, otherwise `None`."""
10
+ origin_tag = Origin.get_tag(value)
11
+
12
+ return str(origin_tag) if origin_tag else None
13
+
14
+
15
+ class FilterModule:
16
+ @staticmethod
17
+ def filters() -> dict[str, t.Callable]:
18
+ return dict(origin=origin)