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

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

Potentially problematic release.


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

Files changed (757) hide show
  1. ansible/_internal/__init__.py +53 -0
  2. ansible/_internal/_ansiballz/__init__.py +0 -0
  3. ansible/_internal/_ansiballz/_builder.py +101 -0
  4. ansible/_internal/_ansiballz/_wrapper.py +262 -0
  5. ansible/_internal/_collection_proxy.py +47 -0
  6. ansible/_internal/_datatag/__init__.py +0 -0
  7. ansible/_internal/_datatag/_tags.py +130 -0
  8. ansible/_internal/_datatag/_utils.py +19 -0
  9. ansible/_internal/_datatag/_wrappers.py +33 -0
  10. ansible/_internal/_errors/__init__.py +0 -0
  11. ansible/_internal/_errors/_alarm_timeout.py +66 -0
  12. ansible/_internal/_errors/_captured.py +123 -0
  13. ansible/_internal/_errors/_error_factory.py +89 -0
  14. ansible/_internal/_errors/_error_utils.py +240 -0
  15. ansible/_internal/_errors/_handler.py +91 -0
  16. ansible/_internal/_errors/_task_timeout.py +28 -0
  17. ansible/_internal/_event_formatting.py +127 -0
  18. ansible/_internal/_json/__init__.py +214 -0
  19. ansible/_internal/_json/_legacy_encoder.py +34 -0
  20. ansible/_internal/_json/_profiles/__init__.py +0 -0
  21. ansible/_internal/_json/_profiles/_cache_persistence.py +57 -0
  22. ansible/_internal/_json/_profiles/_inventory_legacy.py +40 -0
  23. ansible/_internal/_json/_profiles/_legacy.py +189 -0
  24. ansible/_internal/_locking.py +21 -0
  25. ansible/_internal/_plugins/__init__.py +0 -0
  26. ansible/_internal/_plugins/_cache.py +57 -0
  27. ansible/_internal/_ssh/__init__.py +0 -0
  28. ansible/_internal/_ssh/_agent_launch.py +91 -0
  29. ansible/_internal/_ssh/_ssh_agent.py +619 -0
  30. ansible/_internal/_task.py +78 -0
  31. ansible/_internal/_templating/__init__.py +12 -0
  32. ansible/_internal/_templating/_access.py +86 -0
  33. ansible/_internal/_templating/_chain_templar.py +63 -0
  34. ansible/_internal/_templating/_datatag.py +95 -0
  35. ansible/_internal/_templating/_engine.py +592 -0
  36. ansible/_internal/_templating/_errors.py +28 -0
  37. ansible/_internal/_templating/_jinja_bits.py +1106 -0
  38. ansible/_internal/_templating/_jinja_common.py +323 -0
  39. ansible/_internal/_templating/_jinja_patches.py +44 -0
  40. ansible/_internal/_templating/_jinja_plugins.py +375 -0
  41. ansible/_internal/_templating/_lazy_containers.py +633 -0
  42. ansible/_internal/_templating/_marker_behaviors.py +103 -0
  43. ansible/_internal/_templating/_template_vars.py +72 -0
  44. ansible/_internal/_templating/_transform.py +70 -0
  45. ansible/_internal/_templating/_utils.py +108 -0
  46. ansible/_internal/_testing.py +26 -0
  47. ansible/_internal/_wrapt.py +1052 -0
  48. ansible/_internal/_yaml/__init__.py +0 -0
  49. ansible/_internal/_yaml/_constructor.py +240 -0
  50. ansible/_internal/_yaml/_dumper.py +70 -0
  51. ansible/_internal/_yaml/_errors.py +166 -0
  52. ansible/_internal/_yaml/_loader.py +66 -0
  53. ansible/_internal/ansible_collections/ansible/_protomatter/README.md +11 -0
  54. ansible/_internal/ansible_collections/ansible/_protomatter/plugins/action/debug.py +36 -0
  55. ansible/_internal/ansible_collections/ansible/_protomatter/plugins/filter/apply_trust.py +19 -0
  56. ansible/_internal/ansible_collections/ansible/_protomatter/plugins/filter/dump_object.py +27 -0
  57. ansible/_internal/ansible_collections/ansible/_protomatter/plugins/filter/finalize.py +16 -0
  58. ansible/_internal/ansible_collections/ansible/_protomatter/plugins/filter/origin.py +18 -0
  59. ansible/_internal/ansible_collections/ansible/_protomatter/plugins/filter/python_literal_eval.py +24 -0
  60. ansible/_internal/ansible_collections/ansible/_protomatter/plugins/filter/python_literal_eval.yml +33 -0
  61. ansible/_internal/ansible_collections/ansible/_protomatter/plugins/filter/tag_names.py +16 -0
  62. ansible/_internal/ansible_collections/ansible/_protomatter/plugins/filter/true_type.py +17 -0
  63. ansible/_internal/ansible_collections/ansible/_protomatter/plugins/filter/unmask.py +49 -0
  64. ansible/_internal/ansible_collections/ansible/_protomatter/plugins/lookup/config.py +21 -0
  65. ansible/_internal/ansible_collections/ansible/_protomatter/plugins/lookup/config.yml +2 -0
  66. ansible/_internal/ansible_collections/ansible/_protomatter/plugins/test/tagged.py +15 -0
  67. ansible/_internal/ansible_collections/ansible/_protomatter/plugins/test/tagged.yml +19 -0
  68. ansible/_internal/ansible_collections/ansible/_protomatter/plugins/test/tagged_with.py +18 -0
  69. ansible/_internal/ansible_collections/ansible/_protomatter/plugins/test/tagged_with.yml +19 -0
  70. ansible/cli/__init__.py +93 -104
  71. ansible/cli/_ssh_askpass.py +54 -0
  72. ansible/cli/adhoc.py +20 -10
  73. ansible/cli/arguments/option_helpers.py +163 -10
  74. ansible/cli/config.py +43 -68
  75. ansible/cli/console.py +13 -11
  76. ansible/cli/doc.py +134 -77
  77. ansible/cli/galaxy.py +27 -20
  78. ansible/cli/inventory.py +28 -28
  79. ansible/cli/playbook.py +4 -12
  80. ansible/cli/pull.py +6 -3
  81. ansible/cli/scripts/ansible_connection_cli_stub.py +7 -7
  82. ansible/cli/vault.py +12 -11
  83. ansible/compat/__init__.py +2 -2
  84. ansible/compat/importlib_resources.py +9 -12
  85. ansible/config/base.yml +218 -133
  86. ansible/config/manager.py +220 -159
  87. ansible/constants.py +2 -65
  88. ansible/errors/__init__.py +350 -256
  89. ansible/executor/interpreter_discovery.py +28 -149
  90. ansible/executor/module_common.py +480 -514
  91. ansible/executor/play_iterator.py +22 -27
  92. ansible/executor/playbook_executor.py +11 -11
  93. ansible/executor/powershell/async_watchdog.ps1 +97 -102
  94. ansible/executor/powershell/async_wrapper.ps1 +204 -153
  95. ansible/executor/powershell/become_wrapper.ps1 +107 -144
  96. ansible/executor/powershell/bootstrap_wrapper.ps1 +46 -9
  97. ansible/executor/powershell/coverage_wrapper.ps1 +91 -135
  98. ansible/executor/powershell/exec_wrapper.ps1 +675 -196
  99. ansible/executor/powershell/module_manifest.py +469 -265
  100. ansible/executor/powershell/module_wrapper.ps1 +195 -186
  101. ansible/executor/powershell/powershell_expand_user.ps1 +20 -0
  102. ansible/executor/powershell/powershell_mkdtemp.ps1 +17 -0
  103. ansible/executor/powershell/psrp_fetch_file.ps1 +41 -0
  104. ansible/executor/powershell/psrp_put_file.ps1 +122 -0
  105. ansible/executor/powershell/winrm_fetch_file.ps1 +46 -0
  106. ansible/executor/powershell/winrm_put_file.ps1 +36 -0
  107. ansible/executor/process/worker.py +139 -149
  108. ansible/executor/stats.py +5 -5
  109. ansible/executor/task_executor.py +270 -297
  110. ansible/executor/task_queue_manager.py +135 -137
  111. ansible/executor/task_result.py +182 -79
  112. ansible/galaxy/__init__.py +2 -2
  113. ansible/galaxy/api.py +26 -25
  114. ansible/galaxy/collection/__init__.py +6 -14
  115. ansible/galaxy/collection/concrete_artifact_manager.py +12 -21
  116. ansible/galaxy/dependency_resolution/dataclasses.py +14 -4
  117. ansible/galaxy/dependency_resolution/providers.py +4 -4
  118. ansible/galaxy/dependency_resolution/reporters.py +81 -0
  119. ansible/galaxy/role.py +6 -10
  120. ansible/galaxy/token.py +28 -21
  121. ansible/inventory/data.py +47 -57
  122. ansible/inventory/group.py +50 -73
  123. ansible/inventory/helpers.py +9 -0
  124. ansible/inventory/host.py +37 -54
  125. ansible/inventory/manager.py +79 -34
  126. ansible/keyword_desc.yml +1 -1
  127. ansible/module_utils/_internal/__init__.py +55 -0
  128. ansible/module_utils/_internal/_ambient_context.py +58 -0
  129. ansible/module_utils/_internal/_ansiballz/__init__.py +0 -0
  130. ansible/module_utils/_internal/_ansiballz/_extensions/__init__.py +0 -0
  131. ansible/module_utils/_internal/_ansiballz/_extensions/_coverage.py +45 -0
  132. ansible/module_utils/_internal/_ansiballz/_extensions/_pydevd.py +62 -0
  133. ansible/module_utils/_internal/_ansiballz/_loader.py +81 -0
  134. ansible/module_utils/_internal/_ansiballz/_respawn.py +32 -0
  135. ansible/module_utils/_internal/_ansiballz/_respawn_wrapper.py +23 -0
  136. ansible/module_utils/_internal/_concurrent/_daemon_threading.py +1 -0
  137. ansible/module_utils/_internal/_dataclass_validation.py +217 -0
  138. ansible/module_utils/_internal/_datatag/__init__.py +961 -0
  139. ansible/module_utils/_internal/_datatag/_tags.py +16 -0
  140. ansible/module_utils/_internal/_debugging.py +31 -0
  141. ansible/module_utils/_internal/_deprecator.py +157 -0
  142. ansible/module_utils/_internal/_errors.py +101 -0
  143. ansible/module_utils/_internal/_event_utils.py +61 -0
  144. ansible/module_utils/_internal/_json/__init__.py +63 -0
  145. ansible/module_utils/_internal/_json/_legacy_encoder.py +26 -0
  146. ansible/module_utils/_internal/_json/_profiles/__init__.py +428 -0
  147. ansible/module_utils/_internal/_json/_profiles/_fallback_to_str.py +73 -0
  148. ansible/module_utils/_internal/_json/_profiles/_module_legacy_c2m.py +33 -0
  149. ansible/module_utils/_internal/_json/_profiles/_module_legacy_m2c.py +37 -0
  150. ansible/module_utils/_internal/_json/_profiles/_module_modern_c2m.py +35 -0
  151. ansible/module_utils/_internal/_json/_profiles/_module_modern_m2c.py +33 -0
  152. ansible/module_utils/_internal/_json/_profiles/_tagless.py +52 -0
  153. ansible/module_utils/_internal/_messages.py +130 -0
  154. ansible/module_utils/_internal/_patches/__init__.py +66 -0
  155. ansible/module_utils/_internal/_patches/_dataclass_annotation_patch.py +53 -0
  156. ansible/module_utils/_internal/_patches/_socket_patch.py +34 -0
  157. ansible/module_utils/_internal/_patches/_sys_intern_patch.py +34 -0
  158. ansible/module_utils/_internal/_plugin_info.py +38 -0
  159. ansible/module_utils/_internal/_stack.py +22 -0
  160. ansible/module_utils/_internal/_testing.py +0 -0
  161. ansible/module_utils/_internal/_text_utils.py +6 -0
  162. ansible/module_utils/_internal/_traceback.py +92 -0
  163. ansible/module_utils/_internal/_validation.py +14 -0
  164. ansible/module_utils/ansible_release.py +2 -2
  165. ansible/module_utils/api.py +1 -2
  166. ansible/module_utils/basic.py +303 -202
  167. ansible/module_utils/common/_utils.py +24 -28
  168. ansible/module_utils/common/arg_spec.py +8 -3
  169. ansible/module_utils/common/collections.py +7 -2
  170. ansible/module_utils/common/dict_transformations.py +2 -2
  171. ansible/module_utils/common/file.py +2 -2
  172. ansible/module_utils/common/json.py +90 -84
  173. ansible/module_utils/common/locale.py +2 -2
  174. ansible/module_utils/common/parameters.py +27 -24
  175. ansible/module_utils/common/process.py +2 -3
  176. ansible/module_utils/common/respawn.py +11 -33
  177. ansible/module_utils/common/sentinel.py +66 -0
  178. ansible/module_utils/common/sys_info.py +8 -8
  179. ansible/module_utils/common/text/converters.py +16 -37
  180. ansible/module_utils/common/validation.py +35 -24
  181. ansible/module_utils/common/warnings.py +143 -25
  182. ansible/module_utils/common/yaml.py +29 -3
  183. ansible/module_utils/compat/datetime.py +33 -21
  184. ansible/module_utils/compat/paramiko.py +21 -10
  185. ansible/module_utils/compat/typing.py +6 -5
  186. ansible/module_utils/connection.py +10 -13
  187. ansible/module_utils/csharp/Ansible.Basic.cs +15 -12
  188. ansible/module_utils/csharp/Ansible.Become.cs +1 -0
  189. ansible/module_utils/csharp/Ansible.Privilege.cs +2 -2
  190. ansible/module_utils/csharp/Ansible._Async.cs +517 -0
  191. ansible/module_utils/datatag.py +49 -0
  192. ansible/module_utils/distro/__init__.py +2 -2
  193. ansible/module_utils/facts/ansible_collector.py +4 -5
  194. ansible/module_utils/facts/collector.py +13 -14
  195. ansible/module_utils/facts/compat.py +4 -4
  196. ansible/module_utils/facts/default_collectors.py +1 -1
  197. ansible/module_utils/facts/hardware/aix.py +34 -0
  198. ansible/module_utils/facts/hardware/base.py +2 -2
  199. ansible/module_utils/facts/hardware/darwin.py +1 -3
  200. ansible/module_utils/facts/hardware/freebsd.py +2 -2
  201. ansible/module_utils/facts/hardware/linux.py +5 -5
  202. ansible/module_utils/facts/namespace.py +1 -1
  203. ansible/module_utils/facts/network/base.py +1 -1
  204. ansible/module_utils/facts/network/fc_wwn.py +1 -2
  205. ansible/module_utils/facts/network/iscsi.py +1 -2
  206. ansible/module_utils/facts/network/nvme.py +1 -2
  207. ansible/module_utils/facts/other/facter.py +2 -3
  208. ansible/module_utils/facts/other/ohai.py +2 -3
  209. ansible/module_utils/facts/sysctl.py +4 -6
  210. ansible/module_utils/facts/system/apparmor.py +1 -2
  211. ansible/module_utils/facts/system/caps.py +3 -3
  212. ansible/module_utils/facts/system/chroot.py +1 -2
  213. ansible/module_utils/facts/system/cmdline.py +1 -2
  214. ansible/module_utils/facts/system/date_time.py +5 -3
  215. ansible/module_utils/facts/system/distribution.py +27 -13
  216. ansible/module_utils/facts/system/dns.py +1 -1
  217. ansible/module_utils/facts/system/env.py +1 -2
  218. ansible/module_utils/facts/system/fips.py +7 -20
  219. ansible/module_utils/facts/system/loadavg.py +1 -2
  220. ansible/module_utils/facts/system/local.py +2 -3
  221. ansible/module_utils/facts/system/lsb.py +1 -2
  222. ansible/module_utils/facts/system/pkg_mgr.py +1 -2
  223. ansible/module_utils/facts/system/platform.py +1 -2
  224. ansible/module_utils/facts/system/python.py +1 -2
  225. ansible/module_utils/facts/system/selinux.py +1 -1
  226. ansible/module_utils/facts/system/service_mgr.py +1 -2
  227. ansible/module_utils/facts/system/ssh_pub_keys.py +1 -1
  228. ansible/module_utils/facts/system/systemd.py +1 -1
  229. ansible/module_utils/facts/system/user.py +1 -2
  230. ansible/module_utils/facts/utils.py +3 -3
  231. ansible/module_utils/facts/virtual/base.py +1 -1
  232. ansible/module_utils/facts/virtual/linux.py +3 -3
  233. ansible/module_utils/facts/virtual/sunos.py +3 -15
  234. ansible/module_utils/facts/virtual/sysctl.py +3 -16
  235. ansible/module_utils/json_utils.py +2 -2
  236. ansible/module_utils/parsing/convert_bool.py +7 -1
  237. ansible/module_utils/powershell/Ansible.ModuleUtils.AddType.psm1 +1 -1
  238. ansible/module_utils/powershell/Ansible.ModuleUtils.CamelConversion.psm1 +1 -1
  239. ansible/module_utils/powershell/Ansible.ModuleUtils.CommandUtil.psm1 +1 -1
  240. ansible/module_utils/powershell/Ansible.ModuleUtils.WebRequest.psm1 +1 -1
  241. ansible/module_utils/service.py +21 -31
  242. ansible/module_utils/splitter.py +7 -7
  243. ansible/module_utils/testing.py +31 -0
  244. ansible/module_utils/urls.py +64 -35
  245. ansible/modules/add_host.py +4 -4
  246. ansible/modules/apt.py +69 -49
  247. ansible/modules/apt_key.py +19 -12
  248. ansible/modules/apt_repository.py +32 -51
  249. ansible/modules/assemble.py +16 -14
  250. ansible/modules/assert.py +4 -4
  251. ansible/modules/async_status.py +24 -24
  252. ansible/modules/async_wrapper.py +20 -25
  253. ansible/modules/blockinfile.py +6 -7
  254. ansible/modules/command.py +13 -20
  255. ansible/modules/copy.py +60 -147
  256. ansible/modules/cron.py +24 -21
  257. ansible/modules/deb822_repository.py +8 -9
  258. ansible/modules/debconf.py +5 -5
  259. ansible/modules/debug.py +4 -4
  260. ansible/modules/dnf.py +8 -8
  261. ansible/modules/dnf5.py +39 -13
  262. ansible/modules/dpkg_selections.py +4 -4
  263. ansible/modules/expect.py +13 -15
  264. ansible/modules/fail.py +4 -4
  265. ansible/modules/fetch.py +4 -4
  266. ansible/modules/file.py +184 -144
  267. ansible/modules/find.py +22 -20
  268. ansible/modules/gather_facts.py +3 -3
  269. ansible/modules/get_url.py +77 -54
  270. ansible/modules/getent.py +7 -9
  271. ansible/modules/git.py +38 -38
  272. ansible/modules/group.py +6 -6
  273. ansible/modules/group_by.py +4 -4
  274. ansible/modules/hostname.py +15 -32
  275. ansible/modules/import_playbook.py +6 -6
  276. ansible/modules/import_role.py +6 -6
  277. ansible/modules/import_tasks.py +6 -6
  278. ansible/modules/include_role.py +6 -6
  279. ansible/modules/include_tasks.py +6 -6
  280. ansible/modules/include_vars.py +6 -6
  281. ansible/modules/iptables.py +86 -73
  282. ansible/modules/known_hosts.py +22 -24
  283. ansible/modules/lineinfile.py +5 -5
  284. ansible/modules/meta.py +4 -4
  285. ansible/modules/mount_facts.py +2 -2
  286. ansible/modules/package.py +10 -4
  287. ansible/modules/package_facts.py +22 -10
  288. ansible/modules/pause.py +6 -6
  289. ansible/modules/ping.py +6 -6
  290. ansible/modules/pip.py +21 -26
  291. ansible/modules/raw.py +6 -6
  292. ansible/modules/reboot.py +6 -6
  293. ansible/modules/replace.py +10 -14
  294. ansible/modules/rpm_key.py +7 -8
  295. ansible/modules/script.py +4 -4
  296. ansible/modules/service.py +10 -17
  297. ansible/modules/service_facts.py +87 -10
  298. ansible/modules/set_fact.py +5 -5
  299. ansible/modules/set_stats.py +4 -4
  300. ansible/modules/setup.py +2 -2
  301. ansible/modules/shell.py +6 -6
  302. ansible/modules/slurp.py +16 -19
  303. ansible/modules/stat.py +15 -31
  304. ansible/modules/subversion.py +15 -15
  305. ansible/modules/systemd.py +7 -7
  306. ansible/modules/systemd_service.py +7 -7
  307. ansible/modules/sysvinit.py +9 -9
  308. ansible/modules/tempfile.py +5 -6
  309. ansible/modules/template.py +6 -6
  310. ansible/modules/unarchive.py +38 -17
  311. ansible/modules/uri.py +33 -26
  312. ansible/modules/user.py +45 -32
  313. ansible/modules/validate_argument_spec.py +10 -7
  314. ansible/modules/wait_for.py +70 -60
  315. ansible/modules/wait_for_connection.py +6 -6
  316. ansible/modules/yum_repository.py +10 -9
  317. ansible/parsing/ajson.py +17 -37
  318. ansible/parsing/dataloader.py +99 -54
  319. ansible/parsing/mod_args.py +62 -60
  320. ansible/parsing/plugin_docs.py +21 -86
  321. ansible/parsing/quoting.py +1 -1
  322. ansible/parsing/splitter.py +27 -12
  323. ansible/parsing/utils/addresses.py +24 -24
  324. ansible/parsing/utils/jsonify.py +5 -1
  325. ansible/parsing/utils/yaml.py +32 -61
  326. ansible/parsing/vault/__init__.py +327 -99
  327. ansible/parsing/yaml/__init__.py +0 -18
  328. ansible/parsing/yaml/dumper.py +6 -120
  329. ansible/parsing/yaml/loader.py +6 -39
  330. ansible/parsing/yaml/objects.py +43 -335
  331. ansible/playbook/__init__.py +1 -1
  332. ansible/playbook/attribute.py +8 -3
  333. ansible/playbook/base.py +187 -134
  334. ansible/playbook/block.py +26 -24
  335. ansible/playbook/collectionsearch.py +1 -15
  336. ansible/playbook/conditional.py +3 -77
  337. ansible/playbook/handler.py +8 -2
  338. ansible/playbook/helpers.py +41 -53
  339. ansible/playbook/included_file.py +32 -26
  340. ansible/playbook/loop_control.py +2 -2
  341. ansible/playbook/play.py +85 -44
  342. ansible/playbook/play_context.py +14 -17
  343. ansible/playbook/playbook_include.py +27 -62
  344. ansible/playbook/role/__init__.py +64 -49
  345. ansible/playbook/role/definition.py +15 -17
  346. ansible/playbook/role/include.py +2 -4
  347. ansible/playbook/role/metadata.py +10 -11
  348. ansible/playbook/role_include.py +3 -3
  349. ansible/playbook/taggable.py +28 -12
  350. ansible/playbook/task.py +192 -121
  351. ansible/playbook/task_include.py +5 -5
  352. ansible/plugins/__init__.py +58 -26
  353. ansible/plugins/action/__init__.py +188 -186
  354. ansible/plugins/action/add_host.py +2 -2
  355. ansible/plugins/action/assemble.py +11 -18
  356. ansible/plugins/action/assert.py +55 -67
  357. ansible/plugins/action/async_status.py +7 -2
  358. ansible/plugins/action/copy.py +14 -17
  359. ansible/plugins/action/debug.py +37 -31
  360. ansible/plugins/action/dnf.py +3 -4
  361. ansible/plugins/action/fail.py +1 -1
  362. ansible/plugins/action/fetch.py +7 -8
  363. ansible/plugins/action/gather_facts.py +13 -14
  364. ansible/plugins/action/group_by.py +1 -1
  365. ansible/plugins/action/include_vars.py +10 -11
  366. ansible/plugins/action/package.py +8 -14
  367. ansible/plugins/action/pause.py +2 -2
  368. ansible/plugins/action/script.py +27 -38
  369. ansible/plugins/action/service.py +9 -18
  370. ansible/plugins/action/set_fact.py +3 -12
  371. ansible/plugins/action/set_stats.py +3 -8
  372. ansible/plugins/action/template.py +47 -67
  373. ansible/plugins/action/unarchive.py +6 -16
  374. ansible/plugins/action/uri.py +9 -20
  375. ansible/plugins/action/validate_argument_spec.py +5 -5
  376. ansible/plugins/action/wait_for_connection.py +1 -1
  377. ansible/plugins/become/__init__.py +31 -8
  378. ansible/plugins/become/runas.py +71 -0
  379. ansible/plugins/become/su.py +13 -8
  380. ansible/plugins/become/sudo.py +19 -0
  381. ansible/plugins/cache/__init__.py +52 -63
  382. ansible/plugins/cache/base.py +8 -0
  383. ansible/plugins/cache/jsonfile.py +10 -16
  384. ansible/plugins/cache/memory.py +6 -12
  385. ansible/plugins/callback/__init__.py +294 -201
  386. ansible/plugins/callback/default.py +99 -95
  387. ansible/plugins/callback/junit.py +44 -43
  388. ansible/plugins/callback/minimal.py +28 -25
  389. ansible/plugins/callback/oneline.py +34 -21
  390. ansible/plugins/callback/tree.py +27 -16
  391. ansible/plugins/connection/__init__.py +47 -34
  392. ansible/plugins/connection/local.py +156 -60
  393. ansible/plugins/connection/paramiko_ssh.py +34 -24
  394. ansible/plugins/connection/psrp.py +76 -165
  395. ansible/plugins/connection/ssh.py +326 -86
  396. ansible/plugins/connection/winrm.py +62 -141
  397. ansible/plugins/doc_fragments/action_common_attributes.py +14 -14
  398. ansible/plugins/doc_fragments/action_core.py +6 -6
  399. ansible/plugins/doc_fragments/backup.py +2 -2
  400. ansible/plugins/doc_fragments/checksum_common.py +27 -0
  401. ansible/plugins/doc_fragments/constructed.py +8 -4
  402. ansible/plugins/doc_fragments/decrypt.py +2 -2
  403. ansible/plugins/doc_fragments/default_callback.py +2 -2
  404. ansible/plugins/doc_fragments/files.py +2 -2
  405. ansible/plugins/doc_fragments/inventory_cache.py +2 -2
  406. ansible/plugins/doc_fragments/result_format_callback.py +2 -2
  407. ansible/plugins/doc_fragments/return_common.py +2 -2
  408. ansible/plugins/doc_fragments/template_common.py +4 -4
  409. ansible/plugins/doc_fragments/url.py +17 -1
  410. ansible/plugins/doc_fragments/url_windows.py +2 -2
  411. ansible/plugins/doc_fragments/validate.py +2 -2
  412. ansible/plugins/doc_fragments/vars_plugin_staging.py +2 -2
  413. ansible/plugins/filter/__init__.py +6 -2
  414. ansible/plugins/filter/b64decode.yml +22 -0
  415. ansible/plugins/filter/b64encode.yml +22 -0
  416. ansible/plugins/filter/bool.yml +11 -4
  417. ansible/plugins/filter/core.py +245 -120
  418. ansible/plugins/filter/encryption.py +42 -34
  419. ansible/plugins/filter/flatten.yml +3 -2
  420. ansible/plugins/filter/human_to_bytes.yml +1 -1
  421. ansible/plugins/filter/mathstuff.py +30 -37
  422. ansible/plugins/filter/password_hash.yml +8 -0
  423. ansible/plugins/filter/pow.yml +1 -1
  424. ansible/plugins/filter/regex_search.yml +1 -4
  425. ansible/plugins/filter/root.yml +1 -1
  426. ansible/plugins/filter/split.yml +1 -1
  427. ansible/plugins/filter/strftime.yml +3 -3
  428. ansible/plugins/filter/to_nice_yaml.yml +0 -4
  429. ansible/plugins/filter/to_uuid.yml +1 -1
  430. ansible/plugins/filter/to_yaml.yml +0 -4
  431. ansible/plugins/filter/unvault.yml +1 -1
  432. ansible/plugins/filter/urls.py +1 -1
  433. ansible/plugins/filter/urlsplit.py +8 -9
  434. ansible/plugins/filter/vault.yml +14 -9
  435. ansible/plugins/filter/win_basename.yml +6 -1
  436. ansible/plugins/filter/win_dirname.yml +5 -0
  437. ansible/plugins/inventory/__init__.py +107 -86
  438. ansible/plugins/inventory/advanced_host_list.py +7 -5
  439. ansible/plugins/inventory/auto.py +11 -4
  440. ansible/plugins/inventory/constructed.py +21 -24
  441. ansible/plugins/inventory/generator.py +16 -11
  442. ansible/plugins/inventory/host_list.py +7 -5
  443. ansible/plugins/inventory/ini.py +78 -44
  444. ansible/plugins/inventory/script.py +190 -120
  445. ansible/plugins/inventory/toml.py +16 -126
  446. ansible/plugins/inventory/yaml.py +10 -8
  447. ansible/plugins/list.py +72 -19
  448. ansible/plugins/loader.py +383 -198
  449. ansible/plugins/lookup/__init__.py +21 -4
  450. ansible/plugins/lookup/config.py +21 -35
  451. ansible/plugins/lookup/csvfile.py +19 -73
  452. ansible/plugins/lookup/dict.py +1 -6
  453. ansible/plugins/lookup/env.py +12 -9
  454. ansible/plugins/lookup/file.py +5 -8
  455. ansible/plugins/lookup/first_found.py +87 -55
  456. ansible/plugins/lookup/indexed_items.py +1 -10
  457. ansible/plugins/lookup/ini.py +14 -13
  458. ansible/plugins/lookup/items.py +1 -1
  459. ansible/plugins/lookup/lines.py +8 -1
  460. ansible/plugins/lookup/list.py +1 -1
  461. ansible/plugins/lookup/nested.py +2 -18
  462. ansible/plugins/lookup/password.py +5 -5
  463. ansible/plugins/lookup/pipe.py +5 -7
  464. ansible/plugins/lookup/sequence.py +18 -8
  465. ansible/plugins/lookup/subelements.py +1 -4
  466. ansible/plugins/lookup/template.py +47 -36
  467. ansible/plugins/lookup/together.py +0 -12
  468. ansible/plugins/lookup/unvault.py +1 -5
  469. ansible/plugins/lookup/url.py +4 -10
  470. ansible/plugins/lookup/vars.py +16 -24
  471. ansible/plugins/shell/__init__.py +58 -4
  472. ansible/plugins/shell/cmd.py +2 -2
  473. ansible/plugins/shell/powershell.py +106 -31
  474. ansible/plugins/shell/sh.py +13 -7
  475. ansible/plugins/strategy/__init__.py +168 -193
  476. ansible/plugins/strategy/debug.py +2 -2
  477. ansible/plugins/strategy/free.py +16 -31
  478. ansible/plugins/strategy/host_pinned.py +2 -2
  479. ansible/plugins/strategy/linear.py +41 -41
  480. ansible/plugins/terminal/__init__.py +4 -4
  481. ansible/plugins/test/__init__.py +7 -2
  482. ansible/plugins/test/core.py +75 -35
  483. ansible/plugins/test/files.py +1 -1
  484. ansible/plugins/test/finished.yml +1 -1
  485. ansible/plugins/test/mathstuff.py +3 -3
  486. ansible/plugins/test/uri.py +5 -8
  487. ansible/plugins/vars/host_group_vars.py +7 -14
  488. ansible/release.py +2 -2
  489. ansible/template/__init__.py +353 -943
  490. ansible/utils/__init__.py +0 -18
  491. ansible/utils/collection_loader/__init__.py +54 -5
  492. ansible/utils/collection_loader/_collection_config.py +5 -6
  493. ansible/utils/collection_loader/_collection_finder.py +82 -96
  494. ansible/utils/collection_loader/_collection_meta.py +15 -8
  495. ansible/utils/display.py +485 -73
  496. ansible/utils/encrypt.py +27 -19
  497. ansible/utils/fqcn.py +2 -2
  498. ansible/utils/galaxy.py +2 -2
  499. ansible/utils/hashing.py +8 -10
  500. ansible/utils/helpers.py +2 -2
  501. ansible/utils/listify.py +10 -8
  502. ansible/utils/lock.py +2 -2
  503. ansible/utils/path.py +10 -12
  504. ansible/utils/plugin_docs.py +16 -14
  505. ansible/utils/py3compat.py +2 -7
  506. ansible/utils/sentinel.py +4 -62
  507. ansible/utils/singleton.py +2 -0
  508. ansible/utils/ssh_functions.py +6 -2
  509. ansible/utils/unsafe_proxy.py +23 -332
  510. ansible/utils/vars.py +55 -8
  511. ansible/utils/version.py +2 -2
  512. ansible/vars/clean.py +5 -5
  513. ansible/vars/hostvars.py +60 -90
  514. ansible/vars/manager.py +220 -285
  515. ansible/vars/plugins.py +4 -4
  516. ansible/vars/reserved.py +13 -12
  517. {ansible_core-2.18.7.dist-info → ansible_core-2.19.0.dist-info}/METADATA +4 -3
  518. ansible_core-2.19.0.dist-info/RECORD +1097 -0
  519. ansible_core-2.19.0.dist-info/licenses/licenses/BSD-3-Clause.txt +28 -0
  520. ansible_test/_data/completion/docker.txt +7 -7
  521. ansible_test/_data/completion/remote.txt +6 -6
  522. ansible_test/_data/completion/windows.txt +1 -0
  523. ansible_test/_data/requirements/ansible.txt +2 -2
  524. ansible_test/_data/requirements/sanity.ansible-doc.txt +3 -3
  525. ansible_test/_data/requirements/sanity.changelog.txt +2 -2
  526. ansible_test/_data/requirements/sanity.import.plugin.txt +2 -2
  527. ansible_test/_data/requirements/sanity.pep8.txt +1 -1
  528. ansible_test/_data/requirements/sanity.pylint.txt +5 -5
  529. ansible_test/_data/requirements/sanity.validate-modules.txt +2 -2
  530. ansible_test/_data/requirements/sanity.yamllint.txt +1 -1
  531. ansible_test/_data/requirements/units.txt +1 -0
  532. ansible_test/_internal/__init__.py +6 -0
  533. ansible_test/_internal/ansible_util.py +3 -1
  534. ansible_test/_internal/become.py +1 -0
  535. ansible_test/_internal/bootstrap.py +1 -0
  536. ansible_test/_internal/cache.py +1 -0
  537. ansible_test/_internal/cgroup.py +1 -0
  538. ansible_test/_internal/ci/__init__.py +1 -0
  539. ansible_test/_internal/ci/azp.py +1 -0
  540. ansible_test/_internal/ci/local.py +1 -0
  541. ansible_test/_internal/classification/__init__.py +1 -0
  542. ansible_test/_internal/classification/common.py +1 -0
  543. ansible_test/_internal/classification/csharp.py +1 -0
  544. ansible_test/_internal/classification/powershell.py +1 -0
  545. ansible_test/_internal/classification/python.py +1 -0
  546. ansible_test/_internal/cli/__init__.py +1 -0
  547. ansible_test/_internal/cli/actions.py +1 -0
  548. ansible_test/_internal/cli/argparsing/__init__.py +1 -0
  549. ansible_test/_internal/cli/argparsing/actions.py +1 -0
  550. ansible_test/_internal/cli/argparsing/argcompletion.py +1 -0
  551. ansible_test/_internal/cli/argparsing/parsers.py +1 -0
  552. ansible_test/_internal/cli/commands/__init__.py +11 -5
  553. ansible_test/_internal/cli/commands/coverage/__init__.py +1 -0
  554. ansible_test/_internal/cli/commands/coverage/analyze/__init__.py +1 -0
  555. ansible_test/_internal/cli/commands/coverage/analyze/targets/__init__.py +1 -0
  556. ansible_test/_internal/cli/commands/coverage/analyze/targets/combine.py +1 -0
  557. ansible_test/_internal/cli/commands/coverage/analyze/targets/expand.py +1 -0
  558. ansible_test/_internal/cli/commands/coverage/analyze/targets/filter.py +1 -0
  559. ansible_test/_internal/cli/commands/coverage/analyze/targets/generate.py +1 -0
  560. ansible_test/_internal/cli/commands/coverage/analyze/targets/missing.py +1 -0
  561. ansible_test/_internal/cli/commands/coverage/combine.py +1 -0
  562. ansible_test/_internal/cli/commands/coverage/erase.py +1 -0
  563. ansible_test/_internal/cli/commands/coverage/html.py +1 -0
  564. ansible_test/_internal/cli/commands/coverage/report.py +1 -0
  565. ansible_test/_internal/cli/commands/coverage/xml.py +1 -0
  566. ansible_test/_internal/cli/commands/env.py +1 -0
  567. ansible_test/_internal/cli/commands/integration/__init__.py +1 -0
  568. ansible_test/_internal/cli/commands/integration/network.py +1 -0
  569. ansible_test/_internal/cli/commands/integration/posix.py +1 -0
  570. ansible_test/_internal/cli/commands/integration/windows.py +1 -0
  571. ansible_test/_internal/cli/commands/sanity.py +9 -0
  572. ansible_test/_internal/cli/commands/shell.py +1 -0
  573. ansible_test/_internal/cli/commands/units.py +1 -0
  574. ansible_test/_internal/cli/compat.py +1 -0
  575. ansible_test/_internal/cli/completers.py +1 -0
  576. ansible_test/_internal/cli/converters.py +1 -0
  577. ansible_test/_internal/cli/environments.py +52 -5
  578. ansible_test/_internal/cli/epilog.py +1 -0
  579. ansible_test/_internal/cli/parsers/__init__.py +1 -0
  580. ansible_test/_internal/cli/parsers/base_argument_parsers.py +1 -0
  581. ansible_test/_internal/cli/parsers/helpers.py +1 -0
  582. ansible_test/_internal/cli/parsers/host_config_parsers.py +1 -0
  583. ansible_test/_internal/cli/parsers/key_value_parsers.py +1 -0
  584. ansible_test/_internal/cli/parsers/value_parsers.py +1 -0
  585. ansible_test/_internal/commands/__init__.py +1 -0
  586. ansible_test/_internal/commands/coverage/__init__.py +3 -2
  587. ansible_test/_internal/commands/coverage/analyze/__init__.py +1 -0
  588. ansible_test/_internal/commands/coverage/analyze/targets/__init__.py +1 -0
  589. ansible_test/_internal/commands/coverage/analyze/targets/combine.py +1 -0
  590. ansible_test/_internal/commands/coverage/analyze/targets/expand.py +1 -0
  591. ansible_test/_internal/commands/coverage/analyze/targets/filter.py +1 -0
  592. ansible_test/_internal/commands/coverage/analyze/targets/generate.py +1 -0
  593. ansible_test/_internal/commands/coverage/analyze/targets/missing.py +1 -0
  594. ansible_test/_internal/commands/coverage/combine.py +2 -1
  595. ansible_test/_internal/commands/coverage/erase.py +1 -0
  596. ansible_test/_internal/commands/coverage/html.py +1 -0
  597. ansible_test/_internal/commands/coverage/report.py +1 -0
  598. ansible_test/_internal/commands/coverage/xml.py +1 -0
  599. ansible_test/_internal/commands/env/__init__.py +2 -0
  600. ansible_test/_internal/commands/integration/__init__.py +22 -5
  601. ansible_test/_internal/commands/integration/cloud/__init__.py +1 -0
  602. ansible_test/_internal/commands/integration/cloud/acme.py +2 -1
  603. ansible_test/_internal/commands/integration/cloud/aws.py +1 -0
  604. ansible_test/_internal/commands/integration/cloud/azure.py +1 -0
  605. ansible_test/_internal/commands/integration/cloud/cs.py +1 -0
  606. ansible_test/_internal/commands/integration/cloud/digitalocean.py +1 -0
  607. ansible_test/_internal/commands/integration/cloud/galaxy.py +3 -2
  608. ansible_test/_internal/commands/integration/cloud/hcloud.py +1 -0
  609. ansible_test/_internal/commands/integration/cloud/httptester.py +3 -2
  610. ansible_test/_internal/commands/integration/cloud/nios.py +2 -1
  611. ansible_test/_internal/commands/integration/cloud/opennebula.py +1 -0
  612. ansible_test/_internal/commands/integration/cloud/openshift.py +1 -0
  613. ansible_test/_internal/commands/integration/cloud/scaleway.py +1 -0
  614. ansible_test/_internal/commands/integration/cloud/vcenter.py +1 -0
  615. ansible_test/_internal/commands/integration/cloud/vultr.py +1 -0
  616. ansible_test/_internal/commands/integration/coverage.py +8 -2
  617. ansible_test/_internal/commands/integration/filters.py +1 -0
  618. ansible_test/_internal/commands/integration/network.py +1 -0
  619. ansible_test/_internal/commands/integration/posix.py +1 -0
  620. ansible_test/_internal/commands/integration/windows.py +1 -0
  621. ansible_test/_internal/commands/sanity/__init__.py +19 -2
  622. ansible_test/_internal/commands/sanity/ansible_doc.py +1 -0
  623. ansible_test/_internal/commands/sanity/bin_symlinks.py +1 -0
  624. ansible_test/_internal/commands/sanity/compile.py +1 -0
  625. ansible_test/_internal/commands/sanity/ignores.py +1 -0
  626. ansible_test/_internal/commands/sanity/import.py +1 -0
  627. ansible_test/_internal/commands/sanity/integration_aliases.py +12 -0
  628. ansible_test/_internal/commands/sanity/pep8.py +1 -0
  629. ansible_test/_internal/commands/sanity/pslint.py +1 -0
  630. ansible_test/_internal/commands/sanity/pylint.py +25 -26
  631. ansible_test/_internal/commands/sanity/shellcheck.py +1 -0
  632. ansible_test/_internal/commands/sanity/validate_modules.py +1 -0
  633. ansible_test/_internal/commands/sanity/yamllint.py +1 -0
  634. ansible_test/_internal/commands/shell/__init__.py +44 -4
  635. ansible_test/_internal/commands/units/__init__.py +5 -1
  636. ansible_test/_internal/compat/__init__.py +1 -0
  637. ansible_test/_internal/compat/packaging.py +1 -0
  638. ansible_test/_internal/compat/yaml.py +1 -0
  639. ansible_test/_internal/completion.py +1 -0
  640. ansible_test/_internal/config.py +23 -13
  641. ansible_test/_internal/connections.py +1 -0
  642. ansible_test/_internal/constants.py +1 -0
  643. ansible_test/_internal/containers.py +1 -0
  644. ansible_test/_internal/content_config.py +1 -0
  645. ansible_test/_internal/core_ci.py +1 -0
  646. ansible_test/_internal/coverage_util.py +11 -10
  647. ansible_test/_internal/data.py +1 -0
  648. ansible_test/_internal/debugging.py +166 -0
  649. ansible_test/_internal/delegation.py +22 -13
  650. ansible_test/_internal/dev/__init__.py +1 -0
  651. ansible_test/_internal/dev/container_probe.py +1 -0
  652. ansible_test/_internal/diff.py +3 -2
  653. ansible_test/_internal/docker_util.py +2 -1
  654. ansible_test/_internal/encoding.py +1 -0
  655. ansible_test/_internal/executor.py +1 -0
  656. ansible_test/_internal/git.py +1 -0
  657. ansible_test/_internal/host_configs.py +1 -0
  658. ansible_test/_internal/host_profiles.py +260 -16
  659. ansible_test/_internal/http.py +1 -0
  660. ansible_test/_internal/init.py +1 -0
  661. ansible_test/_internal/inventory.py +39 -3
  662. ansible_test/_internal/io.py +1 -0
  663. ansible_test/_internal/metadata.py +95 -4
  664. ansible_test/_internal/payload.py +1 -0
  665. ansible_test/_internal/processes.py +80 -0
  666. ansible_test/_internal/provider/__init__.py +1 -0
  667. ansible_test/_internal/provider/layout/__init__.py +1 -0
  668. ansible_test/_internal/provider/layout/ansible.py +1 -0
  669. ansible_test/_internal/provider/layout/collection.py +1 -0
  670. ansible_test/_internal/provider/layout/unsupported.py +1 -0
  671. ansible_test/_internal/provider/source/__init__.py +1 -0
  672. ansible_test/_internal/provider/source/git.py +1 -0
  673. ansible_test/_internal/provider/source/installed.py +1 -0
  674. ansible_test/_internal/provider/source/unsupported.py +1 -0
  675. ansible_test/_internal/provider/source/unversioned.py +1 -0
  676. ansible_test/_internal/provisioning.py +11 -4
  677. ansible_test/_internal/pypi_proxy.py +6 -5
  678. ansible_test/_internal/python_requirements.py +28 -0
  679. ansible_test/_internal/ssh.py +2 -5
  680. ansible_test/_internal/target.py +9 -0
  681. ansible_test/_internal/test.py +3 -2
  682. ansible_test/_internal/thread.py +3 -1
  683. ansible_test/_internal/timeout.py +2 -1
  684. ansible_test/_internal/util.py +41 -12
  685. ansible_test/_internal/util_common.py +18 -5
  686. ansible_test/_internal/venv.py +1 -0
  687. ansible_test/_util/controller/sanity/code-smell/action-plugin-docs.py +1 -0
  688. ansible_test/_util/controller/sanity/code-smell/changelog/sphinx.py +1 -0
  689. ansible_test/_util/controller/sanity/code-smell/changelog.py +1 -0
  690. ansible_test/_util/controller/sanity/code-smell/empty-init.py +1 -0
  691. ansible_test/_util/controller/sanity/code-smell/line-endings.py +1 -0
  692. ansible_test/_util/controller/sanity/code-smell/no-assert.py +1 -0
  693. ansible_test/_util/controller/sanity/code-smell/no-get-exception.py +1 -0
  694. ansible_test/_util/controller/sanity/code-smell/no-illegal-filenames.py +1 -0
  695. ansible_test/_util/controller/sanity/code-smell/no-smart-quotes.py +1 -0
  696. ansible_test/_util/controller/sanity/code-smell/replace-urlopen.py +1 -0
  697. ansible_test/_util/controller/sanity/code-smell/runtime-metadata.py +28 -1
  698. ansible_test/_util/controller/sanity/code-smell/shebang.py +1 -0
  699. ansible_test/_util/controller/sanity/code-smell/symlinks.py +1 -0
  700. ansible_test/_util/controller/sanity/code-smell/use-argspec-type-path.py +1 -0
  701. ansible_test/_util/controller/sanity/code-smell/use-compat-six.py +1 -0
  702. ansible_test/_util/controller/sanity/integration-aliases/yaml_to_json.py +2 -1
  703. ansible_test/_util/controller/sanity/pep8/current-ignore.txt +4 -0
  704. ansible_test/_util/controller/sanity/pylint/config/ansible-test-target.cfg +8 -5
  705. ansible_test/_util/controller/sanity/pylint/config/ansible-test.cfg +8 -5
  706. ansible_test/_util/controller/sanity/pylint/config/code-smell.cfg +8 -5
  707. ansible_test/_util/controller/sanity/pylint/config/collection.cfg +4 -5
  708. ansible_test/_util/controller/sanity/pylint/config/default.cfg +8 -7
  709. ansible_test/_util/controller/sanity/pylint/plugins/deprecated_calls.py +541 -0
  710. ansible_test/_util/controller/sanity/pylint/plugins/deprecated_comment.py +137 -0
  711. ansible_test/_util/controller/sanity/pylint/plugins/hide_unraisable.py +1 -0
  712. ansible_test/_util/controller/sanity/pylint/plugins/string_format.py +1 -8
  713. ansible_test/_util/controller/sanity/pylint/plugins/unwanted.py +1 -8
  714. ansible_test/_util/controller/sanity/validate-modules/validate_modules/main.py +55 -28
  715. ansible_test/_util/controller/sanity/validate-modules/validate_modules/module_args.py +12 -5
  716. ansible_test/_util/controller/sanity/validate-modules/validate_modules/schema.py +13 -2
  717. ansible_test/_util/controller/sanity/validate-modules/validate_modules/utils.py +1 -0
  718. ansible_test/_util/controller/sanity/yamllint/yamllinter.py +35 -17
  719. ansible_test/_util/controller/tools/collection_detail.py +1 -0
  720. ansible_test/_util/controller/tools/yaml_to_json.py +2 -1
  721. ansible_test/_util/target/injector/python.py +8 -0
  722. ansible_test/_util/target/pytest/plugins/ansible_forked.py +6 -1
  723. ansible_test/_util/target/pytest/plugins/ansible_pytest_collections.py +2 -1
  724. ansible_test/_util/target/pytest/plugins/ansible_pytest_coverage.py +1 -0
  725. ansible_test/_util/target/sanity/compile/compile.py +1 -0
  726. ansible_test/_util/target/sanity/import/importer.py +15 -16
  727. ansible_test/_util/target/setup/bootstrap.sh +9 -20
  728. ansible_test/_util/target/setup/probe_cgroups.py +1 -0
  729. ansible_test/_util/target/setup/quiet_pip.py +1 -0
  730. ansible_test/_util/target/setup/requirements.py +38 -36
  731. ansible_test/_util/target/tools/virtualenvcheck.py +2 -1
  732. ansible_test/_util/target/tools/yamlcheck.py +2 -1
  733. ansible/compat/selectors.py +0 -32
  734. ansible/errors/yaml_strings.py +0 -138
  735. ansible/executor/action_write_locks.py +0 -44
  736. ansible/executor/discovery/python_target.py +0 -47
  737. ansible/executor/powershell/module_powershell_wrapper.ps1 +0 -86
  738. ansible/executor/powershell/module_script_wrapper.ps1 +0 -22
  739. ansible/module_utils/compat/importlib.py +0 -26
  740. ansible/module_utils/compat/selectors.py +0 -32
  741. ansible/module_utils/pycompat24.py +0 -73
  742. ansible/parsing/yaml/constructor.py +0 -178
  743. ansible/template/native_helpers.py +0 -251
  744. ansible/template/template.py +0 -43
  745. ansible/template/vars.py +0 -77
  746. ansible/utils/native_jinja.py +0 -11
  747. ansible/vars/fact_cache.py +0 -71
  748. ansible_core-2.18.7.dist-info/RECORD +0 -992
  749. ansible_test/_util/controller/sanity/pylint/plugins/deprecated.py +0 -411
  750. {ansible_core-2.18.7.dist-info → ansible_core-2.19.0.dist-info}/WHEEL +0 -0
  751. {ansible_core-2.18.7.dist-info → ansible_core-2.19.0.dist-info}/entry_points.txt +0 -0
  752. {ansible_core-2.18.7.dist-info → ansible_core-2.19.0.dist-info}/licenses/COPYING +0 -0
  753. {ansible_core-2.18.7.dist-info → ansible_core-2.19.0.dist-info}/licenses/licenses/Apache-License.txt +0 -0
  754. {ansible_core-2.18.7.dist-info → ansible_core-2.19.0.dist-info}/licenses/licenses/MIT-license.txt +0 -0
  755. {ansible_core-2.18.7.dist-info → ansible_core-2.19.0.dist-info}/licenses/licenses/PSF-license.txt +0 -0
  756. {ansible_core-2.18.7.dist-info → ansible_core-2.19.0.dist-info}/licenses/licenses/simplified_bsd.txt +0 -0
  757. {ansible_core-2.18.7.dist-info → ansible_core-2.19.0.dist-info}/top_level.txt +0 -0
ansible/config/manager.py CHANGED
@@ -6,28 +6,28 @@ from __future__ import annotations
6
6
  import atexit
7
7
  import decimal
8
8
  import configparser
9
+ import functools
9
10
  import os
10
11
  import os.path
11
12
  import sys
12
13
  import stat
13
14
  import tempfile
15
+ import typing as t
14
16
 
15
- from collections import namedtuple
16
17
  from collections.abc import Mapping, Sequence
17
18
  from jinja2.nativetypes import NativeEnvironment
18
19
 
19
- from ansible.errors import AnsibleOptionsError, AnsibleError, AnsibleRequiredOptionError
20
+ from ansible._internal._datatag import _tags
21
+ from ansible.errors import AnsibleOptionsError, AnsibleError, AnsibleUndefinedConfigEntry, AnsibleRequiredOptionError
22
+ from ansible.module_utils._internal._datatag import AnsibleTagHelper
23
+ from ansible.module_utils.common.sentinel import Sentinel
20
24
  from ansible.module_utils.common.text.converters import to_text, to_bytes, to_native
21
25
  from ansible.module_utils.common.yaml import yaml_load
22
- from ansible.module_utils.six import string_types
23
26
  from ansible.module_utils.parsing.convert_bool import boolean
24
27
  from ansible.parsing.quoting import unquote
25
- from ansible.parsing.yaml.objects import AnsibleVaultEncryptedUnicode
26
28
  from ansible.utils.path import cleanup_tmp_file, makedirs_safe, unfrackpath
27
29
 
28
30
 
29
- Setting = namedtuple('Setting', 'name value origin type')
30
-
31
31
  INTERNAL_DEFS = {'lookup': ('_terms',)}
32
32
 
33
33
  GALAXY_SERVER_DEF = [
@@ -39,6 +39,7 @@ GALAXY_SERVER_DEF = [
39
39
  ('api_version', False, 'int'),
40
40
  ('validate_certs', False, 'bool'),
41
41
  ('client_id', False, 'str'),
42
+ ('client_secret', False, 'str'),
42
43
  ('timeout', False, 'int'),
43
44
  ]
44
45
 
@@ -51,145 +52,181 @@ GALAXY_SERVER_ADDITIONAL = {
51
52
  }
52
53
 
53
54
 
54
- def _get_entry(plugin_type, plugin_name, config):
55
- ''' construct entry for requested config '''
56
- entry = ''
55
+ @t.runtime_checkable
56
+ class _EncryptedStringProtocol(t.Protocol):
57
+ """Protocol representing an `EncryptedString`, since it cannot be imported here."""
58
+ # DTFIX-FUTURE: collapse this with the one in collection loader, once we can
59
+
60
+ def _decrypt(self) -> str: ...
61
+
62
+
63
+ def _get_config_label(plugin_type: str, plugin_name: str, config: str) -> str:
64
+ """Return a label for the given config."""
65
+ entry = f'{config!r}'
66
+
57
67
  if plugin_type:
58
- entry += 'plugin_type: %s ' % plugin_type
68
+ entry += ' for'
69
+
59
70
  if plugin_name:
60
- entry += 'plugin: %s ' % plugin_name
61
- entry += 'setting: %s ' % config
71
+ entry += f' {plugin_name!r}'
72
+
73
+ entry += f' {plugin_type} plugin'
74
+
62
75
  return entry
63
76
 
64
77
 
65
- # FIXME: see if we can unify in module_utils with similar function used by argspec
66
- def ensure_type(value, value_type, origin=None, origin_ftype=None):
67
- ''' return a configuration variable with casting
68
- :arg value: The value to ensure correct typing of
69
- :kwarg value_type: The type of the value. This can be any of the following strings:
70
- :boolean: sets the value to a True or False value
71
- :bool: Same as 'boolean'
72
- :integer: Sets the value to an integer or raises a ValueType error
73
- :int: Same as 'integer'
74
- :float: Sets the value to a float or raises a ValueType error
75
- :list: Treats the value as a comma separated list. Split the value
76
- and return it as a python list.
77
- :none: Sets the value to None
78
- :path: Expands any environment variables and tilde's in the value.
79
- :tmppath: Create a unique temporary directory inside of the directory
80
- specified by value and return its path.
81
- :temppath: Same as 'tmppath'
82
- :tmp: Same as 'tmppath'
83
- :pathlist: Treat the value as a typical PATH string. (On POSIX, this
84
- means comma separated strings.) Split the value and then expand
85
- each part for environment variables and tildes.
86
- :pathspec: Treat the value as a PATH string. Expands any environment variables
87
- tildes's in the value.
88
- :str: Sets the value to string types.
89
- :string: Same as 'str'
90
- '''
91
-
92
- errmsg = ''
93
- basedir = None
94
- if origin and os.path.isabs(origin) and os.path.exists(to_bytes(origin)):
95
- basedir = origin
78
+ def ensure_type(value: object, value_type: str | None, origin: str | None = None, origin_ftype: str | None = None) -> t.Any:
79
+ """
80
+ Converts `value` to the requested `value_type`; raises `ValueError` for failed conversions.
81
+
82
+ Values for `value_type` are:
83
+
84
+ * boolean/bool: Return a `bool` by applying non-strict `bool` filter rules:
85
+ 'y', 'yes', 'on', '1', 'true', 't', 1, 1.0, True return True, any other value is False.
86
+ * integer/int: Return an `int`. Accepts any `str` parseable by `int` or numeric value with a zero mantissa (including `bool`).
87
+ * float: Return a `float`. Accepts any `str` parseable by `float` or numeric value (including `bool`).
88
+ * list: Return a `list`. Accepts `list` or `Sequence`. Also accepts, `str`, splitting on ',' while stripping whitespace and unquoting items.
89
+ * none: Return `None`. Accepts only the string "None".
90
+ * path: Return a resolved path. Accepts `str`.
91
+ * temppath/tmppath/tmp: Return a unique temporary directory inside the resolved path specified by the value.
92
+ * pathspec: Return a `list` of resolved paths. Accepts a `list` or `Sequence`. Also accepts `str`, splitting on ':'.
93
+ * pathlist: Return a `list` of resolved paths. Accepts a `list` or `Sequence`. Also accepts `str`, splitting on `,` while stripping whitespace from paths.
94
+ * dictionary/dict: Return a `dict`. Accepts `dict` or `Mapping`.
95
+ * string/str: Return a `str`. Accepts `bool`, `int`, `float`, `complex` or `str`.
96
+
97
+ Path resolution ensures paths are `str` with expansion of '{{CWD}}', environment variables and '~'.
98
+ Non-absolute paths are expanded relative to the basedir from `origin`, if specified.
99
+
100
+ No conversion is performed if `value_type` is unknown or `value` is `None`.
101
+ When `origin_ftype` is "ini", a `str` result will be unquoted.
102
+ """
103
+
104
+ if value is None:
105
+ return None
106
+
107
+ original_value = value
108
+ copy_tags = value_type not in ('temppath', 'tmppath', 'tmp')
109
+
110
+ value = _ensure_type(value, value_type, origin)
111
+
112
+ if copy_tags and value is not original_value:
113
+ if isinstance(value, list):
114
+ value = [AnsibleTagHelper.tag_copy(original_value, item) for item in value]
115
+
116
+ value = AnsibleTagHelper.tag_copy(original_value, value)
117
+
118
+ if isinstance(value, str) and origin_ftype and origin_ftype == 'ini':
119
+ value = unquote(value)
120
+
121
+ return value
122
+
123
+
124
+ def _ensure_type(value: object, value_type: str | None, origin: str | None = None) -> t.Any:
125
+ """Internal implementation for `ensure_type`, call that function instead."""
126
+ original_value = value
127
+ basedir = origin if origin and os.path.isabs(origin) and os.path.exists(to_bytes(origin)) else None
96
128
 
97
129
  if value_type:
98
130
  value_type = value_type.lower()
99
131
 
100
- if value is not None:
101
- if value_type in ('boolean', 'bool'):
102
- value = boolean(value, strict=False)
132
+ match value_type:
133
+ case 'boolean' | 'bool':
134
+ return boolean(value, strict=False)
103
135
 
104
- elif value_type in ('integer', 'int'):
105
- if not isinstance(value, int):
136
+ case 'integer' | 'int':
137
+ if isinstance(value, int): # handle both int and bool (which is an int)
138
+ return int(value)
139
+
140
+ if isinstance(value, (float, str)):
106
141
  try:
142
+ # use Decimal for all other source type conversions; non-zero mantissa is a failure
107
143
  if (decimal_value := decimal.Decimal(value)) == (int_part := int(decimal_value)):
108
- value = int_part
109
- else:
110
- errmsg = 'int'
111
- except decimal.DecimalException as e:
112
- raise ValueError from e
144
+ return int_part
145
+ except (decimal.DecimalException, ValueError):
146
+ pass
113
147
 
114
- elif value_type == 'float':
115
- if not isinstance(value, float):
116
- value = float(value)
148
+ case 'float':
149
+ if isinstance(value, float):
150
+ return value
117
151
 
118
- elif value_type == 'list':
119
- if isinstance(value, string_types):
120
- value = [unquote(x.strip()) for x in value.split(',')]
121
- elif not isinstance(value, Sequence):
122
- errmsg = 'list'
152
+ if isinstance(value, (int, str)):
153
+ try:
154
+ return float(value)
155
+ except ValueError:
156
+ pass
157
+
158
+ case 'list':
159
+ if isinstance(value, list):
160
+ return value
161
+
162
+ if isinstance(value, str):
163
+ return [unquote(x.strip()) for x in value.split(',')]
164
+
165
+ if isinstance(value, Sequence) and not isinstance(value, bytes):
166
+ return list(value)
123
167
 
124
- elif value_type == 'none':
168
+ case 'none':
125
169
  if value == "None":
126
- value = None
170
+ return None
127
171
 
128
- if value is not None:
129
- errmsg = 'None'
172
+ case 'path':
173
+ if isinstance(value, str):
174
+ return resolve_path(value, basedir=basedir)
130
175
 
131
- elif value_type == 'path':
132
- if isinstance(value, string_types):
176
+ case 'temppath' | 'tmppath' | 'tmp':
177
+ if isinstance(value, str):
133
178
  value = resolve_path(value, basedir=basedir)
134
- else:
135
- errmsg = 'path'
136
179
 
137
- elif value_type in ('tmp', 'temppath', 'tmppath'):
138
- if isinstance(value, string_types):
139
- value = resolve_path(value, basedir=basedir)
140
180
  if not os.path.exists(value):
141
181
  makedirs_safe(value, 0o700)
182
+
142
183
  prefix = 'ansible-local-%s' % os.getpid()
143
184
  value = tempfile.mkdtemp(prefix=prefix, dir=value)
144
185
  atexit.register(cleanup_tmp_file, value, warn=True)
145
- else:
146
- errmsg = 'temppath'
147
186
 
148
- elif value_type == 'pathspec':
149
- if isinstance(value, string_types):
187
+ return value
188
+
189
+ case 'pathspec':
190
+ if isinstance(value, str):
150
191
  value = value.split(os.pathsep)
151
192
 
152
- if isinstance(value, Sequence):
153
- value = [resolve_path(x, basedir=basedir) for x in value]
154
- else:
155
- errmsg = 'pathspec'
193
+ if isinstance(value, Sequence) and not isinstance(value, bytes) and all(isinstance(x, str) for x in value):
194
+ return [resolve_path(x, basedir=basedir) for x in value]
156
195
 
157
- elif value_type == 'pathlist':
158
- if isinstance(value, string_types):
196
+ case 'pathlist':
197
+ if isinstance(value, str):
159
198
  value = [x.strip() for x in value.split(',')]
160
199
 
161
- if isinstance(value, Sequence):
162
- value = [resolve_path(x, basedir=basedir) for x in value]
163
- else:
164
- errmsg = 'pathlist'
200
+ if isinstance(value, Sequence) and not isinstance(value, bytes) and all(isinstance(x, str) for x in value):
201
+ return [resolve_path(x, basedir=basedir) for x in value]
165
202
 
166
- elif value_type in ('dict', 'dictionary'):
167
- if not isinstance(value, Mapping):
168
- errmsg = 'dictionary'
203
+ case 'dictionary' | 'dict':
204
+ if isinstance(value, dict):
205
+ return value
169
206
 
170
- elif value_type in ('str', 'string'):
171
- if isinstance(value, (string_types, AnsibleVaultEncryptedUnicode, bool, int, float, complex)):
172
- value = to_text(value, errors='surrogate_or_strict')
173
- if origin_ftype and origin_ftype == 'ini':
174
- value = unquote(value)
175
- else:
176
- errmsg = 'string'
207
+ if isinstance(value, Mapping):
208
+ return dict(value)
209
+
210
+ case 'string' | 'str':
211
+ if isinstance(value, str):
212
+ return value
177
213
 
178
- # defaults to string type
179
- elif isinstance(value, (string_types, AnsibleVaultEncryptedUnicode)):
180
- value = to_text(value, errors='surrogate_or_strict')
181
- if origin_ftype and origin_ftype == 'ini':
182
- value = unquote(value)
214
+ if isinstance(value, (bool, int, float, complex)):
215
+ return str(value)
183
216
 
184
- if errmsg:
185
- raise ValueError(f'Invalid type provided for "{errmsg}": {value!r}')
217
+ if isinstance(value, _EncryptedStringProtocol):
218
+ return value._decrypt()
186
219
 
187
- return to_text(value, errors='surrogate_or_strict', nonstring='passthru')
220
+ case _:
221
+ # FIXME: define and document a pass-through value_type (None, 'raw', 'object', '', ...) and then deprecate acceptance of unknown types
222
+ return value # return non-str values of unknown value_type as-is
223
+
224
+ raise ValueError(f'Invalid value provided for {value_type!r}: {original_value!r}')
188
225
 
189
226
 
190
227
  # FIXME: see if this can live in utils/path
191
- def resolve_path(path, basedir=None):
192
- ''' resolve relative or 'variable' paths '''
228
+ def resolve_path(path: str, basedir: str | None = None) -> str:
229
+ """ resolve relative or 'variable' paths """
193
230
  if '{{CWD}}' in path: # allow users to force CWD using 'magic' {{CWD}}
194
231
  path = path.replace('{{CWD}}', os.getcwd())
195
232
 
@@ -212,35 +249,21 @@ def get_config_type(cfile):
212
249
  return ftype
213
250
 
214
251
 
215
- # FIXME: can move to module_utils for use for ini plugins also?
216
- def get_ini_config_value(p, entry):
217
- ''' returns the value of last ini entry found '''
218
- value = None
219
- if p is not None:
220
- try:
221
- value = p.get(entry.get('section', 'defaults'), entry.get('key', ''), raw=True)
222
- except Exception: # FIXME: actually report issues here
223
- pass
224
- return value
225
-
226
-
227
252
  def find_ini_config_file(warnings=None):
228
- ''' Load INI Config File order(first found is used): ENV, CWD, HOME, /etc/ansible '''
253
+ """ Load INI Config File order(first found is used): ENV, CWD, HOME, /etc/ansible """
229
254
  # FIXME: eventually deprecate ini configs
230
255
 
231
256
  if warnings is None:
232
257
  # Note: In this case, warnings does nothing
233
258
  warnings = set()
234
259
 
235
- # A value that can never be a valid path so that we can tell if ANSIBLE_CONFIG was set later
236
- # We can't use None because we could set path to None.
237
- SENTINEL = object
238
-
239
260
  potential_paths = []
240
261
 
262
+ # A value that can never be a valid path so that we can tell if ANSIBLE_CONFIG was set later
263
+ # We can't use None because we could set path to None.
241
264
  # Environment setting
242
- path_from_env = os.getenv("ANSIBLE_CONFIG", SENTINEL)
243
- if path_from_env is not SENTINEL:
265
+ path_from_env = os.getenv("ANSIBLE_CONFIG", Sentinel)
266
+ if path_from_env is not Sentinel:
244
267
  path_from_env = unfrackpath(path_from_env, follow=False)
245
268
  if os.path.isdir(to_bytes(path_from_env)):
246
269
  path_from_env = os.path.join(path_from_env, "ansible.cfg")
@@ -290,7 +313,7 @@ def find_ini_config_file(warnings=None):
290
313
 
291
314
 
292
315
  def _add_base_defs_deprecations(base_defs):
293
- '''Add deprecation source 'ansible.builtin' to deprecations in base.yml'''
316
+ """Add deprecation source 'ansible.builtin' to deprecations in base.yml"""
294
317
  def process(entry):
295
318
  if 'deprecated' in entry:
296
319
  entry['deprecated']['collection_name'] = 'ansible.builtin'
@@ -303,12 +326,15 @@ def _add_base_defs_deprecations(base_defs):
303
326
  process(entry)
304
327
 
305
328
 
306
- class ConfigManager(object):
329
+ class ConfigManager:
307
330
 
308
331
  DEPRECATED = [] # type: list[tuple[str, dict[str, str]]]
309
332
  WARNINGS = set() # type: set[str]
310
333
 
334
+ _errors: list[tuple[str, Exception]]
335
+
311
336
  def __init__(self, conf_file=None, defs_file=None):
337
+ self._get_ini_config_value = functools.cache(self._get_ini_config_value)
312
338
 
313
339
  self._base_defs = {}
314
340
  self._plugins = {}
@@ -328,6 +354,9 @@ class ConfigManager(object):
328
354
  # initialize parser and read config
329
355
  self._parse_config_file()
330
356
 
357
+ self._errors = []
358
+ """Deferred errors that will be turned into warnings."""
359
+
331
360
  # ensure we always have config def entry
332
361
  self._base_defs['CONFIG_FILE'] = {'default': None, 'type': 'path'}
333
362
 
@@ -367,15 +396,16 @@ class ConfigManager(object):
367
396
  defs = dict((k, server_config_def(server_key, k, req, value_type)) for k, req, value_type in GALAXY_SERVER_DEF)
368
397
  self.initialize_plugin_configuration_definitions('galaxy_server', server_key, defs)
369
398
 
370
- def template_default(self, value, variables):
371
- if isinstance(value, string_types) and (value.startswith('{{') and value.endswith('}}')) and variables is not None:
399
+ def template_default(self, value, variables, key_name: str = '<unknown>'):
400
+ if isinstance(value, str) and (value.startswith('{{') and value.endswith('}}')) and variables is not None:
372
401
  # template default values if possible
373
402
  # NOTE: cannot use is_template due to circular dep
374
403
  try:
375
- t = NativeEnvironment().from_string(value)
376
- value = t.render(variables)
377
- except Exception:
378
- pass # not templatable
404
+ # FIXME: This really should be using an immutable sandboxed native environment, not just native environment
405
+ template = NativeEnvironment().from_string(value)
406
+ value = template.render(variables)
407
+ except Exception as ex:
408
+ self._errors.append((f'Failed to template default for config {key_name}.', ex))
379
409
  return value
380
410
 
381
411
  def _read_config_yaml_file(self, yml_file):
@@ -389,7 +419,7 @@ class ConfigManager(object):
389
419
  "Missing base YAML definition file (bad install?): %s" % to_native(yml_file))
390
420
 
391
421
  def _parse_config_file(self, cfile=None):
392
- ''' return flat configuration settings from file(s) '''
422
+ """ return flat configuration settings from file(s) """
393
423
  # TODO: take list of files with merge/nomerge
394
424
 
395
425
  if cfile is None:
@@ -416,7 +446,7 @@ class ConfigManager(object):
416
446
  raise AnsibleOptionsError("Unsupported configuration file type: %s" % to_native(ftype))
417
447
 
418
448
  def _find_yaml_config_files(self):
419
- ''' Load YAML Config Files in order, check merge flags, keep origin of settings'''
449
+ """ Load YAML Config Files in order, check merge flags, keep origin of settings"""
420
450
  pass
421
451
 
422
452
  def get_plugin_options(self, plugin_type, name, keys=None, variables=None, direct=None):
@@ -468,7 +498,7 @@ class ConfigManager(object):
468
498
  return has
469
499
 
470
500
  def get_configuration_definitions(self, plugin_type=None, name=None, ignore_private=False):
471
- ''' just list the possible settings, either base or for specific plugins or plugin '''
501
+ """ just list the possible settings, either base or for specific plugins or plugin """
472
502
 
473
503
  ret = {}
474
504
  if plugin_type is None:
@@ -478,14 +508,14 @@ class ConfigManager(object):
478
508
  else:
479
509
  ret = self._plugins.get(plugin_type, {}).get(name, {})
480
510
 
481
- if ignore_private:
511
+ if ignore_private: # ignore 'test' config entries, they should not change runtime behaviors
482
512
  for cdef in list(ret.keys()):
483
- if cdef.startswith('_'):
513
+ if cdef.startswith('_Z_'):
484
514
  del ret[cdef]
485
515
  return ret
486
516
 
487
517
  def _loop_entries(self, container, entry_list):
488
- ''' repeat code for value entry assignment '''
518
+ """ repeat code for value entry assignment """
489
519
 
490
520
  value = None
491
521
  origin = None
@@ -497,10 +527,6 @@ class ConfigManager(object):
497
527
  self.WARNINGS.add(u'value for config entry {0} contains invalid characters, ignoring...'.format(to_text(name)))
498
528
  continue
499
529
  if temp_value is not None: # only set if entry is defined in container
500
- # inline vault variables should be converted to a text string
501
- if isinstance(temp_value, AnsibleVaultEncryptedUnicode):
502
- temp_value = to_text(temp_value, errors='surrogate_or_strict')
503
-
504
530
  value = temp_value
505
531
  origin = name
506
532
 
@@ -511,19 +537,23 @@ class ConfigManager(object):
511
537
  return value, origin
512
538
 
513
539
  def get_config_value(self, config, cfile=None, plugin_type=None, plugin_name=None, keys=None, variables=None, direct=None):
514
- ''' wrapper '''
540
+ """ wrapper """
515
541
 
516
542
  try:
517
543
  value, _drop = self.get_config_value_and_origin(config, cfile=cfile, plugin_type=plugin_type, plugin_name=plugin_name,
518
544
  keys=keys, variables=variables, direct=direct)
519
545
  except AnsibleError:
520
546
  raise
521
- except Exception as e:
522
- raise AnsibleError("Unhandled exception when retrieving %s:\n%s" % (config, to_native(e)), orig_exc=e)
547
+ except Exception as ex:
548
+ raise AnsibleError(f"Unhandled exception when retrieving {config!r}.") from ex
523
549
  return value
524
550
 
551
+ def get_config_default(self, config: str, plugin_type: str | None = None, plugin_name: str | None = None) -> t.Any:
552
+ """Return the default value for the specified configuration."""
553
+ return self.get_configuration_definitions(plugin_type, plugin_name)[config]['default']
554
+
525
555
  def get_config_value_and_origin(self, config, cfile=None, plugin_type=None, plugin_name=None, keys=None, variables=None, direct=None):
526
- ''' Given a config key figure out the actual value and report on the origin of the settings '''
556
+ """ Given a config key figure out the actual value and report on the origin of the settings """
527
557
  if cfile is None:
528
558
  # use default config
529
559
  cfile = self._config_file
@@ -588,6 +618,7 @@ class ConfigManager(object):
588
618
  # env vars are next precedence
589
619
  if value is None and defs[config].get('env'):
590
620
  value, origin = self._loop_entries(os.environ, defs[config]['env'])
621
+ value = _tags.TrustedAsTemplate().tag(value)
591
622
  origin = 'env: %s' % origin
592
623
 
593
624
  # try config file entries next, if we have one
@@ -602,7 +633,7 @@ class ConfigManager(object):
602
633
  for entry in defs[config][ftype]:
603
634
  # load from config
604
635
  if ftype == 'ini':
605
- temp_value = get_ini_config_value(self._parsers[cfile], entry)
636
+ temp_value = self._get_ini_config_value(cfile, entry.get('section', 'defaults'), entry['key'])
606
637
  elif ftype == 'yaml':
607
638
  raise AnsibleError('YAML configuration type has not been implemented yet')
608
639
  else:
@@ -626,22 +657,21 @@ class ConfigManager(object):
626
657
  if value is None:
627
658
  if defs[config].get('required', False):
628
659
  if not plugin_type or config not in INTERNAL_DEFS.get(plugin_type, {}):
629
- raise AnsibleRequiredOptionError("No setting was provided for required configuration %s" %
630
- to_native(_get_entry(plugin_type, plugin_name, config)))
660
+ raise AnsibleRequiredOptionError(f"Required config {_get_config_label(plugin_type, plugin_name, config)} not provided.")
631
661
  else:
632
662
  origin = 'default'
633
- value = self.template_default(defs[config].get('default'), variables)
663
+ value = self.template_default(defs[config].get('default'), variables, key_name=_get_config_label(plugin_type, plugin_name, config))
664
+
634
665
  try:
635
666
  # ensure correct type, can raise exceptions on mismatched types
636
667
  value = ensure_type(value, defs[config].get('type'), origin=origin, origin_ftype=origin_ftype)
637
- except ValueError as e:
668
+ except ValueError as ex:
638
669
  if origin.startswith('env:') and value == '':
639
670
  # this is empty env var for non string so we can set to default
640
671
  origin = 'default'
641
672
  value = ensure_type(defs[config].get('default'), defs[config].get('type'), origin=origin, origin_ftype=origin_ftype)
642
673
  else:
643
- raise AnsibleOptionsError('Invalid type for configuration option %s (from %s): %s' %
644
- (to_native(_get_entry(plugin_type, plugin_name, config)).strip(), origin, to_native(e)))
674
+ raise AnsibleOptionsError(f'Config {_get_config_label(plugin_type, plugin_name, config)} from {origin!r} has an invalid value.') from ex
645
675
 
646
676
  # deal with restricted values
647
677
  if value is not None and 'choices' in defs[config] and defs[config]['choices'] is not None:
@@ -657,21 +687,24 @@ class ConfigManager(object):
657
687
 
658
688
  if isinstance(defs[config]['choices'], Mapping):
659
689
  valid = ', '.join([to_text(k) for k in defs[config]['choices'].keys()])
660
- elif isinstance(defs[config]['choices'], string_types):
690
+ elif isinstance(defs[config]['choices'], str):
661
691
  valid = defs[config]['choices']
662
692
  elif isinstance(defs[config]['choices'], Sequence):
663
693
  valid = ', '.join([to_text(c) for c in defs[config]['choices']])
664
694
  else:
665
695
  valid = defs[config]['choices']
666
696
 
667
- raise AnsibleOptionsError('Invalid value "%s" for configuration option "%s", valid values are: %s' %
668
- (value, to_native(_get_entry(plugin_type, plugin_name, config)), valid))
697
+ raise AnsibleOptionsError(f'Invalid value {value!r} for config {_get_config_label(plugin_type, plugin_name, config)}.',
698
+ help_text=f'Valid values are: {valid}')
669
699
 
670
700
  # deal with deprecation of the setting
671
701
  if 'deprecated' in defs[config] and origin != 'default':
672
702
  self.DEPRECATED.append((config, defs[config].get('deprecated')))
673
703
  else:
674
- raise AnsibleError('Requested entry (%s) was not defined in configuration.' % to_native(_get_entry(plugin_type, plugin_name, config)))
704
+ raise AnsibleUndefinedConfigEntry(f'No config definition exists for {_get_config_label(plugin_type, plugin_name, config)}.')
705
+
706
+ if not _tags.Origin.is_tagged_on(value):
707
+ value = _tags.Origin(description=f'<Config {origin}>').tag(value)
675
708
 
676
709
  return value, origin
677
710
 
@@ -682,13 +715,41 @@ class ConfigManager(object):
682
715
 
683
716
  self._plugins[plugin_type][name] = defs
684
717
 
718
+ def _get_ini_config_value(self, config_file: str, section: str, option: str) -> t.Any:
719
+ """
720
+ Fetch `option` from the specified `section`.
721
+ Returns `None` if the specified `section` or `option` are not present.
722
+ Origin and TrustedAsTemplate tags are applied to returned values.
723
+
724
+ CAUTION: Although INI sourced configuration values are trusted for templating, that does not automatically mean they will be templated.
725
+ It is up to the code consuming configuration values to apply templating if required.
726
+ """
727
+ parser = self._parsers[config_file]
728
+ value = parser.get(section, option, raw=True, fallback=None)
729
+
730
+ if value is not None:
731
+ value = self._apply_tags(value, section, option)
732
+
733
+ return value
734
+
735
+ def _apply_tags(self, value: str, section: str, option: str) -> t.Any:
736
+ """Apply origin and trust to the given `value` sourced from the stated `section` and `option`."""
737
+ description = f'section {section!r} option {option!r}'
738
+ origin = _tags.Origin(path=self._config_file, description=description)
739
+ tags = [origin, _tags.TrustedAsTemplate()]
740
+ value = AnsibleTagHelper.tag(value, tags)
741
+
742
+ return value
743
+
685
744
  @staticmethod
686
- def get_deprecated_msg_from_config(dep_docs, include_removal=False):
745
+ def get_deprecated_msg_from_config(dep_docs, include_removal=False, collection_name=None):
687
746
 
688
747
  removal = ''
689
748
  if include_removal:
690
749
  if 'removed_at_date' in dep_docs:
691
750
  removal = f"Will be removed in a release after {dep_docs['removed_at_date']}\n\t"
751
+ elif collection_name:
752
+ removal = f"Will be removed in: {collection_name} {dep_docs['removed_in']}\n\t"
692
753
  else:
693
754
  removal = f"Will be removed in: Ansible {dep_docs['removed_in']}\n\t"
694
755