ansible-core 2.18.7rc1__py3-none-any.whl → 2.19.0__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.

Potentially problematic release.


This version of ansible-core might be problematic. Click here for more details.

Files changed (757) hide show
  1. ansible/_internal/__init__.py +53 -0
  2. ansible/_internal/_ansiballz/__init__.py +0 -0
  3. ansible/_internal/_ansiballz/_builder.py +101 -0
  4. ansible/_internal/_ansiballz/_wrapper.py +262 -0
  5. ansible/_internal/_collection_proxy.py +47 -0
  6. ansible/_internal/_datatag/__init__.py +0 -0
  7. ansible/_internal/_datatag/_tags.py +130 -0
  8. ansible/_internal/_datatag/_utils.py +19 -0
  9. ansible/_internal/_datatag/_wrappers.py +33 -0
  10. ansible/_internal/_errors/__init__.py +0 -0
  11. ansible/_internal/_errors/_alarm_timeout.py +66 -0
  12. ansible/_internal/_errors/_captured.py +123 -0
  13. ansible/_internal/_errors/_error_factory.py +89 -0
  14. ansible/_internal/_errors/_error_utils.py +240 -0
  15. ansible/_internal/_errors/_handler.py +91 -0
  16. ansible/_internal/_errors/_task_timeout.py +28 -0
  17. ansible/_internal/_event_formatting.py +127 -0
  18. ansible/_internal/_json/__init__.py +214 -0
  19. ansible/_internal/_json/_legacy_encoder.py +34 -0
  20. ansible/_internal/_json/_profiles/__init__.py +0 -0
  21. ansible/_internal/_json/_profiles/_cache_persistence.py +57 -0
  22. ansible/_internal/_json/_profiles/_inventory_legacy.py +40 -0
  23. ansible/_internal/_json/_profiles/_legacy.py +189 -0
  24. ansible/_internal/_locking.py +21 -0
  25. ansible/_internal/_plugins/__init__.py +0 -0
  26. ansible/_internal/_plugins/_cache.py +57 -0
  27. ansible/_internal/_ssh/__init__.py +0 -0
  28. ansible/_internal/_ssh/_agent_launch.py +91 -0
  29. ansible/_internal/_ssh/_ssh_agent.py +619 -0
  30. ansible/_internal/_task.py +78 -0
  31. ansible/_internal/_templating/__init__.py +12 -0
  32. ansible/_internal/_templating/_access.py +86 -0
  33. ansible/_internal/_templating/_chain_templar.py +63 -0
  34. ansible/_internal/_templating/_datatag.py +95 -0
  35. ansible/_internal/_templating/_engine.py +592 -0
  36. ansible/_internal/_templating/_errors.py +28 -0
  37. ansible/_internal/_templating/_jinja_bits.py +1106 -0
  38. ansible/_internal/_templating/_jinja_common.py +323 -0
  39. ansible/_internal/_templating/_jinja_patches.py +44 -0
  40. ansible/_internal/_templating/_jinja_plugins.py +375 -0
  41. ansible/_internal/_templating/_lazy_containers.py +633 -0
  42. ansible/_internal/_templating/_marker_behaviors.py +103 -0
  43. ansible/_internal/_templating/_template_vars.py +72 -0
  44. ansible/_internal/_templating/_transform.py +70 -0
  45. ansible/_internal/_templating/_utils.py +108 -0
  46. ansible/_internal/_testing.py +26 -0
  47. ansible/_internal/_wrapt.py +1052 -0
  48. ansible/_internal/_yaml/__init__.py +0 -0
  49. ansible/_internal/_yaml/_constructor.py +240 -0
  50. ansible/_internal/_yaml/_dumper.py +70 -0
  51. ansible/_internal/_yaml/_errors.py +166 -0
  52. ansible/_internal/_yaml/_loader.py +66 -0
  53. ansible/_internal/ansible_collections/ansible/_protomatter/README.md +11 -0
  54. ansible/_internal/ansible_collections/ansible/_protomatter/plugins/action/debug.py +36 -0
  55. ansible/_internal/ansible_collections/ansible/_protomatter/plugins/filter/apply_trust.py +19 -0
  56. ansible/_internal/ansible_collections/ansible/_protomatter/plugins/filter/dump_object.py +27 -0
  57. ansible/_internal/ansible_collections/ansible/_protomatter/plugins/filter/finalize.py +16 -0
  58. ansible/_internal/ansible_collections/ansible/_protomatter/plugins/filter/origin.py +18 -0
  59. ansible/_internal/ansible_collections/ansible/_protomatter/plugins/filter/python_literal_eval.py +24 -0
  60. ansible/_internal/ansible_collections/ansible/_protomatter/plugins/filter/python_literal_eval.yml +33 -0
  61. ansible/_internal/ansible_collections/ansible/_protomatter/plugins/filter/tag_names.py +16 -0
  62. ansible/_internal/ansible_collections/ansible/_protomatter/plugins/filter/true_type.py +17 -0
  63. ansible/_internal/ansible_collections/ansible/_protomatter/plugins/filter/unmask.py +49 -0
  64. ansible/_internal/ansible_collections/ansible/_protomatter/plugins/lookup/config.py +21 -0
  65. ansible/_internal/ansible_collections/ansible/_protomatter/plugins/lookup/config.yml +2 -0
  66. ansible/_internal/ansible_collections/ansible/_protomatter/plugins/test/tagged.py +15 -0
  67. ansible/_internal/ansible_collections/ansible/_protomatter/plugins/test/tagged.yml +19 -0
  68. ansible/_internal/ansible_collections/ansible/_protomatter/plugins/test/tagged_with.py +18 -0
  69. ansible/_internal/ansible_collections/ansible/_protomatter/plugins/test/tagged_with.yml +19 -0
  70. ansible/cli/__init__.py +93 -104
  71. ansible/cli/_ssh_askpass.py +54 -0
  72. ansible/cli/adhoc.py +20 -10
  73. ansible/cli/arguments/option_helpers.py +163 -10
  74. ansible/cli/config.py +43 -68
  75. ansible/cli/console.py +13 -11
  76. ansible/cli/doc.py +134 -77
  77. ansible/cli/galaxy.py +27 -20
  78. ansible/cli/inventory.py +28 -28
  79. ansible/cli/playbook.py +4 -12
  80. ansible/cli/pull.py +6 -3
  81. ansible/cli/scripts/ansible_connection_cli_stub.py +7 -7
  82. ansible/cli/vault.py +12 -11
  83. ansible/compat/__init__.py +2 -2
  84. ansible/compat/importlib_resources.py +9 -12
  85. ansible/config/base.yml +218 -133
  86. ansible/config/manager.py +220 -159
  87. ansible/constants.py +2 -65
  88. ansible/errors/__init__.py +350 -256
  89. ansible/executor/interpreter_discovery.py +28 -149
  90. ansible/executor/module_common.py +480 -514
  91. ansible/executor/play_iterator.py +22 -27
  92. ansible/executor/playbook_executor.py +11 -11
  93. ansible/executor/powershell/async_watchdog.ps1 +97 -102
  94. ansible/executor/powershell/async_wrapper.ps1 +204 -153
  95. ansible/executor/powershell/become_wrapper.ps1 +107 -144
  96. ansible/executor/powershell/bootstrap_wrapper.ps1 +46 -9
  97. ansible/executor/powershell/coverage_wrapper.ps1 +91 -135
  98. ansible/executor/powershell/exec_wrapper.ps1 +675 -196
  99. ansible/executor/powershell/module_manifest.py +469 -265
  100. ansible/executor/powershell/module_wrapper.ps1 +195 -186
  101. ansible/executor/powershell/powershell_expand_user.ps1 +20 -0
  102. ansible/executor/powershell/powershell_mkdtemp.ps1 +17 -0
  103. ansible/executor/powershell/psrp_fetch_file.ps1 +41 -0
  104. ansible/executor/powershell/psrp_put_file.ps1 +122 -0
  105. ansible/executor/powershell/winrm_fetch_file.ps1 +46 -0
  106. ansible/executor/powershell/winrm_put_file.ps1 +36 -0
  107. ansible/executor/process/worker.py +139 -149
  108. ansible/executor/stats.py +5 -5
  109. ansible/executor/task_executor.py +270 -297
  110. ansible/executor/task_queue_manager.py +135 -137
  111. ansible/executor/task_result.py +182 -79
  112. ansible/galaxy/__init__.py +2 -2
  113. ansible/galaxy/api.py +26 -25
  114. ansible/galaxy/collection/__init__.py +6 -14
  115. ansible/galaxy/collection/concrete_artifact_manager.py +12 -21
  116. ansible/galaxy/dependency_resolution/dataclasses.py +14 -4
  117. ansible/galaxy/dependency_resolution/providers.py +4 -4
  118. ansible/galaxy/dependency_resolution/reporters.py +81 -0
  119. ansible/galaxy/role.py +6 -10
  120. ansible/galaxy/token.py +28 -21
  121. ansible/inventory/data.py +47 -57
  122. ansible/inventory/group.py +50 -73
  123. ansible/inventory/helpers.py +9 -0
  124. ansible/inventory/host.py +37 -54
  125. ansible/inventory/manager.py +79 -34
  126. ansible/keyword_desc.yml +1 -1
  127. ansible/module_utils/_internal/__init__.py +55 -0
  128. ansible/module_utils/_internal/_ambient_context.py +58 -0
  129. ansible/module_utils/_internal/_ansiballz/__init__.py +0 -0
  130. ansible/module_utils/_internal/_ansiballz/_extensions/__init__.py +0 -0
  131. ansible/module_utils/_internal/_ansiballz/_extensions/_coverage.py +45 -0
  132. ansible/module_utils/_internal/_ansiballz/_extensions/_pydevd.py +62 -0
  133. ansible/module_utils/_internal/_ansiballz/_loader.py +81 -0
  134. ansible/module_utils/_internal/_ansiballz/_respawn.py +32 -0
  135. ansible/module_utils/_internal/_ansiballz/_respawn_wrapper.py +23 -0
  136. ansible/module_utils/_internal/_concurrent/_daemon_threading.py +1 -0
  137. ansible/module_utils/_internal/_dataclass_validation.py +217 -0
  138. ansible/module_utils/_internal/_datatag/__init__.py +961 -0
  139. ansible/module_utils/_internal/_datatag/_tags.py +16 -0
  140. ansible/module_utils/_internal/_debugging.py +31 -0
  141. ansible/module_utils/_internal/_deprecator.py +157 -0
  142. ansible/module_utils/_internal/_errors.py +101 -0
  143. ansible/module_utils/_internal/_event_utils.py +61 -0
  144. ansible/module_utils/_internal/_json/__init__.py +63 -0
  145. ansible/module_utils/_internal/_json/_legacy_encoder.py +26 -0
  146. ansible/module_utils/_internal/_json/_profiles/__init__.py +428 -0
  147. ansible/module_utils/_internal/_json/_profiles/_fallback_to_str.py +73 -0
  148. ansible/module_utils/_internal/_json/_profiles/_module_legacy_c2m.py +33 -0
  149. ansible/module_utils/_internal/_json/_profiles/_module_legacy_m2c.py +37 -0
  150. ansible/module_utils/_internal/_json/_profiles/_module_modern_c2m.py +35 -0
  151. ansible/module_utils/_internal/_json/_profiles/_module_modern_m2c.py +33 -0
  152. ansible/module_utils/_internal/_json/_profiles/_tagless.py +52 -0
  153. ansible/module_utils/_internal/_messages.py +130 -0
  154. ansible/module_utils/_internal/_patches/__init__.py +66 -0
  155. ansible/module_utils/_internal/_patches/_dataclass_annotation_patch.py +53 -0
  156. ansible/module_utils/_internal/_patches/_socket_patch.py +34 -0
  157. ansible/module_utils/_internal/_patches/_sys_intern_patch.py +34 -0
  158. ansible/module_utils/_internal/_plugin_info.py +38 -0
  159. ansible/module_utils/_internal/_stack.py +22 -0
  160. ansible/module_utils/_internal/_testing.py +0 -0
  161. ansible/module_utils/_internal/_text_utils.py +6 -0
  162. ansible/module_utils/_internal/_traceback.py +92 -0
  163. ansible/module_utils/_internal/_validation.py +14 -0
  164. ansible/module_utils/ansible_release.py +2 -2
  165. ansible/module_utils/api.py +1 -2
  166. ansible/module_utils/basic.py +303 -202
  167. ansible/module_utils/common/_utils.py +24 -28
  168. ansible/module_utils/common/arg_spec.py +8 -3
  169. ansible/module_utils/common/collections.py +7 -2
  170. ansible/module_utils/common/dict_transformations.py +2 -2
  171. ansible/module_utils/common/file.py +2 -2
  172. ansible/module_utils/common/json.py +90 -84
  173. ansible/module_utils/common/locale.py +2 -2
  174. ansible/module_utils/common/parameters.py +27 -24
  175. ansible/module_utils/common/process.py +2 -3
  176. ansible/module_utils/common/respawn.py +11 -33
  177. ansible/module_utils/common/sentinel.py +66 -0
  178. ansible/module_utils/common/sys_info.py +8 -8
  179. ansible/module_utils/common/text/converters.py +16 -37
  180. ansible/module_utils/common/validation.py +35 -24
  181. ansible/module_utils/common/warnings.py +143 -25
  182. ansible/module_utils/common/yaml.py +29 -3
  183. ansible/module_utils/compat/datetime.py +33 -21
  184. ansible/module_utils/compat/paramiko.py +21 -10
  185. ansible/module_utils/compat/typing.py +6 -5
  186. ansible/module_utils/connection.py +10 -13
  187. ansible/module_utils/csharp/Ansible.Basic.cs +15 -12
  188. ansible/module_utils/csharp/Ansible.Become.cs +1 -0
  189. ansible/module_utils/csharp/Ansible.Privilege.cs +2 -2
  190. ansible/module_utils/csharp/Ansible._Async.cs +517 -0
  191. ansible/module_utils/datatag.py +49 -0
  192. ansible/module_utils/distro/__init__.py +2 -2
  193. ansible/module_utils/facts/ansible_collector.py +4 -5
  194. ansible/module_utils/facts/collector.py +13 -14
  195. ansible/module_utils/facts/compat.py +4 -4
  196. ansible/module_utils/facts/default_collectors.py +1 -1
  197. ansible/module_utils/facts/hardware/aix.py +34 -0
  198. ansible/module_utils/facts/hardware/base.py +2 -2
  199. ansible/module_utils/facts/hardware/darwin.py +1 -3
  200. ansible/module_utils/facts/hardware/freebsd.py +2 -2
  201. ansible/module_utils/facts/hardware/linux.py +5 -5
  202. ansible/module_utils/facts/namespace.py +1 -1
  203. ansible/module_utils/facts/network/base.py +1 -1
  204. ansible/module_utils/facts/network/fc_wwn.py +1 -2
  205. ansible/module_utils/facts/network/iscsi.py +1 -2
  206. ansible/module_utils/facts/network/nvme.py +1 -2
  207. ansible/module_utils/facts/other/facter.py +2 -3
  208. ansible/module_utils/facts/other/ohai.py +2 -3
  209. ansible/module_utils/facts/sysctl.py +4 -6
  210. ansible/module_utils/facts/system/apparmor.py +1 -2
  211. ansible/module_utils/facts/system/caps.py +3 -3
  212. ansible/module_utils/facts/system/chroot.py +1 -2
  213. ansible/module_utils/facts/system/cmdline.py +1 -2
  214. ansible/module_utils/facts/system/date_time.py +5 -3
  215. ansible/module_utils/facts/system/distribution.py +27 -13
  216. ansible/module_utils/facts/system/dns.py +1 -1
  217. ansible/module_utils/facts/system/env.py +1 -2
  218. ansible/module_utils/facts/system/fips.py +7 -20
  219. ansible/module_utils/facts/system/loadavg.py +1 -2
  220. ansible/module_utils/facts/system/local.py +2 -3
  221. ansible/module_utils/facts/system/lsb.py +1 -2
  222. ansible/module_utils/facts/system/pkg_mgr.py +1 -2
  223. ansible/module_utils/facts/system/platform.py +1 -2
  224. ansible/module_utils/facts/system/python.py +1 -2
  225. ansible/module_utils/facts/system/selinux.py +1 -1
  226. ansible/module_utils/facts/system/service_mgr.py +1 -2
  227. ansible/module_utils/facts/system/ssh_pub_keys.py +1 -1
  228. ansible/module_utils/facts/system/systemd.py +1 -1
  229. ansible/module_utils/facts/system/user.py +1 -2
  230. ansible/module_utils/facts/utils.py +3 -3
  231. ansible/module_utils/facts/virtual/base.py +1 -1
  232. ansible/module_utils/facts/virtual/linux.py +3 -3
  233. ansible/module_utils/facts/virtual/sunos.py +3 -15
  234. ansible/module_utils/facts/virtual/sysctl.py +3 -16
  235. ansible/module_utils/json_utils.py +2 -2
  236. ansible/module_utils/parsing/convert_bool.py +7 -1
  237. ansible/module_utils/powershell/Ansible.ModuleUtils.AddType.psm1 +1 -1
  238. ansible/module_utils/powershell/Ansible.ModuleUtils.CamelConversion.psm1 +1 -1
  239. ansible/module_utils/powershell/Ansible.ModuleUtils.CommandUtil.psm1 +1 -1
  240. ansible/module_utils/powershell/Ansible.ModuleUtils.WebRequest.psm1 +1 -1
  241. ansible/module_utils/service.py +21 -31
  242. ansible/module_utils/splitter.py +7 -7
  243. ansible/module_utils/testing.py +31 -0
  244. ansible/module_utils/urls.py +64 -35
  245. ansible/modules/add_host.py +4 -4
  246. ansible/modules/apt.py +69 -49
  247. ansible/modules/apt_key.py +19 -12
  248. ansible/modules/apt_repository.py +32 -51
  249. ansible/modules/assemble.py +16 -14
  250. ansible/modules/assert.py +4 -4
  251. ansible/modules/async_status.py +24 -24
  252. ansible/modules/async_wrapper.py +20 -25
  253. ansible/modules/blockinfile.py +6 -7
  254. ansible/modules/command.py +13 -20
  255. ansible/modules/copy.py +60 -147
  256. ansible/modules/cron.py +24 -21
  257. ansible/modules/deb822_repository.py +8 -9
  258. ansible/modules/debconf.py +5 -5
  259. ansible/modules/debug.py +4 -4
  260. ansible/modules/dnf.py +8 -8
  261. ansible/modules/dnf5.py +39 -13
  262. ansible/modules/dpkg_selections.py +4 -4
  263. ansible/modules/expect.py +13 -15
  264. ansible/modules/fail.py +4 -4
  265. ansible/modules/fetch.py +4 -4
  266. ansible/modules/file.py +184 -144
  267. ansible/modules/find.py +22 -20
  268. ansible/modules/gather_facts.py +3 -3
  269. ansible/modules/get_url.py +77 -54
  270. ansible/modules/getent.py +7 -9
  271. ansible/modules/git.py +38 -38
  272. ansible/modules/group.py +6 -6
  273. ansible/modules/group_by.py +4 -4
  274. ansible/modules/hostname.py +15 -32
  275. ansible/modules/import_playbook.py +6 -6
  276. ansible/modules/import_role.py +6 -6
  277. ansible/modules/import_tasks.py +6 -6
  278. ansible/modules/include_role.py +6 -6
  279. ansible/modules/include_tasks.py +6 -6
  280. ansible/modules/include_vars.py +6 -6
  281. ansible/modules/iptables.py +86 -73
  282. ansible/modules/known_hosts.py +22 -24
  283. ansible/modules/lineinfile.py +5 -5
  284. ansible/modules/meta.py +4 -4
  285. ansible/modules/mount_facts.py +2 -2
  286. ansible/modules/package.py +10 -4
  287. ansible/modules/package_facts.py +22 -10
  288. ansible/modules/pause.py +6 -6
  289. ansible/modules/ping.py +6 -6
  290. ansible/modules/pip.py +21 -26
  291. ansible/modules/raw.py +6 -6
  292. ansible/modules/reboot.py +6 -6
  293. ansible/modules/replace.py +10 -14
  294. ansible/modules/rpm_key.py +7 -8
  295. ansible/modules/script.py +4 -4
  296. ansible/modules/service.py +10 -17
  297. ansible/modules/service_facts.py +87 -10
  298. ansible/modules/set_fact.py +5 -5
  299. ansible/modules/set_stats.py +4 -4
  300. ansible/modules/setup.py +2 -2
  301. ansible/modules/shell.py +6 -6
  302. ansible/modules/slurp.py +16 -19
  303. ansible/modules/stat.py +15 -31
  304. ansible/modules/subversion.py +15 -15
  305. ansible/modules/systemd.py +7 -7
  306. ansible/modules/systemd_service.py +7 -7
  307. ansible/modules/sysvinit.py +9 -9
  308. ansible/modules/tempfile.py +5 -6
  309. ansible/modules/template.py +6 -6
  310. ansible/modules/unarchive.py +38 -17
  311. ansible/modules/uri.py +33 -26
  312. ansible/modules/user.py +45 -32
  313. ansible/modules/validate_argument_spec.py +10 -7
  314. ansible/modules/wait_for.py +70 -60
  315. ansible/modules/wait_for_connection.py +6 -6
  316. ansible/modules/yum_repository.py +10 -9
  317. ansible/parsing/ajson.py +17 -37
  318. ansible/parsing/dataloader.py +99 -54
  319. ansible/parsing/mod_args.py +62 -60
  320. ansible/parsing/plugin_docs.py +21 -86
  321. ansible/parsing/quoting.py +1 -1
  322. ansible/parsing/splitter.py +27 -12
  323. ansible/parsing/utils/addresses.py +24 -24
  324. ansible/parsing/utils/jsonify.py +5 -1
  325. ansible/parsing/utils/yaml.py +32 -61
  326. ansible/parsing/vault/__init__.py +327 -99
  327. ansible/parsing/yaml/__init__.py +0 -18
  328. ansible/parsing/yaml/dumper.py +6 -120
  329. ansible/parsing/yaml/loader.py +6 -39
  330. ansible/parsing/yaml/objects.py +43 -335
  331. ansible/playbook/__init__.py +1 -1
  332. ansible/playbook/attribute.py +8 -3
  333. ansible/playbook/base.py +187 -134
  334. ansible/playbook/block.py +26 -24
  335. ansible/playbook/collectionsearch.py +1 -15
  336. ansible/playbook/conditional.py +3 -77
  337. ansible/playbook/handler.py +8 -2
  338. ansible/playbook/helpers.py +41 -53
  339. ansible/playbook/included_file.py +32 -26
  340. ansible/playbook/loop_control.py +2 -2
  341. ansible/playbook/play.py +85 -44
  342. ansible/playbook/play_context.py +14 -17
  343. ansible/playbook/playbook_include.py +27 -62
  344. ansible/playbook/role/__init__.py +64 -49
  345. ansible/playbook/role/definition.py +15 -17
  346. ansible/playbook/role/include.py +2 -4
  347. ansible/playbook/role/metadata.py +10 -11
  348. ansible/playbook/role_include.py +3 -3
  349. ansible/playbook/taggable.py +28 -12
  350. ansible/playbook/task.py +192 -121
  351. ansible/playbook/task_include.py +5 -5
  352. ansible/plugins/__init__.py +58 -26
  353. ansible/plugins/action/__init__.py +188 -186
  354. ansible/plugins/action/add_host.py +2 -2
  355. ansible/plugins/action/assemble.py +11 -18
  356. ansible/plugins/action/assert.py +55 -67
  357. ansible/plugins/action/async_status.py +7 -2
  358. ansible/plugins/action/copy.py +14 -17
  359. ansible/plugins/action/debug.py +37 -31
  360. ansible/plugins/action/dnf.py +3 -4
  361. ansible/plugins/action/fail.py +1 -1
  362. ansible/plugins/action/fetch.py +7 -8
  363. ansible/plugins/action/gather_facts.py +13 -14
  364. ansible/plugins/action/group_by.py +1 -1
  365. ansible/plugins/action/include_vars.py +10 -11
  366. ansible/plugins/action/package.py +8 -14
  367. ansible/plugins/action/pause.py +2 -2
  368. ansible/plugins/action/script.py +27 -38
  369. ansible/plugins/action/service.py +9 -18
  370. ansible/plugins/action/set_fact.py +3 -12
  371. ansible/plugins/action/set_stats.py +3 -8
  372. ansible/plugins/action/template.py +47 -67
  373. ansible/plugins/action/unarchive.py +6 -16
  374. ansible/plugins/action/uri.py +9 -20
  375. ansible/plugins/action/validate_argument_spec.py +5 -5
  376. ansible/plugins/action/wait_for_connection.py +1 -1
  377. ansible/plugins/become/__init__.py +31 -8
  378. ansible/plugins/become/runas.py +71 -0
  379. ansible/plugins/become/su.py +13 -8
  380. ansible/plugins/become/sudo.py +19 -0
  381. ansible/plugins/cache/__init__.py +52 -63
  382. ansible/plugins/cache/base.py +8 -0
  383. ansible/plugins/cache/jsonfile.py +10 -16
  384. ansible/plugins/cache/memory.py +6 -12
  385. ansible/plugins/callback/__init__.py +294 -201
  386. ansible/plugins/callback/default.py +99 -95
  387. ansible/plugins/callback/junit.py +44 -43
  388. ansible/plugins/callback/minimal.py +28 -25
  389. ansible/plugins/callback/oneline.py +34 -21
  390. ansible/plugins/callback/tree.py +27 -16
  391. ansible/plugins/connection/__init__.py +47 -34
  392. ansible/plugins/connection/local.py +156 -60
  393. ansible/plugins/connection/paramiko_ssh.py +34 -24
  394. ansible/plugins/connection/psrp.py +76 -165
  395. ansible/plugins/connection/ssh.py +326 -86
  396. ansible/plugins/connection/winrm.py +62 -141
  397. ansible/plugins/doc_fragments/action_common_attributes.py +14 -14
  398. ansible/plugins/doc_fragments/action_core.py +6 -6
  399. ansible/plugins/doc_fragments/backup.py +2 -2
  400. ansible/plugins/doc_fragments/checksum_common.py +27 -0
  401. ansible/plugins/doc_fragments/constructed.py +8 -4
  402. ansible/plugins/doc_fragments/decrypt.py +2 -2
  403. ansible/plugins/doc_fragments/default_callback.py +2 -2
  404. ansible/plugins/doc_fragments/files.py +2 -2
  405. ansible/plugins/doc_fragments/inventory_cache.py +2 -2
  406. ansible/plugins/doc_fragments/result_format_callback.py +2 -2
  407. ansible/plugins/doc_fragments/return_common.py +2 -2
  408. ansible/plugins/doc_fragments/template_common.py +4 -4
  409. ansible/plugins/doc_fragments/url.py +17 -1
  410. ansible/plugins/doc_fragments/url_windows.py +2 -2
  411. ansible/plugins/doc_fragments/validate.py +2 -2
  412. ansible/plugins/doc_fragments/vars_plugin_staging.py +2 -2
  413. ansible/plugins/filter/__init__.py +6 -2
  414. ansible/plugins/filter/b64decode.yml +22 -0
  415. ansible/plugins/filter/b64encode.yml +22 -0
  416. ansible/plugins/filter/bool.yml +11 -4
  417. ansible/plugins/filter/core.py +245 -120
  418. ansible/plugins/filter/encryption.py +42 -34
  419. ansible/plugins/filter/flatten.yml +3 -2
  420. ansible/plugins/filter/human_to_bytes.yml +1 -1
  421. ansible/plugins/filter/mathstuff.py +30 -37
  422. ansible/plugins/filter/password_hash.yml +8 -0
  423. ansible/plugins/filter/pow.yml +1 -1
  424. ansible/plugins/filter/regex_search.yml +1 -4
  425. ansible/plugins/filter/root.yml +1 -1
  426. ansible/plugins/filter/split.yml +1 -1
  427. ansible/plugins/filter/strftime.yml +3 -3
  428. ansible/plugins/filter/to_nice_yaml.yml +0 -4
  429. ansible/plugins/filter/to_uuid.yml +1 -1
  430. ansible/plugins/filter/to_yaml.yml +0 -4
  431. ansible/plugins/filter/unvault.yml +1 -1
  432. ansible/plugins/filter/urls.py +1 -1
  433. ansible/plugins/filter/urlsplit.py +8 -9
  434. ansible/plugins/filter/vault.yml +14 -9
  435. ansible/plugins/filter/win_basename.yml +6 -1
  436. ansible/plugins/filter/win_dirname.yml +5 -0
  437. ansible/plugins/inventory/__init__.py +107 -86
  438. ansible/plugins/inventory/advanced_host_list.py +7 -5
  439. ansible/plugins/inventory/auto.py +11 -4
  440. ansible/plugins/inventory/constructed.py +21 -24
  441. ansible/plugins/inventory/generator.py +16 -11
  442. ansible/plugins/inventory/host_list.py +7 -5
  443. ansible/plugins/inventory/ini.py +78 -44
  444. ansible/plugins/inventory/script.py +190 -120
  445. ansible/plugins/inventory/toml.py +16 -126
  446. ansible/plugins/inventory/yaml.py +10 -8
  447. ansible/plugins/list.py +72 -19
  448. ansible/plugins/loader.py +383 -198
  449. ansible/plugins/lookup/__init__.py +21 -4
  450. ansible/plugins/lookup/config.py +21 -35
  451. ansible/plugins/lookup/csvfile.py +19 -73
  452. ansible/plugins/lookup/dict.py +1 -6
  453. ansible/plugins/lookup/env.py +12 -9
  454. ansible/plugins/lookup/file.py +5 -8
  455. ansible/plugins/lookup/first_found.py +87 -55
  456. ansible/plugins/lookup/indexed_items.py +1 -10
  457. ansible/plugins/lookup/ini.py +14 -13
  458. ansible/plugins/lookup/items.py +1 -1
  459. ansible/plugins/lookup/lines.py +8 -1
  460. ansible/plugins/lookup/list.py +1 -1
  461. ansible/plugins/lookup/nested.py +2 -18
  462. ansible/plugins/lookup/password.py +5 -5
  463. ansible/plugins/lookup/pipe.py +5 -7
  464. ansible/plugins/lookup/sequence.py +18 -8
  465. ansible/plugins/lookup/subelements.py +1 -4
  466. ansible/plugins/lookup/template.py +47 -36
  467. ansible/plugins/lookup/together.py +0 -12
  468. ansible/plugins/lookup/unvault.py +1 -5
  469. ansible/plugins/lookup/url.py +4 -10
  470. ansible/plugins/lookup/vars.py +16 -24
  471. ansible/plugins/shell/__init__.py +58 -4
  472. ansible/plugins/shell/cmd.py +2 -2
  473. ansible/plugins/shell/powershell.py +106 -31
  474. ansible/plugins/shell/sh.py +13 -7
  475. ansible/plugins/strategy/__init__.py +168 -193
  476. ansible/plugins/strategy/debug.py +2 -2
  477. ansible/plugins/strategy/free.py +16 -31
  478. ansible/plugins/strategy/host_pinned.py +2 -2
  479. ansible/plugins/strategy/linear.py +41 -41
  480. ansible/plugins/terminal/__init__.py +4 -4
  481. ansible/plugins/test/__init__.py +7 -2
  482. ansible/plugins/test/core.py +75 -35
  483. ansible/plugins/test/files.py +1 -1
  484. ansible/plugins/test/finished.yml +1 -1
  485. ansible/plugins/test/mathstuff.py +3 -3
  486. ansible/plugins/test/uri.py +5 -8
  487. ansible/plugins/vars/host_group_vars.py +7 -14
  488. ansible/release.py +2 -2
  489. ansible/template/__init__.py +353 -943
  490. ansible/utils/__init__.py +0 -18
  491. ansible/utils/collection_loader/__init__.py +54 -5
  492. ansible/utils/collection_loader/_collection_config.py +5 -6
  493. ansible/utils/collection_loader/_collection_finder.py +82 -96
  494. ansible/utils/collection_loader/_collection_meta.py +15 -8
  495. ansible/utils/display.py +485 -73
  496. ansible/utils/encrypt.py +27 -19
  497. ansible/utils/fqcn.py +2 -2
  498. ansible/utils/galaxy.py +2 -2
  499. ansible/utils/hashing.py +8 -10
  500. ansible/utils/helpers.py +2 -2
  501. ansible/utils/listify.py +10 -8
  502. ansible/utils/lock.py +2 -2
  503. ansible/utils/path.py +10 -12
  504. ansible/utils/plugin_docs.py +16 -14
  505. ansible/utils/py3compat.py +2 -7
  506. ansible/utils/sentinel.py +4 -62
  507. ansible/utils/singleton.py +2 -0
  508. ansible/utils/ssh_functions.py +6 -2
  509. ansible/utils/unsafe_proxy.py +23 -332
  510. ansible/utils/vars.py +55 -8
  511. ansible/utils/version.py +2 -2
  512. ansible/vars/clean.py +5 -5
  513. ansible/vars/hostvars.py +60 -90
  514. ansible/vars/manager.py +220 -285
  515. ansible/vars/plugins.py +4 -4
  516. ansible/vars/reserved.py +13 -12
  517. {ansible_core-2.18.7rc1.dist-info → ansible_core-2.19.0.dist-info}/METADATA +4 -3
  518. ansible_core-2.19.0.dist-info/RECORD +1097 -0
  519. ansible_core-2.19.0.dist-info/licenses/licenses/BSD-3-Clause.txt +28 -0
  520. ansible_test/_data/completion/docker.txt +7 -7
  521. ansible_test/_data/completion/remote.txt +6 -6
  522. ansible_test/_data/completion/windows.txt +1 -0
  523. ansible_test/_data/requirements/ansible.txt +2 -2
  524. ansible_test/_data/requirements/sanity.ansible-doc.txt +3 -3
  525. ansible_test/_data/requirements/sanity.changelog.txt +2 -2
  526. ansible_test/_data/requirements/sanity.import.plugin.txt +2 -2
  527. ansible_test/_data/requirements/sanity.pep8.txt +1 -1
  528. ansible_test/_data/requirements/sanity.pylint.txt +5 -5
  529. ansible_test/_data/requirements/sanity.validate-modules.txt +2 -2
  530. ansible_test/_data/requirements/sanity.yamllint.txt +1 -1
  531. ansible_test/_data/requirements/units.txt +1 -0
  532. ansible_test/_internal/__init__.py +6 -0
  533. ansible_test/_internal/ansible_util.py +3 -1
  534. ansible_test/_internal/become.py +1 -0
  535. ansible_test/_internal/bootstrap.py +1 -0
  536. ansible_test/_internal/cache.py +1 -0
  537. ansible_test/_internal/cgroup.py +1 -0
  538. ansible_test/_internal/ci/__init__.py +1 -0
  539. ansible_test/_internal/ci/azp.py +1 -0
  540. ansible_test/_internal/ci/local.py +1 -0
  541. ansible_test/_internal/classification/__init__.py +1 -0
  542. ansible_test/_internal/classification/common.py +1 -0
  543. ansible_test/_internal/classification/csharp.py +1 -0
  544. ansible_test/_internal/classification/powershell.py +1 -0
  545. ansible_test/_internal/classification/python.py +1 -0
  546. ansible_test/_internal/cli/__init__.py +1 -0
  547. ansible_test/_internal/cli/actions.py +1 -0
  548. ansible_test/_internal/cli/argparsing/__init__.py +1 -0
  549. ansible_test/_internal/cli/argparsing/actions.py +1 -0
  550. ansible_test/_internal/cli/argparsing/argcompletion.py +1 -0
  551. ansible_test/_internal/cli/argparsing/parsers.py +1 -0
  552. ansible_test/_internal/cli/commands/__init__.py +11 -5
  553. ansible_test/_internal/cli/commands/coverage/__init__.py +1 -0
  554. ansible_test/_internal/cli/commands/coverage/analyze/__init__.py +1 -0
  555. ansible_test/_internal/cli/commands/coverage/analyze/targets/__init__.py +1 -0
  556. ansible_test/_internal/cli/commands/coverage/analyze/targets/combine.py +1 -0
  557. ansible_test/_internal/cli/commands/coverage/analyze/targets/expand.py +1 -0
  558. ansible_test/_internal/cli/commands/coverage/analyze/targets/filter.py +1 -0
  559. ansible_test/_internal/cli/commands/coverage/analyze/targets/generate.py +1 -0
  560. ansible_test/_internal/cli/commands/coverage/analyze/targets/missing.py +1 -0
  561. ansible_test/_internal/cli/commands/coverage/combine.py +1 -0
  562. ansible_test/_internal/cli/commands/coverage/erase.py +1 -0
  563. ansible_test/_internal/cli/commands/coverage/html.py +1 -0
  564. ansible_test/_internal/cli/commands/coverage/report.py +1 -0
  565. ansible_test/_internal/cli/commands/coverage/xml.py +1 -0
  566. ansible_test/_internal/cli/commands/env.py +1 -0
  567. ansible_test/_internal/cli/commands/integration/__init__.py +1 -0
  568. ansible_test/_internal/cli/commands/integration/network.py +1 -0
  569. ansible_test/_internal/cli/commands/integration/posix.py +1 -0
  570. ansible_test/_internal/cli/commands/integration/windows.py +1 -0
  571. ansible_test/_internal/cli/commands/sanity.py +9 -0
  572. ansible_test/_internal/cli/commands/shell.py +1 -0
  573. ansible_test/_internal/cli/commands/units.py +1 -0
  574. ansible_test/_internal/cli/compat.py +1 -0
  575. ansible_test/_internal/cli/completers.py +1 -0
  576. ansible_test/_internal/cli/converters.py +1 -0
  577. ansible_test/_internal/cli/environments.py +52 -5
  578. ansible_test/_internal/cli/epilog.py +1 -0
  579. ansible_test/_internal/cli/parsers/__init__.py +1 -0
  580. ansible_test/_internal/cli/parsers/base_argument_parsers.py +1 -0
  581. ansible_test/_internal/cli/parsers/helpers.py +1 -0
  582. ansible_test/_internal/cli/parsers/host_config_parsers.py +1 -0
  583. ansible_test/_internal/cli/parsers/key_value_parsers.py +1 -0
  584. ansible_test/_internal/cli/parsers/value_parsers.py +1 -0
  585. ansible_test/_internal/commands/__init__.py +1 -0
  586. ansible_test/_internal/commands/coverage/__init__.py +3 -2
  587. ansible_test/_internal/commands/coverage/analyze/__init__.py +1 -0
  588. ansible_test/_internal/commands/coverage/analyze/targets/__init__.py +1 -0
  589. ansible_test/_internal/commands/coverage/analyze/targets/combine.py +1 -0
  590. ansible_test/_internal/commands/coverage/analyze/targets/expand.py +1 -0
  591. ansible_test/_internal/commands/coverage/analyze/targets/filter.py +1 -0
  592. ansible_test/_internal/commands/coverage/analyze/targets/generate.py +1 -0
  593. ansible_test/_internal/commands/coverage/analyze/targets/missing.py +1 -0
  594. ansible_test/_internal/commands/coverage/combine.py +2 -1
  595. ansible_test/_internal/commands/coverage/erase.py +1 -0
  596. ansible_test/_internal/commands/coverage/html.py +1 -0
  597. ansible_test/_internal/commands/coverage/report.py +1 -0
  598. ansible_test/_internal/commands/coverage/xml.py +1 -0
  599. ansible_test/_internal/commands/env/__init__.py +2 -0
  600. ansible_test/_internal/commands/integration/__init__.py +22 -5
  601. ansible_test/_internal/commands/integration/cloud/__init__.py +1 -0
  602. ansible_test/_internal/commands/integration/cloud/acme.py +2 -1
  603. ansible_test/_internal/commands/integration/cloud/aws.py +1 -0
  604. ansible_test/_internal/commands/integration/cloud/azure.py +1 -0
  605. ansible_test/_internal/commands/integration/cloud/cs.py +1 -0
  606. ansible_test/_internal/commands/integration/cloud/digitalocean.py +1 -0
  607. ansible_test/_internal/commands/integration/cloud/galaxy.py +3 -2
  608. ansible_test/_internal/commands/integration/cloud/hcloud.py +1 -0
  609. ansible_test/_internal/commands/integration/cloud/httptester.py +3 -2
  610. ansible_test/_internal/commands/integration/cloud/nios.py +2 -1
  611. ansible_test/_internal/commands/integration/cloud/opennebula.py +1 -0
  612. ansible_test/_internal/commands/integration/cloud/openshift.py +1 -0
  613. ansible_test/_internal/commands/integration/cloud/scaleway.py +1 -0
  614. ansible_test/_internal/commands/integration/cloud/vcenter.py +1 -0
  615. ansible_test/_internal/commands/integration/cloud/vultr.py +1 -0
  616. ansible_test/_internal/commands/integration/coverage.py +8 -2
  617. ansible_test/_internal/commands/integration/filters.py +1 -0
  618. ansible_test/_internal/commands/integration/network.py +1 -0
  619. ansible_test/_internal/commands/integration/posix.py +1 -0
  620. ansible_test/_internal/commands/integration/windows.py +1 -0
  621. ansible_test/_internal/commands/sanity/__init__.py +19 -2
  622. ansible_test/_internal/commands/sanity/ansible_doc.py +1 -0
  623. ansible_test/_internal/commands/sanity/bin_symlinks.py +1 -0
  624. ansible_test/_internal/commands/sanity/compile.py +1 -0
  625. ansible_test/_internal/commands/sanity/ignores.py +1 -0
  626. ansible_test/_internal/commands/sanity/import.py +1 -0
  627. ansible_test/_internal/commands/sanity/integration_aliases.py +12 -0
  628. ansible_test/_internal/commands/sanity/pep8.py +1 -0
  629. ansible_test/_internal/commands/sanity/pslint.py +1 -0
  630. ansible_test/_internal/commands/sanity/pylint.py +25 -26
  631. ansible_test/_internal/commands/sanity/shellcheck.py +1 -0
  632. ansible_test/_internal/commands/sanity/validate_modules.py +1 -0
  633. ansible_test/_internal/commands/sanity/yamllint.py +1 -0
  634. ansible_test/_internal/commands/shell/__init__.py +44 -4
  635. ansible_test/_internal/commands/units/__init__.py +5 -1
  636. ansible_test/_internal/compat/__init__.py +1 -0
  637. ansible_test/_internal/compat/packaging.py +1 -0
  638. ansible_test/_internal/compat/yaml.py +1 -0
  639. ansible_test/_internal/completion.py +1 -0
  640. ansible_test/_internal/config.py +23 -13
  641. ansible_test/_internal/connections.py +1 -0
  642. ansible_test/_internal/constants.py +1 -0
  643. ansible_test/_internal/containers.py +1 -0
  644. ansible_test/_internal/content_config.py +1 -0
  645. ansible_test/_internal/core_ci.py +1 -0
  646. ansible_test/_internal/coverage_util.py +11 -10
  647. ansible_test/_internal/data.py +1 -0
  648. ansible_test/_internal/debugging.py +166 -0
  649. ansible_test/_internal/delegation.py +22 -13
  650. ansible_test/_internal/dev/__init__.py +1 -0
  651. ansible_test/_internal/dev/container_probe.py +1 -0
  652. ansible_test/_internal/diff.py +3 -2
  653. ansible_test/_internal/docker_util.py +2 -1
  654. ansible_test/_internal/encoding.py +1 -0
  655. ansible_test/_internal/executor.py +1 -0
  656. ansible_test/_internal/git.py +1 -0
  657. ansible_test/_internal/host_configs.py +1 -0
  658. ansible_test/_internal/host_profiles.py +260 -16
  659. ansible_test/_internal/http.py +1 -0
  660. ansible_test/_internal/init.py +1 -0
  661. ansible_test/_internal/inventory.py +39 -3
  662. ansible_test/_internal/io.py +1 -0
  663. ansible_test/_internal/metadata.py +95 -4
  664. ansible_test/_internal/payload.py +1 -0
  665. ansible_test/_internal/processes.py +80 -0
  666. ansible_test/_internal/provider/__init__.py +1 -0
  667. ansible_test/_internal/provider/layout/__init__.py +1 -0
  668. ansible_test/_internal/provider/layout/ansible.py +1 -0
  669. ansible_test/_internal/provider/layout/collection.py +1 -0
  670. ansible_test/_internal/provider/layout/unsupported.py +1 -0
  671. ansible_test/_internal/provider/source/__init__.py +1 -0
  672. ansible_test/_internal/provider/source/git.py +1 -0
  673. ansible_test/_internal/provider/source/installed.py +1 -0
  674. ansible_test/_internal/provider/source/unsupported.py +1 -0
  675. ansible_test/_internal/provider/source/unversioned.py +1 -0
  676. ansible_test/_internal/provisioning.py +11 -4
  677. ansible_test/_internal/pypi_proxy.py +6 -5
  678. ansible_test/_internal/python_requirements.py +28 -0
  679. ansible_test/_internal/ssh.py +2 -5
  680. ansible_test/_internal/target.py +9 -0
  681. ansible_test/_internal/test.py +3 -2
  682. ansible_test/_internal/thread.py +3 -1
  683. ansible_test/_internal/timeout.py +2 -1
  684. ansible_test/_internal/util.py +41 -12
  685. ansible_test/_internal/util_common.py +18 -5
  686. ansible_test/_internal/venv.py +1 -0
  687. ansible_test/_util/controller/sanity/code-smell/action-plugin-docs.py +1 -0
  688. ansible_test/_util/controller/sanity/code-smell/changelog/sphinx.py +1 -0
  689. ansible_test/_util/controller/sanity/code-smell/changelog.py +1 -0
  690. ansible_test/_util/controller/sanity/code-smell/empty-init.py +1 -0
  691. ansible_test/_util/controller/sanity/code-smell/line-endings.py +1 -0
  692. ansible_test/_util/controller/sanity/code-smell/no-assert.py +1 -0
  693. ansible_test/_util/controller/sanity/code-smell/no-get-exception.py +1 -0
  694. ansible_test/_util/controller/sanity/code-smell/no-illegal-filenames.py +1 -0
  695. ansible_test/_util/controller/sanity/code-smell/no-smart-quotes.py +1 -0
  696. ansible_test/_util/controller/sanity/code-smell/replace-urlopen.py +1 -0
  697. ansible_test/_util/controller/sanity/code-smell/runtime-metadata.py +28 -1
  698. ansible_test/_util/controller/sanity/code-smell/shebang.py +1 -0
  699. ansible_test/_util/controller/sanity/code-smell/symlinks.py +1 -0
  700. ansible_test/_util/controller/sanity/code-smell/use-argspec-type-path.py +1 -0
  701. ansible_test/_util/controller/sanity/code-smell/use-compat-six.py +1 -0
  702. ansible_test/_util/controller/sanity/integration-aliases/yaml_to_json.py +2 -1
  703. ansible_test/_util/controller/sanity/pep8/current-ignore.txt +4 -0
  704. ansible_test/_util/controller/sanity/pylint/config/ansible-test-target.cfg +8 -5
  705. ansible_test/_util/controller/sanity/pylint/config/ansible-test.cfg +8 -5
  706. ansible_test/_util/controller/sanity/pylint/config/code-smell.cfg +8 -5
  707. ansible_test/_util/controller/sanity/pylint/config/collection.cfg +4 -5
  708. ansible_test/_util/controller/sanity/pylint/config/default.cfg +8 -7
  709. ansible_test/_util/controller/sanity/pylint/plugins/deprecated_calls.py +541 -0
  710. ansible_test/_util/controller/sanity/pylint/plugins/deprecated_comment.py +137 -0
  711. ansible_test/_util/controller/sanity/pylint/plugins/hide_unraisable.py +1 -0
  712. ansible_test/_util/controller/sanity/pylint/plugins/string_format.py +1 -8
  713. ansible_test/_util/controller/sanity/pylint/plugins/unwanted.py +1 -8
  714. ansible_test/_util/controller/sanity/validate-modules/validate_modules/main.py +55 -28
  715. ansible_test/_util/controller/sanity/validate-modules/validate_modules/module_args.py +12 -5
  716. ansible_test/_util/controller/sanity/validate-modules/validate_modules/schema.py +13 -2
  717. ansible_test/_util/controller/sanity/validate-modules/validate_modules/utils.py +1 -0
  718. ansible_test/_util/controller/sanity/yamllint/yamllinter.py +35 -17
  719. ansible_test/_util/controller/tools/collection_detail.py +1 -0
  720. ansible_test/_util/controller/tools/yaml_to_json.py +2 -1
  721. ansible_test/_util/target/injector/python.py +8 -0
  722. ansible_test/_util/target/pytest/plugins/ansible_forked.py +6 -1
  723. ansible_test/_util/target/pytest/plugins/ansible_pytest_collections.py +2 -1
  724. ansible_test/_util/target/pytest/plugins/ansible_pytest_coverage.py +1 -0
  725. ansible_test/_util/target/sanity/compile/compile.py +1 -0
  726. ansible_test/_util/target/sanity/import/importer.py +15 -16
  727. ansible_test/_util/target/setup/bootstrap.sh +9 -20
  728. ansible_test/_util/target/setup/probe_cgroups.py +1 -0
  729. ansible_test/_util/target/setup/quiet_pip.py +1 -0
  730. ansible_test/_util/target/setup/requirements.py +38 -36
  731. ansible_test/_util/target/tools/virtualenvcheck.py +2 -1
  732. ansible_test/_util/target/tools/yamlcheck.py +2 -1
  733. ansible/compat/selectors.py +0 -32
  734. ansible/errors/yaml_strings.py +0 -138
  735. ansible/executor/action_write_locks.py +0 -44
  736. ansible/executor/discovery/python_target.py +0 -47
  737. ansible/executor/powershell/module_powershell_wrapper.ps1 +0 -86
  738. ansible/executor/powershell/module_script_wrapper.ps1 +0 -22
  739. ansible/module_utils/compat/importlib.py +0 -26
  740. ansible/module_utils/compat/selectors.py +0 -32
  741. ansible/module_utils/pycompat24.py +0 -73
  742. ansible/parsing/yaml/constructor.py +0 -178
  743. ansible/template/native_helpers.py +0 -251
  744. ansible/template/template.py +0 -43
  745. ansible/template/vars.py +0 -77
  746. ansible/utils/native_jinja.py +0 -11
  747. ansible/vars/fact_cache.py +0 -71
  748. ansible_core-2.18.7rc1.dist-info/RECORD +0 -992
  749. ansible_test/_util/controller/sanity/pylint/plugins/deprecated.py +0 -411
  750. {ansible_core-2.18.7rc1.dist-info → ansible_core-2.19.0.dist-info}/WHEEL +0 -0
  751. {ansible_core-2.18.7rc1.dist-info → ansible_core-2.19.0.dist-info}/entry_points.txt +0 -0
  752. {ansible_core-2.18.7rc1.dist-info → ansible_core-2.19.0.dist-info}/licenses/COPYING +0 -0
  753. {ansible_core-2.18.7rc1.dist-info → ansible_core-2.19.0.dist-info}/licenses/licenses/Apache-License.txt +0 -0
  754. {ansible_core-2.18.7rc1.dist-info → ansible_core-2.19.0.dist-info}/licenses/licenses/MIT-license.txt +0 -0
  755. {ansible_core-2.18.7rc1.dist-info → ansible_core-2.19.0.dist-info}/licenses/licenses/PSF-license.txt +0 -0
  756. {ansible_core-2.18.7rc1.dist-info → ansible_core-2.19.0.dist-info}/licenses/licenses/simplified_bsd.txt +0 -0
  757. {ansible_core-2.18.7rc1.dist-info → ansible_core-2.19.0.dist-info}/top_level.txt +0 -0
@@ -0,0 +1,127 @@
1
+ from __future__ import annotations as _annotations
2
+
3
+ import collections.abc as _c
4
+ import textwrap as _textwrap
5
+
6
+ from ansible.module_utils._internal import _event_utils, _messages
7
+
8
+
9
+ def format_event(event: _messages.Event, include_traceback: bool) -> str:
10
+ """Format an event into a verbose message and traceback."""
11
+ msg = format_event_verbose_message(event)
12
+
13
+ if include_traceback:
14
+ msg += '\n' + format_event_traceback(event)
15
+
16
+ msg = msg.strip()
17
+
18
+ if '\n' in msg:
19
+ msg += '\n\n'
20
+ else:
21
+ msg += '\n'
22
+
23
+ return msg
24
+
25
+
26
+ def format_event_traceback(event: _messages.Event) -> str:
27
+ """Format an event into a traceback."""
28
+ segments: list[str] = []
29
+
30
+ while event:
31
+ segment = event.formatted_traceback or '(traceback missing)\n'
32
+
33
+ if event.events:
34
+ child_tracebacks = [format_event_traceback(child) for child in event.events]
35
+ segment += _format_event_children("Sub-Traceback", child_tracebacks)
36
+
37
+ segments.append(segment)
38
+
39
+ if event.chain:
40
+ segments.append(f'\n{event.chain.traceback_reason}\n\n')
41
+
42
+ event = event.chain.event
43
+ else:
44
+ event = None
45
+
46
+ return ''.join(reversed(segments))
47
+
48
+
49
+ def format_event_verbose_message(event: _messages.Event) -> str:
50
+ """
51
+ Format an event into a verbose message.
52
+ Help text, contextual information and sub-events will be included.
53
+ """
54
+ segments: list[str] = []
55
+ original_event = event
56
+
57
+ while event:
58
+ messages = [event.msg]
59
+ chain: _messages.EventChain = event.chain
60
+
61
+ while chain and chain.follow:
62
+ if chain.event.events:
63
+ break # do not collapse a chained event with sub-events, since they would be lost
64
+
65
+ if chain.event.formatted_source_context or chain.event.help_text:
66
+ if chain.event.formatted_source_context != event.formatted_source_context or chain.event.help_text != event.help_text:
67
+ break # do not collapse a chained event with different details, since they would be lost
68
+
69
+ if chain.event.chain and chain.msg_reason != chain.event.chain.msg_reason:
70
+ break # do not collapse a chained event which has a chain with a different msg_reason
71
+
72
+ messages.append(chain.event.msg)
73
+
74
+ chain = chain.event.chain
75
+
76
+ msg = _event_utils.deduplicate_message_parts(messages)
77
+ segment = '\n'.join(_get_message_lines(msg, event.help_text, event.formatted_source_context)) + '\n'
78
+
79
+ if event.events:
80
+ child_msgs = [format_event_verbose_message(child) for child in event.events]
81
+ segment += _format_event_children("Sub-Event", child_msgs)
82
+
83
+ segments.append(segment)
84
+
85
+ if chain and chain.follow:
86
+ segments.append(f'\n{chain.msg_reason}\n\n')
87
+
88
+ event = chain.event
89
+ else:
90
+ event = None
91
+
92
+ if len(segments) > 1:
93
+ segments.insert(0, _event_utils.format_event_brief_message(original_event) + '\n\n')
94
+
95
+ return ''.join(segments)
96
+
97
+
98
+ def _format_event_children(label: str, children: _c.Iterable[str]) -> str:
99
+ """Format the given list of child messages into a single string."""
100
+ items = list(children)
101
+ count = len(items)
102
+ lines = ['\n']
103
+
104
+ for idx, item in enumerate(items):
105
+ lines.append(f'+--[ {label} {idx + 1} of {count} ]---\n')
106
+ lines.append(_textwrap.indent(f"\n{item}\n", "| ", lambda value: True))
107
+
108
+ lines.append(f'+--[ End {label} ]---\n')
109
+
110
+ return ''.join(lines)
111
+
112
+
113
+ def _get_message_lines(message: str, help_text: str | None, formatted_source_context: str | None) -> list[str]:
114
+ """Return a list of message lines constructed from the given message, help text and formatted source context."""
115
+ if help_text and not formatted_source_context and '\n' not in message and '\n' not in help_text:
116
+ return [f'{message} {help_text}'] # prefer a single-line message with help text when there is no source context
117
+
118
+ message_lines = [message]
119
+
120
+ if formatted_source_context:
121
+ message_lines.append(formatted_source_context)
122
+
123
+ if help_text:
124
+ message_lines.append('')
125
+ message_lines.append(help_text)
126
+
127
+ return message_lines
@@ -0,0 +1,214 @@
1
+ """Internal utilities for serialization and deserialization."""
2
+
3
+ # DTFIX-FUTURE: most of this isn't JSON specific, find a better home
4
+
5
+ from __future__ import annotations
6
+
7
+ import enum
8
+ import json
9
+ import typing as t
10
+
11
+ from ansible.errors import AnsibleVariableTypeError
12
+
13
+ from ansible.module_utils._internal._datatag import (
14
+ _ANSIBLE_ALLOWED_MAPPING_VAR_TYPES,
15
+ _ANSIBLE_ALLOWED_NON_SCALAR_COLLECTION_VAR_TYPES,
16
+ _ANSIBLE_ALLOWED_VAR_TYPES,
17
+ _AnsibleTaggedStr,
18
+ AnsibleTagHelper,
19
+ )
20
+ from ansible.module_utils._internal._json._profiles import _tagless
21
+ from ansible.parsing.vault import EncryptedString
22
+ from ansible._internal._datatag._tags import Origin, TrustedAsTemplate
23
+ from ansible._internal._templating import _transform
24
+ from ansible.module_utils import _internal
25
+ from ansible.module_utils._internal import _datatag
26
+
27
+ _T = t.TypeVar('_T')
28
+ _sentinel = object()
29
+
30
+
31
+ class HasCurrent(t.Protocol):
32
+ """Utility protocol for mixin type safety."""
33
+
34
+ _current: t.Any
35
+
36
+
37
+ class StateTrackingMixIn(HasCurrent):
38
+ """Mixin for use with `AnsibleVariableVisitor` to track current visitation context."""
39
+
40
+ def __init__(self, *args, **kwargs) -> None:
41
+ super().__init__(*args, **kwargs)
42
+
43
+ self._stack: list[t.Any] = []
44
+
45
+ def __enter__(self) -> None:
46
+ self._stack.append(self._current)
47
+
48
+ def __exit__(self, *_args, **_kwargs) -> None:
49
+ self._stack.pop()
50
+
51
+ def _get_stack(self) -> list[t.Any]:
52
+ if not self._stack:
53
+ return []
54
+
55
+ return self._stack[1:] + [self._current]
56
+
57
+
58
+ class EncryptedStringBehavior(enum.Enum):
59
+ """How `AnsibleVariableVisitor` will handle instances of `EncryptedString`."""
60
+
61
+ PRESERVE = enum.auto()
62
+ """Preserves the unmodified `EncryptedString` instance."""
63
+ DECRYPT = enum.auto()
64
+ """Replaces the value with its decrypted plaintext."""
65
+ REDACT = enum.auto()
66
+ """Replaces the value with a placeholder string."""
67
+ FAIL = enum.auto()
68
+ """Raises an `AnsibleVariableTypeError` error."""
69
+
70
+
71
+ class AnsibleVariableVisitor:
72
+ """Utility visitor base class to recursively apply various behaviors and checks to variable object graphs."""
73
+
74
+ def __init__(
75
+ self,
76
+ *,
77
+ trusted_as_template: bool = False,
78
+ origin: Origin | None = None,
79
+ convert_mapping_to_dict: bool = False,
80
+ convert_sequence_to_list: bool = False,
81
+ convert_custom_scalars: bool = False,
82
+ convert_to_native_values: bool = False,
83
+ apply_transforms: bool = False,
84
+ visit_keys: bool = False,
85
+ encrypted_string_behavior: EncryptedStringBehavior = EncryptedStringBehavior.DECRYPT,
86
+ ):
87
+ super().__init__() # supports StateTrackingMixIn
88
+
89
+ self.trusted_as_template = trusted_as_template
90
+ self.origin = origin
91
+ self.convert_mapping_to_dict = convert_mapping_to_dict
92
+ self.convert_sequence_to_list = convert_sequence_to_list
93
+ self.convert_custom_scalars = convert_custom_scalars
94
+ self.convert_to_native_values = convert_to_native_values
95
+ self.apply_transforms = apply_transforms
96
+ self.visit_keys = visit_keys
97
+ self.encrypted_string_behavior = encrypted_string_behavior
98
+
99
+ if apply_transforms:
100
+ from ansible._internal._templating import _engine
101
+
102
+ self._template_engine = _engine.TemplateEngine()
103
+ else:
104
+ self._template_engine = None
105
+
106
+ self._current: t.Any = None # supports StateTrackingMixIn
107
+
108
+ def __enter__(self) -> t.Any:
109
+ """No-op context manager dispatcher (delegates to mixin behavior if present)."""
110
+ if func := getattr(super(), '__enter__', None):
111
+ func()
112
+
113
+ def __exit__(self, *args, **kwargs) -> t.Any:
114
+ """No-op context manager dispatcher (delegates to mixin behavior if present)."""
115
+ if func := getattr(super(), '__exit__', None):
116
+ func(*args, **kwargs)
117
+
118
+ def visit(self, value: _T) -> _T:
119
+ """
120
+ Enforces Ansible's variable type system restrictions before a var is accepted in inventory. Also, conditionally implements template trust
121
+ compatibility, depending on the plugin's declared understanding (or lack thereof). This always recursively copies inputs to fully isolate
122
+ inventory data from what the plugin provided, and prevent any later mutation.
123
+ """
124
+ return self._visit(None, value)
125
+
126
+ def _early_visit(self, value, value_type) -> t.Any:
127
+ """Overridable hook point to allow custom string handling in derived visitors."""
128
+ if value_type in (str, _AnsibleTaggedStr):
129
+ # apply compatibility behavior
130
+ if self.trusted_as_template:
131
+ result = TrustedAsTemplate().tag(value)
132
+ else:
133
+ result = value
134
+ else:
135
+ result = _sentinel
136
+
137
+ return result
138
+
139
+ def _visit_key(self, key: t.Any) -> t.Any:
140
+ """Internal implementation to recursively visit a key if visit_keys is enabled."""
141
+ if not self.visit_keys:
142
+ return key
143
+
144
+ return self._visit(None, key) # key=None prevents state tracking from seeing the key as value
145
+
146
+ def _visit(self, key: t.Any, value: _T) -> _T:
147
+ """Internal implementation to recursively visit a data structure's contents."""
148
+ self._current = key # supports StateTrackingMixIn
149
+
150
+ value_type: type = type(value)
151
+
152
+ # handle EncryptedString conversion before more generic transformation and native conversions
153
+ if value_type is EncryptedString: # pylint: disable=unidiomatic-typecheck
154
+ match self.encrypted_string_behavior:
155
+ case EncryptedStringBehavior.DECRYPT:
156
+ value = str(value) # type: ignore[assignment]
157
+ value_type = str
158
+ case EncryptedStringBehavior.REDACT:
159
+ value = "<redacted>" # type: ignore[assignment]
160
+ value_type = str
161
+ case EncryptedStringBehavior.FAIL:
162
+ raise AnsibleVariableTypeError.from_value(obj=value)
163
+ elif self.apply_transforms and value_type in _transform._type_transform_mapping:
164
+ value = self._template_engine.transform(value)
165
+ value_type = type(value)
166
+
167
+ if self.convert_to_native_values and isinstance(value, _datatag.AnsibleTaggedObject):
168
+ value = value._native_copy()
169
+ value_type = type(value)
170
+
171
+ result: _T
172
+
173
+ # DTFIX-FUTURE: Visitor generally ignores dict/mapping keys by default except for debugging and schema-aware checking.
174
+ # It could be checking keys destined for variable storage to apply more strict rules about key shape and type.
175
+
176
+ if (result := self._early_visit(value, value_type)) is not _sentinel:
177
+ pass
178
+ # DTFIX7: de-duplicate and optimize; extract inline generator expressions and fallback function or mapping for native type calculation?
179
+ elif value_type in _ANSIBLE_ALLOWED_MAPPING_VAR_TYPES: # check mappings first, because they're also collections
180
+ with self: # supports StateTrackingMixIn
181
+ result = AnsibleTagHelper.tag_copy(value, ((self._visit_key(k), self._visit(k, v)) for k, v in value.items()), value_type=value_type)
182
+ elif value_type in _ANSIBLE_ALLOWED_NON_SCALAR_COLLECTION_VAR_TYPES:
183
+ with self: # supports StateTrackingMixIn
184
+ result = AnsibleTagHelper.tag_copy(value, (self._visit(k, v) for k, v in enumerate(t.cast(t.Iterable, value))), value_type=value_type)
185
+ elif self.convert_mapping_to_dict and _internal.is_intermediate_mapping(value):
186
+ with self: # supports StateTrackingMixIn
187
+ result = {self._visit_key(k): self._visit(k, v) for k, v in value.items()} # type: ignore[assignment]
188
+ elif self.convert_sequence_to_list and _internal.is_intermediate_iterable(value):
189
+ with self: # supports StateTrackingMixIn
190
+ result = [self._visit(k, v) for k, v in enumerate(t.cast(t.Iterable, value))] # type: ignore[assignment]
191
+ elif self.convert_custom_scalars and isinstance(value, str):
192
+ result = str(value) # type: ignore[assignment]
193
+ elif self.convert_custom_scalars and isinstance(value, float):
194
+ result = float(value) # type: ignore[assignment]
195
+ elif self.convert_custom_scalars and isinstance(value, int) and not isinstance(value, bool):
196
+ result = int(value) # type: ignore[assignment]
197
+ elif value_type in _ANSIBLE_ALLOWED_VAR_TYPES:
198
+ # supported scalar type that requires no special handling, just return as-is
199
+ result = value
200
+ elif self.encrypted_string_behavior is EncryptedStringBehavior.PRESERVE and isinstance(value, EncryptedString):
201
+ result = value # type: ignore[assignment]
202
+ else:
203
+ raise AnsibleVariableTypeError.from_value(obj=value)
204
+
205
+ if self.origin and not Origin.is_tagged_on(result):
206
+ # apply shared instance default origin tag
207
+ result = self.origin.tag(result)
208
+
209
+ return result
210
+
211
+
212
+ def json_dumps_formatted(value: object) -> str:
213
+ """Return a JSON dump of `value` with formatting and keys sorted."""
214
+ return json.dumps(value, cls=_tagless.Encoder, sort_keys=True, indent=4)
@@ -0,0 +1,34 @@
1
+ from __future__ import annotations as _annotations
2
+
3
+ import typing as _t
4
+
5
+ from ansible.module_utils._internal._json import _profiles
6
+ from ansible._internal._json._profiles import _legacy
7
+ from ansible.parsing import vault as _vault
8
+
9
+
10
+ class LegacyControllerJSONEncoder(_legacy.Encoder):
11
+ """Compatibility wrapper over `legacy` profile JSON encoder to support trust stripping and vault value plaintext conversion."""
12
+
13
+ def __init__(self, preprocess_unsafe: bool = False, vault_to_text: bool = False, _decode_bytes: bool = False, **kwargs) -> None:
14
+ self._preprocess_unsafe = preprocess_unsafe
15
+ self._vault_to_text = vault_to_text
16
+ self._decode_bytes = _decode_bytes
17
+
18
+ super().__init__(**kwargs)
19
+
20
+ def default(self, o: _t.Any) -> _t.Any:
21
+ """Hooked default that can conditionally bypass base encoder behavior based on this instance's config."""
22
+ if type(o) is _profiles._WrappedValue: # pylint: disable=unidiomatic-typecheck
23
+ o = o.wrapped
24
+
25
+ if not self._preprocess_unsafe and type(o) is _legacy._Untrusted: # pylint: disable=unidiomatic-typecheck
26
+ return o.value # if not emitting unsafe markers, bypass custom unsafe serialization and just return the raw value
27
+
28
+ if self._vault_to_text and type(o) is _vault.EncryptedString: # pylint: disable=unidiomatic-typecheck
29
+ return str(o) # decrypt and return the plaintext (or fail trying)
30
+
31
+ if self._decode_bytes and isinstance(o, bytes):
32
+ return o.decode(errors='surrogateescape') # backward compatibility with `ansible.module_utils.basic.jsonify`
33
+
34
+ return super().default(o)
File without changes
@@ -0,0 +1,57 @@
1
+ from __future__ import annotations
2
+
3
+ import datetime as _datetime
4
+
5
+ from ansible.module_utils._internal import _datatag
6
+ from ansible.module_utils._internal._json import _profiles
7
+ from ansible.parsing import vault as _vault
8
+ from ansible._internal._datatag import _tags
9
+
10
+
11
+ class _Profile(_profiles._JSONSerializationProfile):
12
+ """Profile for external cache persistence of inventory/fact data that preserves most tags."""
13
+
14
+ serialize_map = {}
15
+ schema_id = 1
16
+
17
+ @classmethod
18
+ def post_init(cls, **kwargs):
19
+ cls.allowed_ansible_serializable_types = (
20
+ _profiles._common_module_types
21
+ | _profiles._common_module_response_types
22
+ | {
23
+ _datatag._AnsibleTaggedDate,
24
+ _datatag._AnsibleTaggedTime,
25
+ _datatag._AnsibleTaggedDateTime,
26
+ _datatag._AnsibleTaggedStr,
27
+ _datatag._AnsibleTaggedInt,
28
+ _datatag._AnsibleTaggedFloat,
29
+ _datatag._AnsibleTaggedList,
30
+ _datatag._AnsibleTaggedSet,
31
+ _datatag._AnsibleTaggedTuple,
32
+ _datatag._AnsibleTaggedDict,
33
+ _tags.SourceWasEncrypted,
34
+ _tags.Origin,
35
+ _tags.TrustedAsTemplate,
36
+ _vault.EncryptedString,
37
+ _vault.VaultedValue,
38
+ }
39
+ )
40
+
41
+ cls.serialize_map = {
42
+ set: cls.serialize_as_list,
43
+ tuple: cls.serialize_as_list,
44
+ _datetime.date: _datatag.AnsibleSerializableDate,
45
+ _datetime.time: _datatag.AnsibleSerializableTime,
46
+ _datetime.datetime: _datatag.AnsibleSerializableDateTime,
47
+ }
48
+
49
+ cls.handle_key = cls._handle_key_str_fallback # legacy stdlib-compatible key behavior
50
+
51
+
52
+ class Encoder(_profiles.AnsibleProfileJSONEncoder):
53
+ _profile = _Profile
54
+
55
+
56
+ class Decoder(_profiles.AnsibleProfileJSONDecoder):
57
+ _profile = _Profile
@@ -0,0 +1,40 @@
1
+ """
2
+ Backwards compatibility profile for serialization for persisted ansible-inventory output.
3
+ Behavior is equivalent to pre 2.18 `AnsibleJSONEncoder` with vault_to_text=True.
4
+ """
5
+
6
+ from __future__ import annotations
7
+
8
+ from ... import _json
9
+ from . import _legacy
10
+
11
+
12
+ class _InventoryVariableVisitor(_legacy._LegacyVariableVisitor, _json.StateTrackingMixIn):
13
+ """State-tracking visitor implementation that only applies trust to `_meta.hostvars` and `vars` inventory values."""
14
+
15
+ # DTFIX5: does the variable visitor need to support conversion of sequence/mapping for inventory?
16
+
17
+ @property
18
+ def _allow_trust(self) -> bool:
19
+ stack = self._get_stack()
20
+
21
+ if len(stack) >= 4 and stack[:2] == ['_meta', 'hostvars']:
22
+ return True
23
+
24
+ if len(stack) >= 3 and stack[1] == 'vars':
25
+ return True
26
+
27
+ return False
28
+
29
+
30
+ class _Profile(_legacy._Profile):
31
+ visitor_type = _InventoryVariableVisitor
32
+ encode_strings_as_utf8 = True
33
+
34
+
35
+ class Encoder(_legacy.Encoder):
36
+ _profile = _Profile
37
+
38
+
39
+ class Decoder(_legacy.Decoder):
40
+ _profile = _Profile
@@ -0,0 +1,189 @@
1
+ """
2
+ Backwards compatibility profile for serialization other than inventory (which should use inventory_legacy for backward-compatible trust behavior).
3
+ Behavior is equivalent to pre 2.19 `AnsibleJSONEncoder` with vault_to_text=True.
4
+ """
5
+
6
+ from __future__ import annotations as _annotations
7
+
8
+ import datetime as _datetime
9
+ import typing as _t
10
+
11
+ from ansible._internal import _json
12
+ from ansible._internal._datatag import _tags
13
+ from ansible.module_utils._internal import _datatag
14
+ from ansible.module_utils._internal._json import _profiles
15
+ from ansible.parsing import vault as _vault
16
+
17
+
18
+ class _Untrusted:
19
+ """
20
+ Temporarily wraps strings which are not trusted for templating.
21
+ Used before serialization of strings not tagged TrustedAsTemplate when trust inversion is enabled and trust is allowed in the string's context.
22
+ Used during deserialization of `__ansible_unsafe` strings to indicate they should not be tagged TrustedAsTemplate.
23
+ """
24
+
25
+ __slots__ = ('value',)
26
+
27
+ def __init__(self, value: str) -> None:
28
+ self.value = value
29
+
30
+
31
+ class _LegacyVariableVisitor(_json.AnsibleVariableVisitor):
32
+ """Variable visitor that supports optional trust inversion for legacy serialization."""
33
+
34
+ def __init__(
35
+ self,
36
+ *,
37
+ trusted_as_template: bool = False,
38
+ invert_trust: bool = False,
39
+ origin: _tags.Origin | None = None,
40
+ convert_mapping_to_dict: bool = False,
41
+ convert_sequence_to_list: bool = False,
42
+ convert_custom_scalars: bool = False,
43
+ ):
44
+ super().__init__(
45
+ trusted_as_template=trusted_as_template,
46
+ origin=origin,
47
+ convert_mapping_to_dict=convert_mapping_to_dict,
48
+ convert_sequence_to_list=convert_sequence_to_list,
49
+ convert_custom_scalars=convert_custom_scalars,
50
+ encrypted_string_behavior=_json.EncryptedStringBehavior.PRESERVE,
51
+ )
52
+
53
+ self.invert_trust = invert_trust
54
+
55
+ if trusted_as_template and invert_trust:
56
+ raise ValueError('trusted_as_template is mutually exclusive with invert_trust')
57
+
58
+ @property
59
+ def _allow_trust(self) -> bool:
60
+ """
61
+ This profile supports trust application in all contexts.
62
+ Derived implementations can override this behavior for application-dependent/schema-aware trust.
63
+ """
64
+ return True
65
+
66
+ def _early_visit(self, value, value_type) -> _t.Any:
67
+ """Similar to base implementation, but supports an intermediate wrapper for trust inversion."""
68
+ if value_type in (str, _datatag._AnsibleTaggedStr):
69
+ # apply compatibility behavior
70
+ if self.trusted_as_template and self._allow_trust:
71
+ result = _tags.TrustedAsTemplate().tag(value)
72
+ elif self.invert_trust and not _tags.TrustedAsTemplate.is_tagged_on(value) and self._allow_trust:
73
+ result = _Untrusted(value)
74
+ else:
75
+ result = value
76
+ elif value_type is _Untrusted:
77
+ result = value.value
78
+ else:
79
+ result = _json._sentinel
80
+
81
+ return result
82
+
83
+
84
+ class _Profile(_profiles._JSONSerializationProfile["Encoder", "Decoder"]):
85
+ visitor_type = _LegacyVariableVisitor
86
+
87
+ @classmethod
88
+ def serialize_untrusted(cls, value: _Untrusted) -> dict[str, str] | str:
89
+ return dict(
90
+ __ansible_unsafe=_datatag.AnsibleTagHelper.untag(value.value),
91
+ )
92
+
93
+ @classmethod
94
+ def serialize_tagged_str(cls, value: _datatag.AnsibleTaggedObject) -> _t.Any:
95
+ if ciphertext := _vault.VaultHelper.get_ciphertext(value, with_tags=False):
96
+ return dict(
97
+ __ansible_vault=ciphertext,
98
+ )
99
+
100
+ return _datatag.AnsibleTagHelper.untag(value)
101
+
102
+ @classmethod
103
+ def deserialize_unsafe(cls, value: dict[str, _t.Any]) -> _Untrusted:
104
+ ansible_unsafe = value['__ansible_unsafe']
105
+
106
+ if type(ansible_unsafe) is not str: # pylint: disable=unidiomatic-typecheck
107
+ raise TypeError(f"__ansible_unsafe is {type(ansible_unsafe)} not {str}")
108
+
109
+ return _Untrusted(ansible_unsafe)
110
+
111
+ @classmethod
112
+ def deserialize_vault(cls, value: dict[str, _t.Any]) -> _vault.EncryptedString:
113
+ ansible_vault = value['__ansible_vault']
114
+
115
+ if type(ansible_vault) is not str: # pylint: disable=unidiomatic-typecheck
116
+ raise TypeError(f"__ansible_vault is {type(ansible_vault)} not {str}")
117
+
118
+ encrypted_string = _vault.EncryptedString(ciphertext=ansible_vault)
119
+
120
+ return encrypted_string
121
+
122
+ @classmethod
123
+ def serialize_encrypted_string(cls, value: _vault.EncryptedString) -> dict[str, str]:
124
+ return dict(
125
+ __ansible_vault=_vault.VaultHelper.get_ciphertext(value, with_tags=False),
126
+ )
127
+
128
+ @classmethod
129
+ def post_init(cls) -> None:
130
+ cls.serialize_map = {
131
+ set: cls.serialize_as_list,
132
+ tuple: cls.serialize_as_list,
133
+ _datetime.date: cls.serialize_as_isoformat, # existing devel behavior
134
+ _datetime.time: cls.serialize_as_isoformat, # always failed pre-2.18, so okay to include for consistency
135
+ _datetime.datetime: cls.serialize_as_isoformat, # existing devel behavior
136
+ _datatag._AnsibleTaggedDate: cls.discard_tags,
137
+ _datatag._AnsibleTaggedTime: cls.discard_tags,
138
+ _datatag._AnsibleTaggedDateTime: cls.discard_tags,
139
+ _vault.EncryptedString: cls.serialize_encrypted_string,
140
+ _datatag._AnsibleTaggedStr: cls.serialize_tagged_str, # for VaultedValue tagged str
141
+ _datatag._AnsibleTaggedInt: cls.discard_tags,
142
+ _datatag._AnsibleTaggedFloat: cls.discard_tags,
143
+ _datatag._AnsibleTaggedList: cls.discard_tags,
144
+ _datatag._AnsibleTaggedSet: cls.discard_tags,
145
+ _datatag._AnsibleTaggedTuple: cls.discard_tags,
146
+ _datatag._AnsibleTaggedDict: cls.discard_tags,
147
+ _Untrusted: cls.serialize_untrusted, # equivalent to AnsibleJSONEncoder(preprocess_unsafe=True) in devel
148
+ }
149
+
150
+ cls.deserialize_map = {
151
+ '__ansible_unsafe': cls.deserialize_unsafe,
152
+ '__ansible_vault': cls.deserialize_vault,
153
+ }
154
+
155
+ cls.handle_key = cls._handle_key_str_fallback # type: ignore[method-assign] # legacy stdlib-compatible key behavior
156
+
157
+ @classmethod
158
+ def pre_serialize(cls, encoder: Encoder, o: _t.Any) -> _t.Any:
159
+ # DTFIX7: these conversion args probably aren't needed
160
+ avv = cls.visitor_type(invert_trust=True, convert_mapping_to_dict=True, convert_sequence_to_list=True, convert_custom_scalars=True)
161
+
162
+ return avv.visit(o)
163
+
164
+ @classmethod
165
+ def post_deserialize(cls, decoder: Decoder, o: _t.Any) -> _t.Any:
166
+ avv = cls.visitor_type(trusted_as_template=decoder._trusted_as_template, origin=decoder._origin)
167
+
168
+ return avv.visit(o)
169
+
170
+
171
+ class Encoder(_profiles.AnsibleProfileJSONEncoder):
172
+ _profile = _Profile
173
+
174
+
175
+ class Decoder(_profiles.AnsibleProfileJSONDecoder):
176
+ _profile = _Profile
177
+
178
+ def __init__(self, **kwargs) -> None:
179
+ super().__init__(**kwargs)
180
+
181
+ # NB: these can only be sampled properly when loading strings, eg, `json.loads`; the global `json.load` function does not expose the file-like to us
182
+ self._origin: _tags.Origin | None = None
183
+ self._trusted_as_template: bool = False
184
+
185
+ def raw_decode(self, s: str, idx: int = 0) -> tuple[_t.Any, int]:
186
+ self._origin = _tags.Origin.get_tag(s)
187
+ self._trusted_as_template = _tags.TrustedAsTemplate.is_tagged_on(s)
188
+
189
+ return super().raw_decode(s, idx)
@@ -0,0 +1,21 @@
1
+ from __future__ import annotations
2
+
3
+ import contextlib
4
+ import fcntl
5
+ import typing as t
6
+
7
+
8
+ @contextlib.contextmanager
9
+ def named_mutex(path: str) -> t.Iterator[None]:
10
+ """
11
+ Lightweight context manager wrapper over `fcntl.flock` to provide IPC locking via a shared filename.
12
+ Entering the context manager blocks until the lock is acquired.
13
+ The lock file will be created automatically, but creation of the parent directory and deletion of the lockfile are the caller's responsibility.
14
+ """
15
+ with open(path, 'a') as file:
16
+ fcntl.flock(file, fcntl.LOCK_EX)
17
+
18
+ try:
19
+ yield
20
+ finally:
21
+ fcntl.flock(file, fcntl.LOCK_UN)
File without changes