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
ansible/modules/apt.py CHANGED
@@ -9,7 +9,7 @@
9
9
  from __future__ import annotations
10
10
 
11
11
 
12
- DOCUMENTATION = '''
12
+ DOCUMENTATION = """
13
13
  ---
14
14
  module: apt
15
15
  short_description: Manages apt-packages
@@ -17,6 +17,12 @@ description:
17
17
  - Manages I(apt) packages (such as for Debian/Ubuntu).
18
18
  version_added: "0.0.2"
19
19
  options:
20
+ auto_install_module_deps:
21
+ description:
22
+ - Automatically install dependencies required to run this module.
23
+ type: bool
24
+ default: yes
25
+ version_added: 2.19
20
26
  name:
21
27
  description:
22
28
  - A list of package names, like V(foo), or package specifier with version, like V(foo=1.0) or V(foo>=1.0).
@@ -191,8 +197,7 @@ options:
191
197
  default: 60
192
198
  version_added: "2.12"
193
199
  requirements:
194
- - python-apt (python 2)
195
- - python3-apt (python 3)
200
+ - python3-apt
196
201
  - aptitude (before 2.4)
197
202
  author: "Matthew Williams (@mgwilliams)"
198
203
  extends_documentation_fragment: action_common_attributes
@@ -214,12 +219,12 @@ notes:
214
219
  - When used with a C(loop:) each package will be processed individually, it is much more efficient to pass the list directly to the O(name) option.
215
220
  - When O(default_release) is used, an implicit priority of 990 is used. This is the same behavior as C(apt-get -t).
216
221
  - When an exact version is specified, an implicit priority of 1001 is used.
217
- - If the interpreter can't import C(python-apt)/C(python3-apt) the module will check for it in system-owned interpreters as well.
218
- If the dependency can't be found, the module will attempt to install it.
222
+ - If the interpreter can't import C(python3-apt) the module will check for it in system-owned interpreters as well.
223
+ If the dependency can't be found, depending on the value of O(auto_install_module_deps) the module will attempt to install it.
219
224
  If the dependency is found or installed, the module will be respawned under the correct interpreter.
220
- '''
225
+ """
221
226
 
222
- EXAMPLES = '''
227
+ EXAMPLES = """
223
228
  - name: Install apache httpd (state=present is optional)
224
229
  ansible.builtin.apt:
225
230
  name: apache2
@@ -327,9 +332,9 @@ EXAMPLES = '''
327
332
  - name: Run the equivalent of "apt-get clean" as a separate step
328
333
  ansible.builtin.apt:
329
334
  clean: yes
330
- '''
335
+ """
331
336
 
332
- RETURN = '''
337
+ RETURN = """
333
338
  cache_updated:
334
339
  description: if the cache was updated or not
335
340
  returned: success, in some cases
@@ -355,7 +360,7 @@ stderr:
355
360
  returned: success, when needed
356
361
  type: str
357
362
  sample: "AH00558: apache2: Could not reliably determine the server's fully qualified domain name, using 127.0.1.1. Set the 'ServerName' directive globally to ..."
358
- ''' # NOQA
363
+ """ # NOQA
359
364
 
360
365
  # added to stave off future warnings about apt api
361
366
  import warnings
@@ -483,7 +488,7 @@ class PolicyRcD(object):
483
488
 
484
489
 
485
490
  def package_split(pkgspec):
486
- parts = re.split(r'(>?=)', pkgspec, 1)
491
+ parts = re.split(r'(>?=)', pkgspec, maxsplit=1)
487
492
  if len(parts) > 1:
488
493
  return parts
489
494
  return parts[0], None, None
@@ -850,6 +855,7 @@ def install_deb(
850
855
  allow_downgrade,
851
856
  allow_change_held_packages,
852
857
  dpkg_options,
858
+ lock_timeout,
853
859
  ):
854
860
  changed = False
855
861
  deps_to_install = []
@@ -898,13 +904,14 @@ def install_deb(
898
904
  # install the deps through apt
899
905
  retvals = {}
900
906
  if deps_to_install:
907
+ install_dpkg_options = f"{expand_dpkg_options(dpkg_options)} -o DPkg::Lock::Timeout={lock_timeout}"
901
908
  (success, retvals) = install(m=m, pkgspec=deps_to_install, cache=cache,
902
909
  install_recommends=install_recommends,
903
910
  fail_on_autoremove=fail_on_autoremove,
904
911
  allow_unauthenticated=allow_unauthenticated,
905
912
  allow_downgrade=allow_downgrade,
906
913
  allow_change_held_packages=allow_change_held_packages,
907
- dpkg_options=expand_dpkg_options(dpkg_options))
914
+ dpkg_options=install_dpkg_options)
908
915
  if not success:
909
916
  m.fail_json(**retvals)
910
917
  changed = retvals.get('changed', False)
@@ -1184,7 +1191,7 @@ def get_updated_cache_time():
1184
1191
 
1185
1192
  # https://github.com/ansible/ansible-modules-core/issues/2951
1186
1193
  def get_cache(module):
1187
- '''Attempt to get the cache object and update till it works'''
1194
+ """Attempt to get the cache object and update till it works"""
1188
1195
  cache = None
1189
1196
  try:
1190
1197
  cache = apt.Cache()
@@ -1233,6 +1240,7 @@ def main():
1233
1240
  allow_downgrade=dict(type='bool', default=False, aliases=['allow-downgrade', 'allow_downgrades', 'allow-downgrades']),
1234
1241
  allow_change_held_packages=dict(type='bool', default=False),
1235
1242
  lock_timeout=dict(type='int', default=60),
1243
+ auto_install_module_deps=dict(type='bool', default=True),
1236
1244
  ),
1237
1245
  mutually_exclusive=[['deb', 'package', 'upgrade']],
1238
1246
  required_one_of=[['autoremove', 'deb', 'package', 'update_cache', 'upgrade']],
@@ -1263,12 +1271,12 @@ def main():
1263
1271
 
1264
1272
  p = module.params
1265
1273
  install_recommends = p['install_recommends']
1266
- dpkg_options = expand_dpkg_options(p['dpkg_options'])
1274
+ dpkg_options = f"{expand_dpkg_options(p['dpkg_options'])} -o DPkg::Lock::Timeout={p['lock_timeout']}"
1267
1275
 
1268
1276
  if not HAS_PYTHON_APT:
1269
1277
  # This interpreter can't see the apt Python library- we'll do the following to try and fix that:
1270
1278
  # 1) look in common locations for system-owned interpreters that can see it; if we find one, respawn under it
1271
- # 2) finding none, try to install a matching python-apt package for the current interpreter version;
1279
+ # 2) finding none, try to install a matching python3-apt package for the current interpreter version;
1272
1280
  # we limit to the current interpreter version to try and avoid installing a whole other Python just
1273
1281
  # for apt support
1274
1282
  # 3) if we installed a support package, try to respawn under what we think is the right interpreter (could be
@@ -1294,39 +1302,47 @@ def main():
1294
1302
 
1295
1303
  # don't make changes if we're in check_mode
1296
1304
  if module.check_mode:
1297
- module.fail_json(msg="%s must be installed to use check mode. "
1298
- "If run normally this module can auto-install it." % apt_pkg_name)
1299
-
1300
- # We skip cache update in auto install the dependency if the
1301
- # user explicitly declared it with update_cache=no.
1302
- if module.params.get('update_cache') is False:
1303
- module.warn("Auto-installing missing dependency without updating cache: %s" % apt_pkg_name)
1304
- else:
1305
- module.warn("Updating cache and auto-installing missing dependency: %s" % apt_pkg_name)
1306
- module.run_command([APT_GET_CMD, 'update'], check_rc=True)
1307
-
1308
- # try to install the apt Python binding
1309
- apt_pkg_cmd = [APT_GET_CMD, 'install', apt_pkg_name, '-y', '-q', dpkg_options]
1310
-
1311
- if install_recommends is False:
1312
- apt_pkg_cmd.extend(["-o", "APT::Install-Recommends=no"])
1313
- elif install_recommends is True:
1314
- apt_pkg_cmd.extend(["-o", "APT::Install-Recommends=yes"])
1315
- # install_recommends is None uses the OS default
1316
-
1317
- module.run_command(apt_pkg_cmd, check_rc=True)
1318
-
1319
- # try again to find the bindings in common places
1320
- interpreter = probe_interpreters_for_module(interpreters, 'apt')
1321
-
1322
- if interpreter:
1323
- # found the Python bindings; respawn this module under the interpreter where we found them
1324
- # NB: respawn is somewhat wasteful if it's this interpreter, but simplifies the code
1325
- respawn_module(interpreter)
1326
- # this is the end of the line for this process, it will exit here once the respawned module has completed
1327
- else:
1328
- # we've done all we can do; just tell the user it's busted and get out
1329
- module.fail_json(msg="{0} must be installed and visible from {1}.".format(apt_pkg_name, sys.executable))
1305
+ module.fail_json(
1306
+ msg=f"{apt_pkg_name} must be installed to use check mode. "
1307
+ "If run normally this module can auto-install it, "
1308
+ "see the auto_install_module_deps option.",
1309
+ )
1310
+ elif p['auto_install_module_deps']:
1311
+ # We skip cache update in auto install the dependency if the
1312
+ # user explicitly declared it with update_cache=no.
1313
+ if module.params.get('update_cache') is False:
1314
+ module.warn("Auto-installing missing dependency without updating cache: %s" % apt_pkg_name)
1315
+ else:
1316
+ module.warn("Updating cache and auto-installing missing dependency: %s" % apt_pkg_name)
1317
+ module.run_command([APT_GET_CMD, 'update'], check_rc=True)
1318
+
1319
+ # try to install the apt Python binding
1320
+ apt_pkg_cmd = [APT_GET_CMD, 'install', apt_pkg_name, '-y', '-q', dpkg_options]
1321
+
1322
+ if install_recommends is False:
1323
+ apt_pkg_cmd.extend(["-o", "APT::Install-Recommends=no"])
1324
+ elif install_recommends is True:
1325
+ apt_pkg_cmd.extend(["-o", "APT::Install-Recommends=yes"])
1326
+ # install_recommends is None uses the OS default
1327
+
1328
+ module.run_command(apt_pkg_cmd, check_rc=True)
1329
+
1330
+ # try again to find the bindings in common places
1331
+ interpreter = probe_interpreters_for_module(interpreters, 'apt')
1332
+
1333
+ if interpreter:
1334
+ # found the Python bindings; respawn this module under the interpreter where we found them
1335
+ # NB: respawn is somewhat wasteful if it's this interpreter, but simplifies the code
1336
+ respawn_module(interpreter)
1337
+ # this is the end of the line for this process, it will exit here once the respawned module has completed
1338
+
1339
+ # we've done all we can do; just tell the user it's busted and get out
1340
+ py_version = sys.version.replace("\n", "")
1341
+ module.fail_json(
1342
+ msg=f"Could not import the {apt_pkg_name} module using {sys.executable} ({py_version}). "
1343
+ f"Ensure {apt_pkg_name} package is installed (either manually or via the auto_install_module_deps option) "
1344
+ f"or that you have specified the correct ansible_python_interpreter. (attempted {interpreters}).",
1345
+ )
1330
1346
 
1331
1347
  if p['clean'] is True:
1332
1348
  aptclean_stdout, aptclean_stderr, aptclean_diff = aptclean(module)
@@ -1456,7 +1472,11 @@ def main():
1456
1472
  allow_unauthenticated=allow_unauthenticated,
1457
1473
  allow_change_held_packages=allow_change_held_packages,
1458
1474
  allow_downgrade=allow_downgrade,
1459
- force=force_yes, fail_on_autoremove=fail_on_autoremove, dpkg_options=p['dpkg_options'])
1475
+ force=force_yes,
1476
+ fail_on_autoremove=fail_on_autoremove,
1477
+ dpkg_options=p['dpkg_options'],
1478
+ lock_timeout=p['lock_timeout']
1479
+ )
1460
1480
 
1461
1481
  unfiltered_packages = p['package'] or ()
1462
1482
  packages = [package.strip() for package in unfiltered_packages if package != '*']
@@ -8,7 +8,7 @@
8
8
  from __future__ import annotations
9
9
 
10
10
 
11
- DOCUMENTATION = '''
11
+ DOCUMENTATION = """
12
12
  ---
13
13
  module: apt_key
14
14
  author:
@@ -33,6 +33,8 @@ notes:
33
33
  To generate a full-fingerprint imported key: C(apt-key adv --list-public-keys --with-fingerprint --with-colons)."
34
34
  - If you specify both the key O(id) and the O(url) with O(state=present), the task can verify or add the key as needed.
35
35
  - Adding a new key requires an apt cache update (e.g. using the M(ansible.builtin.apt) module's C(update_cache) option).
36
+ - The C(apt-key) utility has been deprecated and removed in modern debian versions, use M(ansible.builtin.deb822_repository) as an alternative
37
+ to M(ansible.builtin.apt_repository) + apt_key combinations.
36
38
  requirements:
37
39
  - gpg
38
40
  seealso:
@@ -79,9 +81,9 @@ options:
79
81
  on personally controlled sites using self-signed certificates.
80
82
  type: bool
81
83
  default: 'yes'
82
- '''
84
+ """
83
85
 
84
- EXAMPLES = '''
86
+ EXAMPLES = """
85
87
  - name: One way to avoid apt_key once it is removed from your distro, armored keys should use .asc extension, binary should use .gpg
86
88
  block:
87
89
  - name: somerepo | no apt key
@@ -133,9 +135,9 @@ EXAMPLES = '''
133
135
  id: 9FED2BCBDCD29CDF762678CBAED4B06F473041FA
134
136
  file: /tmp/apt.gpg
135
137
  state: present
136
- '''
138
+ """
137
139
 
138
- RETURN = '''
140
+ RETURN = """
139
141
  after:
140
142
  description: List of apt key ids or fingerprints after any modification
141
143
  returned: on change
@@ -166,13 +168,10 @@ short_id:
166
168
  returned: always
167
169
  type: str
168
170
  sample: "A88D21E9"
169
- '''
171
+ """
170
172
 
171
173
  import os
172
174
 
173
- # FIXME: standardize into module_common
174
- from traceback import format_exc
175
-
176
175
  from ansible.module_utils.common.text.converters import to_native
177
176
  from ansible.module_utils.basic import AnsibleModule
178
177
  from ansible.module_utils.common.locale import get_best_parsable_locale
@@ -196,8 +195,16 @@ def lang_env(module):
196
195
  def find_needed_binaries(module):
197
196
  global apt_key_bin
198
197
  global gpg_bin
199
- apt_key_bin = module.get_bin_path('apt-key', required=True)
200
- gpg_bin = module.get_bin_path('gpg', required=True)
198
+
199
+ try:
200
+ apt_key_bin = module.get_bin_path('apt-key', required=True)
201
+ except ValueError as e:
202
+ module.exit_json(f'{to_native(e)}. Apt-key has been deprecated. See the deb822_repository as an alternative.')
203
+
204
+ try:
205
+ gpg_bin = module.get_bin_path('gpg', required=True)
206
+ except ValueError as e:
207
+ module.exit_json(msg=to_native(e))
201
208
 
202
209
 
203
210
  def add_http_proxy(cmd):
@@ -310,7 +317,7 @@ def download_key(module, url):
310
317
 
311
318
  return rsp.read()
312
319
  except Exception:
313
- module.fail_json(msg="error getting key id from url: %s" % url, traceback=format_exc())
320
+ module.fail_json(msg=f"Error getting key id from url: {url}")
314
321
 
315
322
 
316
323
  def get_key_id_from_file(module, filename, data=None):
@@ -9,7 +9,7 @@
9
9
  from __future__ import annotations
10
10
 
11
11
 
12
- DOCUMENTATION = '''
12
+ DOCUMENTATION = """
13
13
  ---
14
14
  module: apt_repository
15
15
  short_description: Add and remove APT repositories
@@ -88,8 +88,8 @@ options:
88
88
  description:
89
89
  - Whether to automatically try to install the Python apt library or not, if it is not already installed.
90
90
  Without this library, the module does not work.
91
- - Runs C(apt-get install python-apt) for Python 2, and C(apt-get install python3-apt) for Python 3.
92
- - Only works with the system Python 2 or Python 3. If you are using a Python on the remote that is not
91
+ - Runs C(apt-get install python3-apt).
92
+ - Only works with the system Python. If you are using a Python on the remote that is not
93
93
  the system Python, set O(install_python_apt=false) and ensure that the Python apt library
94
94
  for your Python version is installed some other way.
95
95
  type: bool
@@ -98,12 +98,11 @@ author:
98
98
  - Alexander Saltanov (@sashka)
99
99
  version_added: "0.7"
100
100
  requirements:
101
- - python-apt (python 2)
102
- - python3-apt (python 3)
101
+ - python3-apt
103
102
  - apt-key or gpg
104
- '''
103
+ """
105
104
 
106
- EXAMPLES = '''
105
+ EXAMPLES = """
107
106
  - name: Add specified repository into sources list
108
107
  ansible.builtin.apt_repository:
109
108
  repo: deb http://archive.canonical.com/ubuntu hardy partner
@@ -143,11 +142,11 @@ EXAMPLES = '''
143
142
 
144
143
  - name: somerepo | apt source
145
144
  ansible.builtin.apt_repository:
146
- repo: "deb [arch=amd64 signed-by=/etc/apt/keyrings/myrepo.asc] https://download.example.com/linux/ubuntu {{ ansible_distribution_release }} stable"
145
+ repo: "deb [arch=amd64 signed-by=/etc/apt/keyrings/somerepo.asc] https://download.example.com/linux/ubuntu {{ ansible_distribution_release }} stable"
147
146
  state: present
148
- '''
147
+ """
149
148
 
150
- RETURN = '''
149
+ RETURN = """
151
150
  repo:
152
151
  description: A source string for the repository
153
152
  returned: always
@@ -167,7 +166,7 @@ sources_removed:
167
166
  type: list
168
167
  sample: ["/etc/apt/sources.list.d/artifacts_elastic_co_packages_6_x_apt.list"]
169
168
  version_added: "2.15"
170
- '''
169
+ """
171
170
 
172
171
  import copy
173
172
  import glob
@@ -232,20 +231,21 @@ class SourcesList(object):
232
231
  self.files_mapping = {} # internal DS for tracking symlinks
233
232
  # Repositories that we're adding -- used to implement mode param
234
233
  self.new_repos = set()
235
- self.default_file = self._apt_cfg_file('Dir::Etc::sourcelist')
234
+ self.default_file = apt_pkg.config.find_file('Dir::Etc::sourcelist')
236
235
 
237
236
  # read sources.list if it exists
238
237
  if os.path.isfile(self.default_file):
239
238
  self.load(self.default_file)
240
239
 
241
240
  # read sources.list.d
242
- for file in glob.iglob('%s/*.list' % self._apt_cfg_dir('Dir::Etc::sourceparts')):
241
+ self.sources_dir = apt_pkg.config.find_dir('Dir::Etc::sourceparts')
242
+ for file in glob.iglob(f'{self.sources_dir}/*.list'):
243
243
  if os.path.islink(file):
244
244
  self.files_mapping[file] = os.readlink(file)
245
245
  self.load(file)
246
246
 
247
247
  def __iter__(self):
248
- '''Simple iterator to go over all sources. Empty, non-source, and other not valid lines will be skipped.'''
248
+ """Simple iterator to go over all sources. Empty, non-source, and other not valid lines will be skipped."""
249
249
  for file, sources in self.files.items():
250
250
  for n, valid, enabled, source, comment in sources:
251
251
  if valid:
@@ -255,7 +255,7 @@ class SourcesList(object):
255
255
  if '/' in filename:
256
256
  return filename
257
257
  else:
258
- return os.path.abspath(os.path.join(self._apt_cfg_dir('Dir::Etc::sourceparts'), filename))
258
+ return os.path.abspath(os.path.join(self.sources_dir, filename))
259
259
 
260
260
  def _suggest_filename(self, line):
261
261
  def _cleanup_filename(s):
@@ -313,28 +313,6 @@ class SourcesList(object):
313
313
 
314
314
  return valid, enabled, source, comment
315
315
 
316
- @staticmethod
317
- def _apt_cfg_file(filespec):
318
- '''
319
- Wrapper for `apt_pkg` module for running with Python 2.5
320
- '''
321
- try:
322
- result = apt_pkg.config.find_file(filespec)
323
- except AttributeError:
324
- result = apt_pkg.Config.FindFile(filespec)
325
- return result
326
-
327
- @staticmethod
328
- def _apt_cfg_dir(dirspec):
329
- '''
330
- Wrapper for `apt_pkg` module for running with Python 2.5
331
- '''
332
- try:
333
- result = apt_pkg.config.find_dir(dirspec)
334
- except AttributeError:
335
- result = apt_pkg.Config.FindDir(dirspec)
336
- return result
337
-
338
316
  def load(self, file):
339
317
  group = []
340
318
  f = open(file, 'r')
@@ -355,8 +333,8 @@ class SourcesList(object):
355
333
 
356
334
  try:
357
335
  fd, tmp_path = tempfile.mkstemp(prefix=".%s-" % fn, dir=d)
358
- except (OSError, IOError) as e:
359
- self.module.fail_json(msg='Unable to create temp file at "%s" for apt source: %s' % (d, to_native(e)))
336
+ except OSError as ex:
337
+ raise Exception(f'Unable to create temp file at {d!r} for apt source.') from ex
360
338
 
361
339
  f = os.fdopen(fd, 'w')
362
340
  for n, valid, enabled, source, comment in sources:
@@ -372,8 +350,8 @@ class SourcesList(object):
372
350
 
373
351
  try:
374
352
  f.write(line)
375
- except IOError as ex:
376
- self.module.fail_json(msg="Failed to write to file %s: %s" % (tmp_path, to_native(ex)))
353
+ except OSError as ex:
354
+ raise Exception(f"Failed to write to file {tmp_path!r}.") from ex
377
355
  if filename in self.files_mapping:
378
356
  # Write to symlink target instead of replacing symlink as a normal file
379
357
  self.module.atomic_move(tmp_path, self.files_mapping[filename])
@@ -413,10 +391,10 @@ class SourcesList(object):
413
391
  return new
414
392
 
415
393
  def modify(self, file, n, enabled=None, source=None, comment=None):
416
- '''
394
+ """
417
395
  This function to be used with iterator, so we don't care of invalid sources.
418
396
  If source, enabled, or comment is None, original value from line ``n`` will be preserved.
419
- '''
397
+ """
420
398
  valid, enabled_old, source_old, comment_old = self.files[file][n][1:]
421
399
  self.files[file][n] = (n, valid, self._choice(enabled, enabled_old), self._choice(source, source_old), self._choice(comment, comment_old))
422
400
 
@@ -475,7 +453,10 @@ class UbuntuSourcesList(SourcesList):
475
453
  self.apt_key_bin = self.module.get_bin_path('apt-key', required=False)
476
454
  self.gpg_bin = self.module.get_bin_path('gpg', required=False)
477
455
  if not self.apt_key_bin and not self.gpg_bin:
478
- self.module.fail_json(msg='Either apt-key or gpg binary is required, but neither could be found')
456
+ msg = 'Either apt-key or gpg binary is required, but neither could be found.' \
457
+ 'The apt-key CLI has been deprecated and removed in modern Debian and derivatives, ' \
458
+ 'you might want to use "deb822_repository" instead.'
459
+ self.module.fail_json(msg)
479
460
 
480
461
  def __deepcopy__(self, memo=None):
481
462
  return UbuntuSourcesList(self.module)
@@ -526,8 +507,8 @@ class UbuntuSourcesList(SourcesList):
526
507
  if os.path.exists(key_file):
527
508
  try:
528
509
  rc, out, err = self.module.run_command([self.gpg_bin, '--list-packets', key_file])
529
- except (IOError, OSError) as e:
530
- self.debug("Could check key against file %s: %s" % (key_file, to_native(e)))
510
+ except OSError as ex:
511
+ self.debug(f"Could check key against file {key_file!r}: {ex}")
531
512
  continue
532
513
 
533
514
  if key_fingerprint in out:
@@ -576,8 +557,8 @@ class UbuntuSourcesList(SourcesList):
576
557
  with open(keyfile, 'wb') as f:
577
558
  f.write(stdout)
578
559
  self.module.log('Added repo key "%s" for apt to file "%s"' % (info['signing_key_fingerprint'], keyfile))
579
- except (OSError, IOError) as e:
580
- self.module.fail_json(msg='Unable to add required signing key for%s ', rc=rc, stderr=stderr, error=to_native(e))
560
+ except OSError as ex:
561
+ self.module.fail_json(msg='Unable to add required signing key.', rc=rc, stderr=stderr, error=str(ex), exception=ex)
581
562
 
582
563
  # apt source file
583
564
  file = file or self._suggest_filename('%s_%s' % (line, self.codename))
@@ -616,7 +597,7 @@ class UbuntuSourcesList(SourcesList):
616
597
 
617
598
 
618
599
  def revert_sources_list(sources_before, sources_after, sourceslist_before):
619
- '''Revert the sourcelist files to their previous state.'''
600
+ """Revert the sourcelist files to their previous state."""
620
601
 
621
602
  # First remove any new files that were created:
622
603
  for filename in set(sources_after.keys()).difference(sources_before.keys()):
@@ -771,9 +752,9 @@ def main():
771
752
  )
772
753
  module.fail_json(msg=msg)
773
754
 
774
- except (OSError, IOError) as ex:
755
+ except OSError as ex:
775
756
  revert_sources_list(sources_before, sources_after, sourceslist_before)
776
- module.fail_json(msg=to_native(ex))
757
+ raise
777
758
 
778
759
  module.exit_json(changed=changed, repo=repo, sources_added=sources_added, sources_removed=sources_removed, state=state, diff=diff)
779
760
 
@@ -8,7 +8,7 @@
8
8
  from __future__ import annotations
9
9
 
10
10
 
11
- DOCUMENTATION = r'''
11
+ DOCUMENTATION = r"""
12
12
  ---
13
13
  module: assemble
14
14
  short_description: Assemble configuration files from fragments
@@ -80,7 +80,7 @@ attributes:
80
80
  bypass_host_loop:
81
81
  support: none
82
82
  check_mode:
83
- support: none
83
+ support: full
84
84
  diff_mode:
85
85
  support: full
86
86
  platform:
@@ -102,9 +102,9 @@ extends_documentation_fragment:
102
102
  - action_common_attributes.files
103
103
  - decrypt
104
104
  - files
105
- '''
105
+ """
106
106
 
107
- EXAMPLES = r'''
107
+ EXAMPLES = r"""
108
108
  - name: Assemble from fragments from a directory
109
109
  ansible.builtin.assemble:
110
110
  src: /etc/someapp/fragments
@@ -121,9 +121,9 @@ EXAMPLES = r'''
121
121
  src: /etc/ssh/conf.d/
122
122
  dest: /etc/ssh/sshd_config
123
123
  validate: /usr/sbin/sshd -t -f %s
124
- '''
124
+ """
125
125
 
126
- RETURN = r'''#'''
126
+ RETURN = r"""#"""
127
127
 
128
128
  import codecs
129
129
  import os
@@ -136,7 +136,7 @@ from ansible.module_utils.common.text.converters import to_native
136
136
 
137
137
 
138
138
  def assemble_from_fragments(src_path, delimiter=None, compiled_regexp=None, ignore_hidden=False, tmpdir=None):
139
- ''' assemble a file from a directory of fragments '''
139
+ """ assemble a file from a directory of fragments """
140
140
  tmpfd, temp_path = tempfile.mkstemp(dir=tmpdir)
141
141
  tmp = os.fdopen(tmpfd, 'wb')
142
142
  delimit_me = False
@@ -181,15 +181,15 @@ def assemble_from_fragments(src_path, delimiter=None, compiled_regexp=None, igno
181
181
  return temp_path
182
182
 
183
183
 
184
- def cleanup(path, result=None):
184
+ def cleanup(module, path, result=None):
185
185
  # cleanup just in case
186
186
  if os.path.exists(path):
187
187
  try:
188
188
  os.remove(path)
189
- except (IOError, OSError) as e:
189
+ except OSError as ex:
190
190
  # don't error on possible race conditions, but keep warning
191
191
  if result is not None:
192
- result['warnings'] = ['Unable to remove temp file (%s): %s' % (path, to_native(e))]
192
+ module.error_as_warning(f'Unable to remove temp file {path!r}.', exception=ex)
193
193
 
194
194
 
195
195
  def main():
@@ -212,6 +212,7 @@ def main():
212
212
  decrypt=dict(type='bool', default=True),
213
213
  ),
214
214
  add_file_common_args=True,
215
+ supports_check_mode=True,
215
216
  )
216
217
 
217
218
  changed = False
@@ -261,17 +262,18 @@ def main():
261
262
  (rc, out, err) = module.run_command(validate % path)
262
263
  result['validation'] = dict(rc=rc, stdout=out, stderr=err)
263
264
  if rc != 0:
264
- cleanup(path)
265
+ cleanup(module, path)
265
266
  module.fail_json(msg="failed to validate: rc:%s error:%s" % (rc, err))
266
267
  if backup and dest_hash is not None:
267
268
  result['backup_file'] = module.backup_local(dest)
268
269
 
269
- module.atomic_move(path, dest, unsafe_writes=module.params['unsafe_writes'])
270
+ if not module.check_mode:
271
+ module.atomic_move(path, dest, unsafe_writes=module.params['unsafe_writes'])
270
272
  changed = True
271
273
 
272
- cleanup(path, result)
274
+ cleanup(module, path, result)
273
275
 
274
- # handle file permissions
276
+ # handle file permissions (check mode aware)
275
277
  file_args = module.load_file_common_arguments(module.params)
276
278
  result['changed'] = module.set_fs_attributes_if_different(file_args, changed)
277
279
 
ansible/modules/assert.py CHANGED
@@ -6,7 +6,7 @@
6
6
  from __future__ import annotations
7
7
 
8
8
 
9
- DOCUMENTATION = r'''
9
+ DOCUMENTATION = r"""
10
10
  ---
11
11
  module: assert
12
12
  short_description: Asserts given expressions are true
@@ -70,9 +70,9 @@ seealso:
70
70
  author:
71
71
  - Ansible Core Team
72
72
  - Michael DeHaan
73
- '''
73
+ """
74
74
 
75
- EXAMPLES = r'''
75
+ EXAMPLES = r"""
76
76
  - name: A single condition can be supplied as string instead of list
77
77
  ansible.builtin.assert:
78
78
  that: "ansible_os_family != 'RedHat'"
@@ -106,4 +106,4 @@ EXAMPLES = r'''
106
106
  - my_param <= 100
107
107
  - my_param >= 0
108
108
  quiet: true
109
- '''
109
+ """