ansible-core 2.16.7__py3-none-any.whl → 2.17.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 (597) hide show
  1. ansible/__init__.py +1 -3
  2. ansible/__main__.py +1 -0
  3. ansible/_vendor/__init__.py +1 -2
  4. ansible/cli/__init__.py +7 -8
  5. ansible/cli/adhoc.py +1 -2
  6. ansible/cli/arguments/__init__.py +1 -2
  7. ansible/cli/arguments/option_helpers.py +1 -2
  8. ansible/cli/config.py +1 -2
  9. ansible/cli/console.py +1 -2
  10. ansible/cli/doc.py +326 -202
  11. ansible/cli/galaxy.py +9 -3
  12. ansible/cli/inventory.py +4 -6
  13. ansible/cli/playbook.py +1 -2
  14. ansible/cli/pull.py +4 -5
  15. ansible/cli/scripts/ansible_connection_cli_stub.py +1 -4
  16. ansible/cli/vault.py +1 -2
  17. ansible/collections/list.py +1 -0
  18. ansible/compat/__init__.py +1 -4
  19. ansible/compat/importlib_resources.py +1 -2
  20. ansible/compat/{selectors/__init__.py → selectors.py} +12 -12
  21. ansible/config/ansible_builtin_runtime.yml +2 -0
  22. ansible/config/base.yml +154 -149
  23. ansible/config/manager.py +33 -25
  24. ansible/constants.py +1 -2
  25. ansible/context.py +1 -4
  26. ansible/errors/__init__.py +1 -3
  27. ansible/errors/yaml_strings.py +1 -3
  28. ansible/executor/__init__.py +1 -3
  29. ansible/executor/discovery/python_target.py +1 -2
  30. ansible/executor/interpreter_discovery.py +9 -8
  31. ansible/executor/module_common.py +1 -3
  32. ansible/executor/play_iterator.py +1 -3
  33. ansible/executor/playbook_executor.py +1 -3
  34. ansible/executor/powershell/module_manifest.py +2 -3
  35. ansible/executor/process/__init__.py +1 -3
  36. ansible/executor/process/worker.py +1 -3
  37. ansible/executor/stats.py +1 -3
  38. ansible/executor/task_executor.py +2 -3
  39. ansible/executor/task_queue_manager.py +1 -3
  40. ansible/executor/task_result.py +2 -3
  41. ansible/galaxy/__init__.py +1 -2
  42. ansible/galaxy/api.py +10 -2
  43. ansible/galaxy/collection/__init__.py +38 -24
  44. ansible/galaxy/collection/concrete_artifact_manager.py +1 -2
  45. ansible/galaxy/collection/galaxy_api_proxy.py +1 -2
  46. ansible/galaxy/collection/gpg.py +4 -2
  47. ansible/galaxy/data/apb/meta/main.yml.j2 +0 -15
  48. ansible/galaxy/data/container/meta/main.yml.j2 +0 -18
  49. ansible/galaxy/data/default/role/meta/main.yml.j2 +0 -18
  50. ansible/galaxy/data/network/cliconf_plugins/example.py.j2 +1 -2
  51. ansible/galaxy/data/network/library/example_command.py.j2 +1 -2
  52. ansible/galaxy/data/network/library/example_config.py.j2 +1 -2
  53. ansible/galaxy/data/network/library/example_facts.py.j2 +1 -2
  54. ansible/galaxy/data/network/meta/main.yml.j2 +0 -15
  55. ansible/galaxy/data/network/module_utils/example.py.j2 +1 -2
  56. ansible/galaxy/data/network/netconf_plugins/example.py.j2 +1 -2
  57. ansible/galaxy/data/network/terminal_plugins/example.py.j2 +1 -2
  58. ansible/galaxy/dependency_resolution/__init__.py +1 -2
  59. ansible/galaxy/dependency_resolution/dataclasses.py +5 -6
  60. ansible/galaxy/dependency_resolution/errors.py +1 -2
  61. ansible/galaxy/dependency_resolution/providers.py +3 -4
  62. ansible/galaxy/dependency_resolution/reporters.py +2 -3
  63. ansible/galaxy/dependency_resolution/resolvers.py +1 -2
  64. ansible/galaxy/dependency_resolution/versioning.py +1 -2
  65. ansible/galaxy/role.py +2 -3
  66. ansible/galaxy/token.py +1 -2
  67. ansible/galaxy/user_agent.py +1 -2
  68. ansible/inventory/data.py +1 -2
  69. ansible/inventory/group.py +1 -2
  70. ansible/inventory/helpers.py +1 -2
  71. ansible/inventory/host.py +1 -3
  72. ansible/inventory/manager.py +1 -2
  73. ansible/module_utils/_text.py +1 -2
  74. ansible/module_utils/ansible_release.py +3 -5
  75. ansible/module_utils/api.py +1 -2
  76. ansible/module_utils/basic.py +113 -158
  77. ansible/module_utils/common/_collections_compat.py +1 -2
  78. ansible/module_utils/common/_utils.py +1 -3
  79. ansible/module_utils/common/arg_spec.py +1 -2
  80. ansible/module_utils/common/collections.py +1 -2
  81. ansible/module_utils/common/dict_transformations.py +1 -2
  82. ansible/module_utils/common/file.py +10 -5
  83. ansible/module_utils/common/json.py +1 -3
  84. ansible/module_utils/common/locale.py +1 -2
  85. ansible/module_utils/common/network.py +2 -3
  86. ansible/module_utils/common/parameters.py +9 -9
  87. ansible/module_utils/common/process.py +12 -5
  88. ansible/module_utils/common/respawn.py +2 -3
  89. ansible/module_utils/common/sys_info.py +1 -2
  90. ansible/module_utils/common/text/converters.py +1 -2
  91. ansible/module_utils/common/text/formatters.py +1 -2
  92. ansible/module_utils/common/validation.py +5 -6
  93. ansible/module_utils/common/warnings.py +1 -2
  94. ansible/module_utils/common/yaml.py +1 -2
  95. ansible/module_utils/compat/datetime.py +1 -3
  96. ansible/module_utils/compat/importlib.py +21 -13
  97. ansible/module_utils/compat/paramiko.py +1 -2
  98. ansible/module_utils/compat/selectors.py +10 -34
  99. ansible/module_utils/compat/selinux.py +1 -2
  100. ansible/module_utils/compat/typing.py +1 -2
  101. ansible/module_utils/compat/version.py +1 -2
  102. ansible/module_utils/connection.py +1 -2
  103. ansible/module_utils/csharp/Ansible.Basic.cs +20 -3
  104. ansible/module_utils/distro/__init__.py +3 -4
  105. ansible/module_utils/distro/_distro.py +230 -234
  106. ansible/module_utils/errors.py +1 -2
  107. ansible/module_utils/facts/__init__.py +1 -2
  108. ansible/module_utils/facts/ansible_collector.py +1 -2
  109. ansible/module_utils/facts/collector.py +1 -2
  110. ansible/module_utils/facts/compat.py +1 -2
  111. ansible/module_utils/facts/default_collectors.py +1 -2
  112. ansible/module_utils/facts/hardware/aix.py +1 -2
  113. ansible/module_utils/facts/hardware/base.py +1 -2
  114. ansible/module_utils/facts/hardware/darwin.py +1 -2
  115. ansible/module_utils/facts/hardware/dragonfly.py +1 -2
  116. ansible/module_utils/facts/hardware/freebsd.py +1 -2
  117. ansible/module_utils/facts/hardware/hpux.py +1 -2
  118. ansible/module_utils/facts/hardware/hurd.py +1 -2
  119. ansible/module_utils/facts/hardware/linux.py +8 -6
  120. ansible/module_utils/facts/hardware/netbsd.py +1 -2
  121. ansible/module_utils/facts/hardware/openbsd.py +1 -2
  122. ansible/module_utils/facts/hardware/sunos.py +2 -3
  123. ansible/module_utils/facts/namespace.py +1 -2
  124. ansible/module_utils/facts/network/aix.py +1 -2
  125. ansible/module_utils/facts/network/base.py +1 -2
  126. ansible/module_utils/facts/network/darwin.py +1 -2
  127. ansible/module_utils/facts/network/dragonfly.py +1 -2
  128. ansible/module_utils/facts/network/fc_wwn.py +1 -2
  129. ansible/module_utils/facts/network/freebsd.py +1 -2
  130. ansible/module_utils/facts/network/generic_bsd.py +1 -2
  131. ansible/module_utils/facts/network/hpux.py +1 -2
  132. ansible/module_utils/facts/network/hurd.py +1 -2
  133. ansible/module_utils/facts/network/iscsi.py +1 -2
  134. ansible/module_utils/facts/network/linux.py +1 -2
  135. ansible/module_utils/facts/network/netbsd.py +1 -2
  136. ansible/module_utils/facts/network/nvme.py +1 -2
  137. ansible/module_utils/facts/network/openbsd.py +1 -2
  138. ansible/module_utils/facts/network/sunos.py +1 -2
  139. ansible/module_utils/facts/other/facter.py +1 -2
  140. ansible/module_utils/facts/other/ohai.py +1 -2
  141. ansible/module_utils/facts/packages.py +1 -2
  142. ansible/module_utils/facts/sysctl.py +1 -2
  143. ansible/module_utils/facts/system/apparmor.py +1 -2
  144. ansible/module_utils/facts/system/caps.py +1 -2
  145. ansible/module_utils/facts/system/chroot.py +1 -2
  146. ansible/module_utils/facts/system/cmdline.py +1 -2
  147. ansible/module_utils/facts/system/date_time.py +1 -2
  148. ansible/module_utils/facts/system/distribution.py +4 -5
  149. ansible/module_utils/facts/system/dns.py +1 -2
  150. ansible/module_utils/facts/system/env.py +1 -2
  151. ansible/module_utils/facts/system/fips.py +1 -2
  152. ansible/module_utils/facts/system/loadavg.py +1 -2
  153. ansible/module_utils/facts/system/local.py +1 -2
  154. ansible/module_utils/facts/system/lsb.py +1 -2
  155. ansible/module_utils/facts/system/pkg_mgr.py +7 -30
  156. ansible/module_utils/facts/system/platform.py +1 -2
  157. ansible/module_utils/facts/system/python.py +1 -2
  158. ansible/module_utils/facts/system/selinux.py +1 -2
  159. ansible/module_utils/facts/system/service_mgr.py +1 -2
  160. ansible/module_utils/facts/system/ssh_pub_keys.py +1 -2
  161. ansible/module_utils/facts/system/user.py +1 -2
  162. ansible/module_utils/facts/timeout.py +1 -2
  163. ansible/module_utils/facts/utils.py +1 -2
  164. ansible/module_utils/facts/virtual/base.py +1 -2
  165. ansible/module_utils/facts/virtual/dragonfly.py +1 -2
  166. ansible/module_utils/facts/virtual/freebsd.py +1 -2
  167. ansible/module_utils/facts/virtual/hpux.py +1 -2
  168. ansible/module_utils/facts/virtual/linux.py +1 -2
  169. ansible/module_utils/facts/virtual/netbsd.py +1 -2
  170. ansible/module_utils/facts/virtual/openbsd.py +1 -2
  171. ansible/module_utils/facts/virtual/sunos.py +1 -2
  172. ansible/module_utils/facts/virtual/sysctl.py +1 -2
  173. ansible/module_utils/json_utils.py +1 -2
  174. ansible/module_utils/parsing/convert_bool.py +1 -2
  175. ansible/module_utils/powershell/Ansible.ModuleUtils.Legacy.psm1 +5 -2
  176. ansible/module_utils/powershell/Ansible.ModuleUtils.WebRequest.psm1 +1 -1
  177. ansible/module_utils/pycompat24.py +24 -4
  178. ansible/module_utils/service.py +31 -5
  179. ansible/module_utils/six/__init__.py +1 -1
  180. ansible/module_utils/splitter.py +1 -2
  181. ansible/module_utils/urls.py +335 -1052
  182. ansible/module_utils/yumdnf.py +13 -35
  183. ansible/modules/add_host.py +1 -2
  184. ansible/modules/apt.py +38 -22
  185. ansible/modules/apt_key.py +1 -2
  186. ansible/modules/apt_repository.py +18 -10
  187. ansible/modules/assemble.py +1 -2
  188. ansible/modules/assert.py +8 -4
  189. ansible/modules/async_status.py +17 -14
  190. ansible/modules/async_wrapper.py +11 -9
  191. ansible/modules/blockinfile.py +2 -3
  192. ansible/modules/command.py +1 -2
  193. ansible/modules/copy.py +4 -76
  194. ansible/modules/cron.py +3 -3
  195. ansible/modules/deb822_repository.py +5 -5
  196. ansible/modules/debconf.py +19 -8
  197. ansible/modules/debug.py +1 -2
  198. ansible/modules/dnf.py +39 -46
  199. ansible/modules/dnf5.py +28 -26
  200. ansible/modules/dpkg_selections.py +1 -2
  201. ansible/modules/expect.py +23 -15
  202. ansible/modules/fail.py +1 -2
  203. ansible/modules/fetch.py +1 -2
  204. ansible/modules/file.py +4 -3
  205. ansible/modules/find.py +18 -5
  206. ansible/modules/gather_facts.py +1 -2
  207. ansible/modules/get_url.py +2 -3
  208. ansible/modules/getent.py +2 -3
  209. ansible/modules/git.py +28 -17
  210. ansible/modules/group.py +1 -2
  211. ansible/modules/group_by.py +1 -2
  212. ansible/modules/hostname.py +2 -19
  213. ansible/modules/import_playbook.py +1 -2
  214. ansible/modules/import_role.py +9 -2
  215. ansible/modules/import_tasks.py +1 -2
  216. ansible/modules/include_role.py +1 -2
  217. ansible/modules/include_tasks.py +1 -2
  218. ansible/modules/include_vars.py +1 -2
  219. ansible/modules/iptables.py +38 -21
  220. ansible/modules/known_hosts.py +15 -8
  221. ansible/modules/lineinfile.py +1 -6
  222. ansible/modules/meta.py +3 -2
  223. ansible/modules/package.py +6 -5
  224. ansible/modules/package_facts.py +1 -2
  225. ansible/modules/pause.py +2 -3
  226. ansible/modules/ping.py +1 -2
  227. ansible/modules/pip.py +40 -20
  228. ansible/modules/raw.py +1 -2
  229. ansible/modules/reboot.py +1 -2
  230. ansible/modules/replace.py +7 -5
  231. ansible/modules/rpm_key.py +1 -2
  232. ansible/modules/script.py +1 -2
  233. ansible/modules/service.py +3 -21
  234. ansible/modules/service_facts.py +3 -12
  235. ansible/modules/set_fact.py +1 -2
  236. ansible/modules/set_stats.py +1 -2
  237. ansible/modules/setup.py +1 -2
  238. ansible/modules/shell.py +1 -2
  239. ansible/modules/slurp.py +1 -2
  240. ansible/modules/stat.py +1 -2
  241. ansible/modules/subversion.py +2 -3
  242. ansible/modules/systemd.py +12 -9
  243. ansible/modules/systemd_service.py +12 -9
  244. ansible/modules/sysvinit.py +7 -2
  245. ansible/modules/tempfile.py +7 -2
  246. ansible/modules/template.py +2 -3
  247. ansible/modules/unarchive.py +13 -3
  248. ansible/modules/uri.py +12 -15
  249. ansible/modules/user.py +11 -4
  250. ansible/modules/validate_argument_spec.py +15 -16
  251. ansible/modules/wait_for.py +1 -2
  252. ansible/modules/wait_for_connection.py +1 -2
  253. ansible/modules/yum_repository.py +2 -3
  254. ansible/parsing/__init__.py +1 -3
  255. ansible/parsing/ajson.py +1 -3
  256. ansible/parsing/dataloader.py +23 -12
  257. ansible/parsing/mod_args.py +6 -4
  258. ansible/parsing/plugin_docs.py +1 -2
  259. ansible/parsing/quoting.py +1 -3
  260. ansible/parsing/splitter.py +1 -3
  261. ansible/parsing/utils/__init__.py +1 -3
  262. ansible/parsing/utils/addresses.py +1 -3
  263. ansible/parsing/utils/jsonify.py +1 -3
  264. ansible/parsing/utils/yaml.py +1 -3
  265. ansible/parsing/vault/__init__.py +6 -8
  266. ansible/parsing/yaml/__init__.py +1 -3
  267. ansible/parsing/yaml/constructor.py +1 -3
  268. ansible/parsing/yaml/dumper.py +1 -3
  269. ansible/parsing/yaml/loader.py +1 -3
  270. ansible/parsing/yaml/objects.py +1 -3
  271. ansible/playbook/__init__.py +1 -3
  272. ansible/playbook/attribute.py +1 -3
  273. ansible/playbook/base.py +2 -3
  274. ansible/playbook/block.py +1 -3
  275. ansible/playbook/collectionsearch.py +1 -2
  276. ansible/playbook/conditional.py +1 -3
  277. ansible/playbook/delegatable.py +1 -0
  278. ansible/playbook/handler.py +2 -4
  279. ansible/playbook/handler_task_include.py +1 -3
  280. ansible/playbook/helpers.py +1 -4
  281. ansible/playbook/included_file.py +4 -4
  282. ansible/playbook/loop_control.py +1 -3
  283. ansible/playbook/notifiable.py +1 -0
  284. ansible/playbook/play.py +1 -3
  285. ansible/playbook/play_context.py +1 -3
  286. ansible/playbook/playbook_include.py +1 -3
  287. ansible/playbook/role/__init__.py +1 -3
  288. ansible/playbook/role/definition.py +1 -3
  289. ansible/playbook/role/include.py +1 -3
  290. ansible/playbook/role/metadata.py +1 -3
  291. ansible/playbook/role/requirement.py +1 -3
  292. ansible/playbook/role_include.py +2 -10
  293. ansible/playbook/taggable.py +1 -3
  294. ansible/playbook/task.py +2 -4
  295. ansible/playbook/task_include.py +1 -3
  296. ansible/plugins/__init__.py +4 -5
  297. ansible/plugins/action/__init__.py +19 -13
  298. ansible/plugins/action/add_host.py +2 -4
  299. ansible/plugins/action/assemble.py +2 -3
  300. ansible/plugins/action/assert.py +1 -2
  301. ansible/plugins/action/async_status.py +1 -2
  302. ansible/plugins/action/command.py +1 -2
  303. ansible/plugins/action/copy.py +12 -9
  304. ansible/plugins/action/debug.py +1 -2
  305. ansible/plugins/action/dnf.py +4 -4
  306. ansible/plugins/action/fail.py +1 -2
  307. ansible/plugins/action/fetch.py +2 -3
  308. ansible/plugins/action/gather_facts.py +3 -4
  309. ansible/plugins/action/group_by.py +1 -2
  310. ansible/plugins/action/include_vars.py +1 -2
  311. ansible/plugins/action/normal.py +1 -2
  312. ansible/plugins/action/package.py +36 -21
  313. ansible/plugins/action/pause.py +1 -2
  314. ansible/plugins/action/raw.py +2 -3
  315. ansible/plugins/action/reboot.py +30 -15
  316. ansible/plugins/action/script.py +3 -4
  317. ansible/plugins/action/service.py +1 -2
  318. ansible/plugins/action/set_fact.py +1 -2
  319. ansible/plugins/action/set_stats.py +1 -2
  320. ansible/plugins/action/shell.py +1 -2
  321. ansible/plugins/action/template.py +1 -2
  322. ansible/plugins/action/unarchive.py +1 -2
  323. ansible/plugins/action/uri.py +2 -3
  324. ansible/plugins/action/validate_argument_spec.py +1 -2
  325. ansible/plugins/action/wait_for_connection.py +2 -3
  326. ansible/plugins/become/__init__.py +1 -2
  327. ansible/plugins/become/runas.py +1 -2
  328. ansible/plugins/become/su.py +1 -2
  329. ansible/plugins/become/sudo.py +1 -2
  330. ansible/plugins/cache/__init__.py +3 -3
  331. ansible/plugins/cache/base.py +1 -2
  332. ansible/plugins/cache/jsonfile.py +1 -3
  333. ansible/plugins/cache/memory.py +1 -2
  334. ansible/plugins/callback/__init__.py +2 -4
  335. ansible/plugins/callback/default.py +2 -3
  336. ansible/plugins/callback/junit.py +1 -2
  337. ansible/plugins/callback/minimal.py +1 -3
  338. ansible/plugins/callback/oneline.py +1 -3
  339. ansible/plugins/callback/tree.py +1 -2
  340. ansible/plugins/cliconf/__init__.py +1 -2
  341. ansible/plugins/connection/__init__.py +4 -5
  342. ansible/plugins/connection/local.py +3 -4
  343. ansible/plugins/connection/paramiko_ssh.py +1 -2
  344. ansible/plugins/connection/psrp.py +1 -2
  345. ansible/plugins/connection/ssh.py +18 -54
  346. ansible/plugins/connection/winrm.py +3 -4
  347. ansible/plugins/doc_fragments/action_common_attributes.py +2 -3
  348. ansible/plugins/doc_fragments/action_core.py +3 -4
  349. ansible/plugins/doc_fragments/backup.py +1 -2
  350. ansible/plugins/doc_fragments/connection_pipelining.py +1 -2
  351. ansible/plugins/doc_fragments/constructed.py +1 -2
  352. ansible/plugins/doc_fragments/decrypt.py +2 -3
  353. ansible/plugins/doc_fragments/default_callback.py +1 -2
  354. ansible/plugins/doc_fragments/files.py +1 -2
  355. ansible/plugins/doc_fragments/inventory_cache.py +1 -2
  356. ansible/plugins/doc_fragments/result_format_callback.py +1 -2
  357. ansible/plugins/doc_fragments/return_common.py +1 -2
  358. ansible/plugins/doc_fragments/shell_common.py +1 -2
  359. ansible/plugins/doc_fragments/shell_windows.py +1 -2
  360. ansible/plugins/doc_fragments/template_common.py +1 -2
  361. ansible/plugins/doc_fragments/url.py +1 -2
  362. ansible/plugins/doc_fragments/url_windows.py +1 -2
  363. ansible/plugins/doc_fragments/validate.py +1 -2
  364. ansible/plugins/doc_fragments/vars_plugin_staging.py +1 -2
  365. ansible/plugins/filter/__init__.py +1 -2
  366. ansible/plugins/filter/b64decode.yml +8 -8
  367. ansible/plugins/filter/b64encode.yml +4 -4
  368. ansible/plugins/filter/comment.yml +1 -1
  369. ansible/plugins/filter/core.py +11 -9
  370. ansible/plugins/filter/encryption.py +1 -3
  371. ansible/plugins/filter/extract.yml +1 -1
  372. ansible/plugins/filter/from_yaml_all.yml +1 -1
  373. ansible/plugins/filter/human_readable.yml +3 -3
  374. ansible/plugins/filter/human_to_bytes.yml +2 -2
  375. ansible/plugins/filter/mandatory.yml +1 -1
  376. ansible/plugins/filter/mathstuff.py +2 -2
  377. ansible/plugins/filter/password_hash.yml +3 -2
  378. ansible/plugins/filter/regex_replace.yml +15 -0
  379. ansible/plugins/filter/regex_search.yml +12 -0
  380. ansible/plugins/filter/strftime.yml +2 -9
  381. ansible/plugins/filter/to_datetime.yml +17 -2
  382. ansible/plugins/filter/to_nice_json.yml +4 -0
  383. ansible/plugins/filter/union.yml +1 -1
  384. ansible/plugins/filter/urls.py +1 -2
  385. ansible/plugins/filter/urlsplit.py +1 -2
  386. ansible/plugins/filter/zip.yml +2 -2
  387. ansible/plugins/filter/zip_longest.yml +1 -1
  388. ansible/plugins/httpapi/__init__.py +1 -2
  389. ansible/plugins/inventory/__init__.py +2 -4
  390. ansible/plugins/inventory/advanced_host_list.py +1 -2
  391. ansible/plugins/inventory/auto.py +2 -3
  392. ansible/plugins/inventory/constructed.py +3 -2
  393. ansible/plugins/inventory/generator.py +1 -2
  394. ansible/plugins/inventory/host_list.py +1 -2
  395. ansible/plugins/inventory/ini.py +1 -2
  396. ansible/plugins/inventory/script.py +122 -3
  397. ansible/plugins/inventory/toml.py +1 -2
  398. ansible/plugins/inventory/yaml.py +3 -4
  399. ansible/plugins/list.py +2 -3
  400. ansible/plugins/loader.py +10 -11
  401. ansible/plugins/lookup/__init__.py +1 -3
  402. ansible/plugins/lookup/config.py +19 -15
  403. ansible/plugins/lookup/csvfile.py +16 -7
  404. ansible/plugins/lookup/dict.py +2 -3
  405. ansible/plugins/lookup/env.py +4 -4
  406. ansible/plugins/lookup/file.py +1 -2
  407. ansible/plugins/lookup/fileglob.py +1 -2
  408. ansible/plugins/lookup/first_found.py +8 -7
  409. ansible/plugins/lookup/indexed_items.py +1 -2
  410. ansible/plugins/lookup/ini.py +6 -3
  411. ansible/plugins/lookup/inventory_hostnames.py +1 -2
  412. ansible/plugins/lookup/items.py +1 -2
  413. ansible/plugins/lookup/lines.py +1 -2
  414. ansible/plugins/lookup/list.py +1 -3
  415. ansible/plugins/lookup/nested.py +1 -2
  416. ansible/plugins/lookup/password.py +16 -14
  417. ansible/plugins/lookup/pipe.py +1 -2
  418. ansible/plugins/lookup/random_choice.py +1 -2
  419. ansible/plugins/lookup/sequence.py +21 -52
  420. ansible/plugins/lookup/subelements.py +1 -2
  421. ansible/plugins/lookup/template.py +1 -2
  422. ansible/plugins/lookup/together.py +1 -2
  423. ansible/plugins/lookup/unvault.py +1 -2
  424. ansible/plugins/lookup/url.py +9 -11
  425. ansible/plugins/lookup/varnames.py +1 -2
  426. ansible/plugins/lookup/vars.py +1 -2
  427. ansible/plugins/netconf/__init__.py +1 -2
  428. ansible/plugins/shell/__init__.py +3 -4
  429. ansible/plugins/shell/cmd.py +1 -2
  430. ansible/plugins/shell/powershell.py +1 -2
  431. ansible/plugins/shell/sh.py +1 -2
  432. ansible/plugins/strategy/__init__.py +33 -21
  433. ansible/plugins/strategy/debug.py +1 -2
  434. ansible/plugins/strategy/free.py +17 -7
  435. ansible/plugins/strategy/host_pinned.py +1 -3
  436. ansible/plugins/strategy/linear.py +22 -22
  437. ansible/plugins/terminal/__init__.py +2 -3
  438. ansible/plugins/test/__init__.py +1 -2
  439. ansible/plugins/test/change.yml +1 -1
  440. ansible/plugins/test/changed.yml +1 -1
  441. ansible/plugins/test/contains.yml +1 -1
  442. ansible/plugins/test/core.py +2 -4
  443. ansible/plugins/test/exists.yml +1 -1
  444. ansible/plugins/test/failed.yml +1 -1
  445. ansible/plugins/test/failure.yml +1 -1
  446. ansible/plugins/test/files.py +1 -3
  447. ansible/plugins/test/finished.yml +3 -3
  448. ansible/plugins/test/issuperset.yml +1 -1
  449. ansible/plugins/test/match.yml +1 -1
  450. ansible/plugins/test/mathstuff.py +1 -2
  451. ansible/plugins/test/reachable.yml +1 -1
  452. ansible/plugins/test/regex.yml +1 -1
  453. ansible/plugins/test/search.yml +1 -1
  454. ansible/plugins/test/skip.yml +1 -1
  455. ansible/plugins/test/skipped.yml +1 -1
  456. ansible/plugins/test/started.yml +1 -1
  457. ansible/plugins/test/succeeded.yml +1 -1
  458. ansible/plugins/test/success.yml +1 -1
  459. ansible/plugins/test/successful.yml +1 -1
  460. ansible/plugins/test/superset.yml +1 -1
  461. ansible/plugins/test/unreachable.yml +1 -1
  462. ansible/plugins/test/uri.py +1 -3
  463. ansible/plugins/vars/__init__.py +1 -2
  464. ansible/plugins/vars/host_group_vars.py +2 -3
  465. ansible/release.py +3 -5
  466. ansible/template/__init__.py +14 -27
  467. ansible/template/native_helpers.py +1 -3
  468. ansible/template/template.py +1 -3
  469. ansible/template/vars.py +1 -0
  470. ansible/utils/__init__.py +1 -3
  471. ansible/utils/cmd_functions.py +1 -2
  472. ansible/utils/collection_loader/__init__.py +1 -2
  473. ansible/utils/collection_loader/_collection_config.py +1 -2
  474. ansible/utils/collection_loader/_collection_finder.py +1 -2
  475. ansible/utils/collection_loader/_collection_meta.py +1 -2
  476. ansible/utils/color.py +1 -2
  477. ansible/utils/context_objects.py +1 -4
  478. ansible/utils/display.py +89 -30
  479. ansible/utils/encrypt.py +4 -105
  480. ansible/utils/fqcn.py +1 -2
  481. ansible/utils/galaxy.py +1 -3
  482. ansible/utils/hashing.py +1 -3
  483. ansible/utils/helpers.py +1 -3
  484. ansible/utils/jsonrpc.py +1 -2
  485. ansible/utils/listify.py +1 -3
  486. ansible/utils/lock.py +1 -3
  487. ansible/utils/multiprocessing.py +1 -3
  488. ansible/utils/native_jinja.py +1 -3
  489. ansible/utils/path.py +1 -2
  490. ansible/utils/plugin_docs.py +7 -6
  491. ansible/utils/py3compat.py +17 -55
  492. ansible/utils/sentinel.py +1 -3
  493. ansible/utils/shlex.py +1 -3
  494. ansible/utils/singleton.py +1 -3
  495. ansible/utils/ssh_functions.py +1 -3
  496. ansible/utils/unicode.py +1 -3
  497. ansible/utils/unsafe_proxy.py +1 -2
  498. ansible/utils/vars.py +6 -8
  499. ansible/utils/version.py +1 -3
  500. ansible/vars/clean.py +1 -3
  501. ansible/vars/fact_cache.py +1 -2
  502. ansible/vars/hostvars.py +3 -7
  503. ansible/vars/manager.py +24 -6
  504. ansible/vars/reserved.py +1 -3
  505. {ansible_core-2.16.7.data → ansible_core-2.17.0.data}/scripts/ansible-test +1 -2
  506. {ansible_core-2.16.7.dist-info → ansible_core-2.17.0.dist-info}/METADATA +3 -3
  507. ansible_core-2.17.0.dist-info/RECORD +987 -0
  508. ansible_test/__init__.py +1 -2
  509. ansible_test/_data/completion/docker.txt +7 -9
  510. ansible_test/_data/completion/remote.txt +6 -7
  511. ansible_test/_data/requirements/ansible-test.txt +0 -2
  512. ansible_test/_data/requirements/constraints.txt +1 -6
  513. ansible_test/_data/requirements/sanity.ansible-doc.txt +3 -3
  514. ansible_test/_data/requirements/sanity.changelog.txt +3 -3
  515. ansible_test/_data/requirements/sanity.import.plugin.txt +2 -2
  516. ansible_test/_data/requirements/sanity.mypy.txt +12 -12
  517. ansible_test/_data/requirements/sanity.pep8.txt +1 -1
  518. ansible_test/_data/requirements/sanity.pylint.txt +7 -7
  519. ansible_test/_data/requirements/sanity.runtime-metadata.txt +1 -1
  520. ansible_test/_data/requirements/sanity.validate-modules.txt +3 -3
  521. ansible_test/_data/requirements/sanity.yamllint.txt +2 -2
  522. ansible_test/_internal/bootstrap.py +2 -2
  523. ansible_test/_internal/classification/__init__.py +0 -5
  524. ansible_test/_internal/commands/integration/cloud/cs.py +1 -1
  525. ansible_test/_internal/commands/integration/cloud/nios.py +1 -1
  526. ansible_test/_internal/commands/sanity/__init__.py +1 -27
  527. ansible_test/_internal/commands/sanity/import.py +0 -18
  528. ansible_test/_internal/commands/sanity/mypy.py +7 -10
  529. ansible_test/_internal/commands/units/__init__.py +1 -1
  530. ansible_test/_internal/config.py +0 -1
  531. ansible_test/_internal/content_config.py +0 -5
  532. ansible_test/_internal/coverage_util.py +0 -1
  533. ansible_test/_internal/docker_util.py +1 -1
  534. ansible_test/_internal/host_profiles.py +5 -4
  535. ansible_test/_internal/pypi_proxy.py +1 -8
  536. ansible_test/_internal/python_requirements.py +1 -119
  537. ansible_test/_internal/ssh.py +1 -0
  538. ansible_test/_internal/util.py +1 -1
  539. ansible_test/_internal/util_common.py +1 -1
  540. ansible_test/_internal/venv.py +10 -108
  541. ansible_test/_util/__init__.py +1 -2
  542. ansible_test/_util/controller/sanity/mypy/ansible-core.ini +0 -6
  543. ansible_test/_util/controller/sanity/mypy/modules.ini +0 -6
  544. ansible_test/_util/controller/sanity/pylint/config/ansible-test-target.cfg +0 -1
  545. ansible_test/_util/controller/sanity/pylint/config/ansible-test.cfg +0 -1
  546. ansible_test/_util/controller/sanity/pylint/config/code-smell.cfg +0 -1
  547. ansible_test/_util/controller/sanity/pylint/config/collection.cfg +0 -1
  548. ansible_test/_util/controller/sanity/pylint/config/default.cfg +0 -1
  549. ansible_test/_util/controller/sanity/pylint/plugins/deprecated.py +1 -2
  550. ansible_test/_util/controller/sanity/shellcheck/exclude.txt +0 -1
  551. ansible_test/_util/controller/sanity/validate-modules/validate_modules/main.py +31 -59
  552. ansible_test/_util/controller/sanity/validate-modules/validate_modules/module_args.py +0 -7
  553. ansible_test/_util/controller/sanity/validate-modules/validate_modules/schema.py +10 -2
  554. ansible_test/_util/controller/sanity/validate-modules/validate_modules/utils.py +1 -1
  555. ansible_test/_util/controller/sanity/yamllint/yamllinter.py +16 -4
  556. ansible_test/_util/target/__init__.py +1 -2
  557. ansible_test/_util/target/cli/ansible_test_cli_stub.py +1 -2
  558. ansible_test/_util/target/common/constants.py +1 -4
  559. ansible_test/_util/target/injector/python.py +4 -19
  560. ansible_test/_util/target/pytest/plugins/ansible_forked.py +2 -9
  561. ansible_test/_util/target/pytest/plugins/ansible_pytest_collections.py +1 -5
  562. ansible_test/_util/target/pytest/plugins/ansible_pytest_coverage.py +1 -2
  563. ansible_test/_util/target/sanity/compile/compile.py +3 -12
  564. ansible_test/_util/target/sanity/import/importer.py +1 -12
  565. ansible_test/_util/target/setup/bootstrap.sh +49 -105
  566. ansible_test/_util/target/setup/probe_cgroups.py +1 -2
  567. ansible_test/_util/target/setup/quiet_pip.py +1 -16
  568. ansible_test/_util/target/setup/requirements.py +9 -2
  569. ansible_test/_util/target/tools/virtualenvcheck.py +1 -2
  570. ansible_test/_util/target/tools/yamlcheck.py +1 -2
  571. ansible/module_utils/common/_json_compat.py +0 -16
  572. ansible/module_utils/compat/_selectors2.py +0 -655
  573. ansible/modules/yum.py +0 -1821
  574. ansible/plugins/action/yum.py +0 -111
  575. ansible_core-2.16.7.dist-info/RECORD +0 -1009
  576. ansible_test/_util/controller/sanity/code-smell/future-import-boilerplate.json +0 -7
  577. ansible_test/_util/controller/sanity/code-smell/future-import-boilerplate.py +0 -46
  578. ansible_test/_util/controller/sanity/code-smell/metaclass-boilerplate.json +0 -7
  579. ansible_test/_util/controller/sanity/code-smell/metaclass-boilerplate.py +0 -44
  580. ansible_test/_util/controller/sanity/code-smell/no-basestring.json +0 -7
  581. ansible_test/_util/controller/sanity/code-smell/no-basestring.py +0 -21
  582. ansible_test/_util/controller/sanity/code-smell/no-dict-iteritems.json +0 -7
  583. ansible_test/_util/controller/sanity/code-smell/no-dict-iteritems.py +0 -21
  584. ansible_test/_util/controller/sanity/code-smell/no-dict-iterkeys.json +0 -7
  585. ansible_test/_util/controller/sanity/code-smell/no-dict-iterkeys.py +0 -21
  586. ansible_test/_util/controller/sanity/code-smell/no-dict-itervalues.json +0 -7
  587. ansible_test/_util/controller/sanity/code-smell/no-dict-itervalues.py +0 -21
  588. ansible_test/_util/controller/sanity/code-smell/no-main-display.json +0 -10
  589. ansible_test/_util/controller/sanity/code-smell/no-main-display.py +0 -21
  590. ansible_test/_util/controller/sanity/code-smell/no-unicode-literals.json +0 -7
  591. ansible_test/_util/controller/sanity/code-smell/no-unicode-literals.py +0 -21
  592. ansible_test/_util/controller/tools/sslcheck.py +0 -22
  593. ansible_test/_util/target/common/__init__.py +0 -2
  594. {ansible_core-2.16.7.dist-info → ansible_core-2.17.0.dist-info}/COPYING +0 -0
  595. {ansible_core-2.16.7.dist-info → ansible_core-2.17.0.dist-info}/WHEEL +0 -0
  596. {ansible_core-2.16.7.dist-info → ansible_core-2.17.0.dist-info}/entry_points.txt +0 -0
  597. {ansible_core-2.16.7.dist-info → ansible_core-2.17.0.dist-info}/top_level.txt +0 -0
@@ -1,11 +1,10 @@
1
1
  # Copyright (c), Toshio Kuratomi <tkuratomi@ansible.com> 2016
2
2
  # Simplified BSD License (see licenses/simplified_bsd.txt or https://opensource.org/licenses/BSD-2-Clause)
3
- from __future__ import (absolute_import, division, print_function)
4
- __metaclass__ = type
5
3
 
6
4
  """
7
5
  .. warn:: Use ansible.module_utils.common.text.converters instead.
8
6
  """
7
+ from __future__ import annotations
9
8
 
10
9
  # Backwards compat for people still calling it from this package
11
10
  # pylint: disable=unused-import
@@ -15,10 +15,8 @@
15
15
  # You should have received a copy of the GNU General Public License
16
16
  # along with Ansible. If not, see <http://www.gnu.org/licenses/>.
17
17
 
18
- # Make coding more python3-ish
19
- from __future__ import (absolute_import, division, print_function)
20
- __metaclass__ = type
18
+ from __future__ import annotations
21
19
 
22
- __version__ = '2.16.7'
20
+ __version__ = '2.17.0'
23
21
  __author__ = 'Ansible, Inc.'
24
- __codename__ = "All My Love"
22
+ __codename__ = "Gallows Pole"
@@ -23,8 +23,7 @@ The 'api' module provides the following common argument specs:
23
23
  - retries: number of attempts
24
24
  - retry_pause: delay between attempts in seconds
25
25
  """
26
- from __future__ import (absolute_import, division, print_function)
27
- __metaclass__ = type
26
+ from __future__ import annotations
28
27
 
29
28
  import copy
30
29
  import functools
@@ -2,22 +2,20 @@
2
2
  # Copyright (c), Toshio Kuratomi <tkuratomi@ansible.com> 2016
3
3
  # Simplified BSD License (see licenses/simplified_bsd.txt or https://opensource.org/licenses/BSD-2-Clause)
4
4
 
5
- from __future__ import absolute_import, division, print_function
6
- __metaclass__ = type
5
+ from __future__ import annotations
7
6
 
7
+ import json
8
8
  import sys
9
9
 
10
10
  # Used for determining if the system is running a new enough python version
11
11
  # and should only restrict on our documented minimum versions
12
- _PY3_MIN = sys.version_info >= (3, 6)
13
- _PY2_MIN = (2, 7) <= sys.version_info < (3,)
14
- _PY_MIN = _PY3_MIN or _PY2_MIN
15
-
16
- if not _PY_MIN:
17
- print(
18
- '\n{"failed": true, '
19
- '"msg": "ansible-core requires a minimum of Python2 version 2.7 or Python3 version 3.6. Current version: %s"}' % ''.join(sys.version.splitlines())
20
- )
12
+ _PY_MIN = (3, 7)
13
+
14
+ if sys.version_info < _PY_MIN:
15
+ print(json.dumps(dict(
16
+ failed=True,
17
+ msg=f"ansible-core requires a minimum of Python version {'.'.join(map(str, _PY_MIN))}. Current version: {''.join(sys.version.splitlines())}",
18
+ )))
21
19
  sys.exit(1)
22
20
 
23
21
  # Ansible modules can be written in any language.
@@ -27,7 +25,6 @@ if not _PY_MIN:
27
25
  import __main__
28
26
  import atexit
29
27
  import errno
30
- import datetime
31
28
  import grp
32
29
  import fcntl
33
30
  import locale
@@ -36,17 +33,16 @@ import pwd
36
33
  import platform
37
34
  import re
38
35
  import select
36
+ import selectors
39
37
  import shlex
40
38
  import shutil
41
- import signal
42
39
  import stat
43
40
  import subprocess
44
41
  import tempfile
45
42
  import time
46
43
  import traceback
47
- import types
48
44
 
49
- from itertools import chain, repeat
45
+ from functools import reduce
50
46
 
51
47
  try:
52
48
  import syslog
@@ -74,8 +70,6 @@ except ImportError:
74
70
  # Python2 & 3 way to get NoneType
75
71
  NoneType = type(None)
76
72
 
77
- from ansible.module_utils.compat import selectors
78
-
79
73
  from ._text import to_native, to_bytes, to_text
80
74
  from ansible.module_utils.common.text.converters import (
81
75
  jsonify,
@@ -97,21 +91,9 @@ import hashlib
97
91
 
98
92
  def _get_available_hash_algorithms():
99
93
  """Return a dictionary of available hash function names and their associated function."""
100
- try:
101
- # Algorithms available in Python 2.7.9+ and Python 3.2+
102
- # https://docs.python.org/2.7/library/hashlib.html#hashlib.algorithms_available
103
- # https://docs.python.org/3.2/library/hashlib.html#hashlib.algorithms_available
104
- algorithm_names = hashlib.algorithms_available
105
- except AttributeError:
106
- # Algorithms in Python 2.7.x (used only for Python 2.7.0 through 2.7.8)
107
- # https://docs.python.org/2.7/library/hashlib.html#hashlib.hashlib.algorithms
108
- algorithm_names = set(hashlib.algorithms)
109
-
110
94
  algorithms = {}
111
-
112
- for algorithm_name in algorithm_names:
95
+ for algorithm_name in hashlib.algorithms_available:
113
96
  algorithm_func = getattr(hashlib, algorithm_name, None)
114
-
115
97
  if algorithm_func:
116
98
  try:
117
99
  # Make sure the algorithm is actually available for use.
@@ -128,12 +110,6 @@ def _get_available_hash_algorithms():
128
110
 
129
111
  AVAILABLE_HASH_ALGORITHMS = _get_available_hash_algorithms()
130
112
 
131
- try:
132
- from ansible.module_utils.common._json_compat import json
133
- except ImportError as e:
134
- print('\n{{"msg": "Error: ansible requires the stdlib json: {0}", "failed": true}}'.format(to_native(e)))
135
- sys.exit(1)
136
-
137
113
  from ansible.module_utils.six.moves.collections_abc import (
138
114
  KeysView,
139
115
  Mapping, MutableMapping,
@@ -144,19 +120,19 @@ from ansible.module_utils.common.locale import get_best_parsable_locale
144
120
  from ansible.module_utils.common.process import get_bin_path
145
121
  from ansible.module_utils.common.file import (
146
122
  _PERM_BITS as PERM_BITS,
147
- _EXEC_PERM_BITS as EXEC_PERM_BITS,
148
123
  _DEFAULT_PERM as DEFAULT_PERM,
149
124
  is_executable,
150
125
  format_attributes,
151
126
  get_flags_from_attributes,
152
127
  FILE_ATTRIBUTES,
128
+ S_IXANY,
129
+ S_IRWU_RWG_RWO,
153
130
  )
154
131
  from ansible.module_utils.common.sys_info import (
155
132
  get_distribution,
156
133
  get_distribution_version,
157
134
  get_platform_subclass,
158
135
  )
159
- from ansible.module_utils.pycompat24 import get_exception, literal_eval
160
136
  from ansible.module_utils.common.parameters import (
161
137
  env_fallback,
162
138
  remove_values,
@@ -167,17 +143,6 @@ from ansible.module_utils.common.parameters import (
167
143
  )
168
144
 
169
145
  from ansible.module_utils.errors import AnsibleFallbackNotFound, AnsibleValidationErrorMultiple, UnsupportedError
170
- from ansible.module_utils.six import (
171
- PY2,
172
- PY3,
173
- b,
174
- binary_type,
175
- integer_types,
176
- iteritems,
177
- string_types,
178
- text_type,
179
- )
180
- from ansible.module_utils.six.moves import map, reduce, shlex_quote
181
146
  from ansible.module_utils.common.validation import (
182
147
  check_missing_parameters,
183
148
  safe_eval,
@@ -199,24 +164,6 @@ PASSWORD_MATCH = re.compile(r'^(?:.+[-_\s])?pass(?:[-_\s]?(?:word|phrase|wrd|wd)
199
164
 
200
165
  imap = map
201
166
 
202
- try:
203
- # Python 2
204
- unicode # type: ignore[used-before-def] # pylint: disable=used-before-assignment
205
- except NameError:
206
- # Python 3
207
- unicode = text_type
208
-
209
- try:
210
- # Python 2
211
- basestring # type: ignore[used-before-def,has-type] # pylint: disable=used-before-assignment
212
- except NameError:
213
- # Python 3
214
- basestring = string_types
215
-
216
- _literal_eval = literal_eval
217
-
218
- # End of deprecated names
219
-
220
167
  # Internal global holding passed in params. This is consulted in case
221
168
  # multiple AnsibleModules are created. Otherwise each AnsibleModule would
222
169
  # attempt to read from stdin. Other code should not use this directly as it
@@ -373,33 +320,25 @@ def _load_params():
373
320
  buffer = fd.read()
374
321
  fd.close()
375
322
  else:
376
- buffer = sys.argv[1]
377
- if PY3:
378
- buffer = buffer.encode('utf-8', errors='surrogateescape')
323
+ buffer = sys.argv[1].encode('utf-8', errors='surrogateescape')
379
324
  # default case, read from stdin
380
325
  else:
381
- if PY2:
382
- buffer = sys.stdin.read()
383
- else:
384
- buffer = sys.stdin.buffer.read()
326
+ buffer = sys.stdin.buffer.read()
385
327
  _ANSIBLE_ARGS = buffer
386
328
 
387
329
  try:
388
330
  params = json.loads(buffer.decode('utf-8'))
389
331
  except ValueError:
390
- # This helper used too early for fail_json to work.
391
- print('\n{"msg": "Error: Module unable to decode valid JSON on stdin. Unable to figure out what parameters were passed", "failed": true}')
332
+ # This helper is used too early for fail_json to work.
333
+ print('\n{"msg": "Error: Module unable to decode stdin/parameters as valid JSON. Unable to parse what parameters were passed", "failed": true}')
392
334
  sys.exit(1)
393
335
 
394
- if PY2:
395
- params = json_dict_unicode_to_bytes(params)
396
-
397
336
  try:
398
337
  return params['ANSIBLE_MODULE_ARGS']
399
338
  except KeyError:
400
339
  # This helper does not have access to fail_json so we have to print
401
340
  # json output on our own.
402
- print('\n{"msg": "Error: Module unable to locate ANSIBLE_MODULE_ARGS in json data from stdin. Unable to figure out what parameters were passed", '
341
+ print('\n{"msg": "Error: Module unable to locate ANSIBLE_MODULE_ARGS in JSON data from stdin. Unable to figure out what parameters were passed", '
403
342
  '"failed": true}')
404
343
  sys.exit(1)
405
344
 
@@ -492,6 +431,8 @@ class AnsibleModule(object):
492
431
 
493
432
  try:
494
433
  error = self.validation_result.errors[0]
434
+ if isinstance(error, UnsupportedError) and self._ignore_unknown_opts:
435
+ error = None
495
436
  except IndexError:
496
437
  error = None
497
438
 
@@ -568,7 +509,7 @@ class AnsibleModule(object):
568
509
  raise AssertionError("implementation error -- version and date must not both be set")
569
510
  deprecate(msg, version=version, date=date, collection_name=collection_name)
570
511
  # For compatibility, we accept that neither version nor date is set,
571
- # and treat that the same as if version would haven been set
512
+ # and treat that the same as if version would not have been set
572
513
  if date is not None:
573
514
  self.log('[DEPRECATION WARNING] %s %s' % (msg, date))
574
515
  else:
@@ -695,7 +636,7 @@ class AnsibleModule(object):
695
636
 
696
637
  def find_mount_point(self, path):
697
638
  '''
698
- Takes a path and returns it's mount point
639
+ Takes a path and returns its mount point
699
640
 
700
641
  :param path: a string type with a filesystem path
701
642
  :returns: the path to the mount point as a text type
@@ -891,7 +832,7 @@ class AnsibleModule(object):
891
832
  details=to_native(e))
892
833
 
893
834
  if mode != stat.S_IMODE(mode):
894
- # prevent mode from having extra info orbeing invalid long number
835
+ # prevent mode from having extra info or being invalid long number
895
836
  path = to_text(b_path)
896
837
  self.fail_json(path=path, msg="Invalid mode supplied, only permission info is allowed", details=mode)
897
838
 
@@ -968,7 +909,7 @@ class AnsibleModule(object):
968
909
  attr_mod = attributes[0]
969
910
  attributes = attributes[1:]
970
911
 
971
- if existing.get('attr_flags', '') != attributes or attr_mod == '-':
912
+ if attributes and (existing.get('attr_flags', '') != attributes or attr_mod == '-'):
972
913
  attrcmd = self.get_bin_path('chattr')
973
914
  if attrcmd:
974
915
  attrcmd = [attrcmd, '%s%s' % (attr_mod, attributes), b_path]
@@ -1081,7 +1022,7 @@ class AnsibleModule(object):
1081
1022
  if prev_mode is None:
1082
1023
  prev_mode = stat.S_IMODE(path_stat.st_mode)
1083
1024
  is_directory = stat.S_ISDIR(path_stat.st_mode)
1084
- has_x_permissions = (prev_mode & EXEC_PERM_BITS) > 0
1025
+ has_x_permissions = (prev_mode & S_IXANY) > 0
1085
1026
  apply_X_permission = is_directory or has_x_permissions
1086
1027
 
1087
1028
  # Get the umask, if the 'user' part is empty, the effect is as if (a) were
@@ -1279,7 +1220,7 @@ class AnsibleModule(object):
1279
1220
  facility = getattr(syslog, self._syslog_facility, syslog.LOG_USER)
1280
1221
  syslog.openlog(str(module), 0, facility)
1281
1222
  syslog.syslog(syslog.LOG_INFO, msg)
1282
- except TypeError as e:
1223
+ except (TypeError, ValueError) as e:
1283
1224
  self.fail_json(
1284
1225
  msg='Failed to log to syslog (%s). To proceed anyway, '
1285
1226
  'disable syslog logging by setting no_target_syslog '
@@ -1300,25 +1241,26 @@ class AnsibleModule(object):
1300
1241
  log_args = dict()
1301
1242
 
1302
1243
  module = 'ansible-%s' % self._name
1303
- if isinstance(module, binary_type):
1244
+ if isinstance(module, bytes):
1304
1245
  module = module.decode('utf-8', 'replace')
1305
1246
 
1306
1247
  # 6655 - allow for accented characters
1307
- if not isinstance(msg, (binary_type, text_type)):
1248
+ if not isinstance(msg, (bytes, str)):
1308
1249
  raise TypeError("msg should be a string (got %s)" % type(msg))
1309
1250
 
1310
1251
  # We want journal to always take text type
1311
1252
  # syslog takes bytes on py2, text type on py3
1312
- if isinstance(msg, binary_type):
1313
- journal_msg = remove_values(msg.decode('utf-8', 'replace'), self.no_log_values)
1253
+ if isinstance(msg, bytes):
1254
+ journal_msg = msg.decode('utf-8', 'replace')
1314
1255
  else:
1315
1256
  # TODO: surrogateescape is a danger here on Py3
1316
- journal_msg = remove_values(msg, self.no_log_values)
1257
+ journal_msg = msg
1317
1258
 
1318
- if PY3:
1319
- syslog_msg = journal_msg
1320
- else:
1321
- syslog_msg = journal_msg.encode('utf-8', 'replace')
1259
+ if self._target_log_info:
1260
+ journal_msg = ' '.join([self._target_log_info, journal_msg])
1261
+
1262
+ # ensure we clean up secrets!
1263
+ journal_msg = remove_values(journal_msg, self.no_log_values)
1322
1264
 
1323
1265
  if has_journal:
1324
1266
  journal_args = [("MODULE", os.path.basename(__file__))]
@@ -1349,9 +1291,9 @@ class AnsibleModule(object):
1349
1291
  **dict(journal_args))
1350
1292
  except IOError:
1351
1293
  # fall back to syslog since logging to journal failed
1352
- self._log_to_syslog(syslog_msg)
1294
+ self._log_to_syslog(journal_msg)
1353
1295
  else:
1354
- self._log_to_syslog(syslog_msg)
1296
+ self._log_to_syslog(journal_msg)
1355
1297
 
1356
1298
  def _log_invocation(self):
1357
1299
  ''' log that ansible ran the module '''
@@ -1372,9 +1314,9 @@ class AnsibleModule(object):
1372
1314
  log_args[param] = 'NOT_LOGGING_PARAMETER'
1373
1315
  else:
1374
1316
  param_val = self.params[param]
1375
- if not isinstance(param_val, (text_type, binary_type)):
1317
+ if not isinstance(param_val, (str, bytes)):
1376
1318
  param_val = str(param_val)
1377
- elif isinstance(param_val, text_type):
1319
+ elif isinstance(param_val, str):
1378
1320
  param_val = param_val.encode('utf-8')
1379
1321
  log_args[param] = heuristic_log_sanitize(param_val, self.no_log_values)
1380
1322
 
@@ -1520,12 +1462,7 @@ class AnsibleModule(object):
1520
1462
  # Add traceback if debug or high verbosity and it is missing
1521
1463
  # NOTE: Badly named as exception, it really always has been a traceback
1522
1464
  if 'exception' not in kwargs and sys.exc_info()[2] and (self._debug or self._verbosity >= 3):
1523
- if PY2:
1524
- # On Python 2 this is the last (stack frame) exception and as such may be unrelated to the failure
1525
- kwargs['exception'] = 'WARNING: The below traceback may *not* be related to the actual failure.\n' +\
1526
- ''.join(traceback.format_tb(sys.exc_info()[2]))
1527
- else:
1528
- kwargs['exception'] = ''.join(traceback.format_tb(sys.exc_info()[2]))
1465
+ kwargs['exception'] = ''.join(traceback.format_tb(sys.exc_info()[2]))
1529
1466
 
1530
1467
  self.do_cleanup_files()
1531
1468
  self._return_formatted(kwargs)
@@ -1648,7 +1585,7 @@ class AnsibleModule(object):
1648
1585
  current_attribs = current_attribs.get('attr_flags', '')
1649
1586
  self.set_attributes_if_different(dest, current_attribs, True)
1650
1587
 
1651
- def atomic_move(self, src, dest, unsafe_writes=False):
1588
+ def atomic_move(self, src, dest, unsafe_writes=False, keep_dest_attrs=True):
1652
1589
  '''atomically move src to dest, copying attributes from dest, returns true on success
1653
1590
  it uses os.rename to ensure this as it is an atomic operation, rest of the function is
1654
1591
  to work around limitations, corner cases and ensure selinux context is saved if possible'''
@@ -1656,24 +1593,11 @@ class AnsibleModule(object):
1656
1593
  dest_stat = None
1657
1594
  b_src = to_bytes(src, errors='surrogate_or_strict')
1658
1595
  b_dest = to_bytes(dest, errors='surrogate_or_strict')
1659
- if os.path.exists(b_dest):
1596
+ if os.path.exists(b_dest) and keep_dest_attrs:
1660
1597
  try:
1661
1598
  dest_stat = os.stat(b_dest)
1662
-
1663
- # copy mode and ownership
1664
- os.chmod(b_src, dest_stat.st_mode & PERM_BITS)
1665
1599
  os.chown(b_src, dest_stat.st_uid, dest_stat.st_gid)
1666
-
1667
- # try to copy flags if possible
1668
- if hasattr(os, 'chflags') and hasattr(dest_stat, 'st_flags'):
1669
- try:
1670
- os.chflags(b_src, dest_stat.st_flags)
1671
- except OSError as e:
1672
- for err in 'EOPNOTSUPP', 'ENOTSUP':
1673
- if hasattr(errno, err) and e.errno == getattr(errno, err):
1674
- break
1675
- else:
1676
- raise
1600
+ shutil.copystat(b_dest, b_src)
1677
1601
  except OSError as e:
1678
1602
  if e.errno != errno.EPERM:
1679
1603
  raise
@@ -1721,18 +1645,21 @@ class AnsibleModule(object):
1721
1645
  os.close(tmp_dest_fd)
1722
1646
  # leaves tmp file behind when sudo and not root
1723
1647
  try:
1724
- shutil.move(b_src, b_tmp_dest_name)
1648
+ shutil.move(b_src, b_tmp_dest_name, copy_function=shutil.copy if keep_dest_attrs else shutil.copy2)
1725
1649
  except OSError:
1726
1650
  # cleanup will happen by 'rm' of tmpdir
1727
1651
  # copy2 will preserve some metadata
1728
- shutil.copy2(b_src, b_tmp_dest_name)
1652
+ if keep_dest_attrs:
1653
+ shutil.copy(b_src, b_tmp_dest_name)
1654
+ else:
1655
+ shutil.copy2(b_src, b_tmp_dest_name)
1729
1656
 
1730
1657
  if self.selinux_enabled():
1731
1658
  self.set_context_if_different(
1732
1659
  b_tmp_dest_name, context, False)
1733
1660
  try:
1734
1661
  tmp_stat = os.stat(b_tmp_dest_name)
1735
- if dest_stat and (tmp_stat.st_uid != dest_stat.st_uid or tmp_stat.st_gid != dest_stat.st_gid):
1662
+ if keep_dest_attrs and dest_stat and (tmp_stat.st_uid != dest_stat.st_uid or tmp_stat.st_gid != dest_stat.st_gid):
1736
1663
  os.chown(b_tmp_dest_name, dest_stat.st_uid, dest_stat.st_gid)
1737
1664
  except OSError as e:
1738
1665
  if e.errno != errno.EPERM:
@@ -1758,7 +1685,7 @@ class AnsibleModule(object):
1758
1685
  # based on the current value of umask
1759
1686
  umask = os.umask(0)
1760
1687
  os.umask(umask)
1761
- os.chmod(b_dest, DEFAULT_PERM & ~umask)
1688
+ os.chmod(b_dest, S_IRWU_RWG_RWO & ~umask)
1762
1689
  try:
1763
1690
  os.chown(b_dest, os.geteuid(), os.getegid())
1764
1691
  except OSError:
@@ -1794,13 +1721,9 @@ class AnsibleModule(object):
1794
1721
  # create a printable version of the command for use in reporting later,
1795
1722
  # which strips out things like passwords from the args list
1796
1723
  to_clean_args = args
1797
- if PY2:
1798
- if isinstance(args, text_type):
1799
- to_clean_args = to_bytes(args)
1800
- else:
1801
- if isinstance(args, binary_type):
1802
- to_clean_args = to_text(args)
1803
- if isinstance(args, (text_type, binary_type)):
1724
+ if isinstance(args, bytes):
1725
+ to_clean_args = to_text(args)
1726
+ if isinstance(args, (str, bytes)):
1804
1727
  to_clean_args = shlex.split(to_clean_args)
1805
1728
 
1806
1729
  clean_args = []
@@ -1819,15 +1742,10 @@ class AnsibleModule(object):
1819
1742
  is_passwd = True
1820
1743
  arg = heuristic_log_sanitize(arg, self.no_log_values)
1821
1744
  clean_args.append(arg)
1822
- self._clean = ' '.join(shlex_quote(arg) for arg in clean_args)
1745
+ self._clean = ' '.join(shlex.quote(arg) for arg in clean_args)
1823
1746
 
1824
1747
  return self._clean
1825
1748
 
1826
- def _restore_signal_handlers(self):
1827
- # Reset SIGPIPE to SIG_DFL, otherwise in Python2.7 it gets ignored in subprocesses.
1828
- if PY2 and sys.platform != 'win32':
1829
- signal.signal(signal.SIGPIPE, signal.SIG_DFL)
1830
-
1831
1749
  def run_command(self, args, check_rc=False, close_fds=True, executable=None, data=None, binary_data=False, path_prefix=None, cwd=None,
1832
1750
  use_unsafe_shell=False, prompt_regex=None, environ_update=None, umask=None, encoding='utf-8', errors='surrogate_or_strict',
1833
1751
  expand_user_and_vars=True, pass_fds=None, before_communicate_callback=None, ignore_invalid_cwd=True, handle_exceptions=True):
@@ -1904,7 +1822,7 @@ class AnsibleModule(object):
1904
1822
  # used by clean args later on
1905
1823
  self._clean = None
1906
1824
 
1907
- if not isinstance(args, (list, binary_type, text_type)):
1825
+ if not isinstance(args, (list, bytes, str)):
1908
1826
  msg = "Argument 'args' to run_command must be list or string"
1909
1827
  self.fail_json(rc=257, cmd=args, msg=msg)
1910
1828
 
@@ -1913,7 +1831,7 @@ class AnsibleModule(object):
1913
1831
 
1914
1832
  # stringify args for unsafe/direct shell usage
1915
1833
  if isinstance(args, list):
1916
- args = b" ".join([to_bytes(shlex_quote(x), errors='surrogate_or_strict') for x in args])
1834
+ args = b" ".join([to_bytes(shlex.quote(x), errors='surrogate_or_strict') for x in args])
1917
1835
  else:
1918
1836
  args = to_bytes(args, errors='surrogate_or_strict')
1919
1837
 
@@ -1927,14 +1845,8 @@ class AnsibleModule(object):
1927
1845
  shell = True
1928
1846
  else:
1929
1847
  # ensure args are a list
1930
- if isinstance(args, (binary_type, text_type)):
1931
- # On python2.6 and below, shlex has problems with text type
1932
- # On python3, shlex needs a text type.
1933
- if PY2:
1934
- args = to_bytes(args, errors='surrogate_or_strict')
1935
- elif PY3:
1936
- args = to_text(args, errors='surrogateescape')
1937
- args = shlex.split(args)
1848
+ if isinstance(args, (bytes, str)):
1849
+ args = shlex.split(to_text(args, errors='surrogateescape'))
1938
1850
 
1939
1851
  # expand ``~`` in paths, and all environment vars
1940
1852
  if expand_user_and_vars:
@@ -1944,11 +1856,8 @@ class AnsibleModule(object):
1944
1856
 
1945
1857
  prompt_re = None
1946
1858
  if prompt_regex:
1947
- if isinstance(prompt_regex, text_type):
1948
- if PY3:
1949
- prompt_regex = to_bytes(prompt_regex, errors='surrogateescape')
1950
- elif PY2:
1951
- prompt_regex = to_bytes(prompt_regex, errors='surrogate_or_strict')
1859
+ if isinstance(prompt_regex, str):
1860
+ prompt_regex = to_bytes(prompt_regex, errors='surrogateescape')
1952
1861
  try:
1953
1862
  prompt_re = re.compile(prompt_regex, re.MULTILINE)
1954
1863
  except re.error:
@@ -1987,7 +1896,6 @@ class AnsibleModule(object):
1987
1896
  st_in = subprocess.PIPE
1988
1897
 
1989
1898
  def preexec():
1990
- self._restore_signal_handlers()
1991
1899
  if umask:
1992
1900
  os.umask(umask)
1993
1901
 
@@ -2001,10 +1909,8 @@ class AnsibleModule(object):
2001
1909
  preexec_fn=preexec,
2002
1910
  env=env,
2003
1911
  )
2004
- if PY3 and pass_fds:
1912
+ if pass_fds:
2005
1913
  kwargs["pass_fds"] = pass_fds
2006
- elif PY2 and pass_fds:
2007
- kwargs['close_fds'] = False
2008
1914
 
2009
1915
  # make sure we're in the right working directory
2010
1916
  if cwd:
@@ -2036,7 +1942,7 @@ class AnsibleModule(object):
2036
1942
  if data:
2037
1943
  if not binary_data:
2038
1944
  data += '\n'
2039
- if isinstance(data, text_type):
1945
+ if isinstance(data, str):
2040
1946
  data = to_bytes(data)
2041
1947
 
2042
1948
  selector.register(cmd.stdout, selectors.EVENT_READ)
@@ -2155,3 +2061,52 @@ class AnsibleModule(object):
2155
2061
 
2156
2062
  def get_module_path():
2157
2063
  return os.path.dirname(os.path.realpath(__file__))
2064
+
2065
+
2066
+ def __getattr__(importable_name):
2067
+ """Inject import-time deprecation warnings."""
2068
+ if importable_name == 'get_exception':
2069
+ from ansible.module_utils.pycompat24 import get_exception
2070
+ importable = get_exception
2071
+ elif importable_name in {'literal_eval', '_literal_eval'}:
2072
+ from ast import literal_eval
2073
+ importable = literal_eval
2074
+ elif importable_name == 'datetime':
2075
+ import datetime
2076
+ importable = datetime
2077
+ elif importable_name == 'signal':
2078
+ import signal
2079
+ importable = signal
2080
+ elif importable_name == 'types':
2081
+ import types
2082
+ importable = types
2083
+ elif importable_name == 'chain':
2084
+ from itertools import chain
2085
+ importable = chain
2086
+ elif importable_name == 'repeat':
2087
+ from itertools import repeat
2088
+ importable = repeat
2089
+ elif importable_name in {
2090
+ 'PY2', 'PY3', 'b', 'binary_type', 'integer_types',
2091
+ 'iteritems', 'string_types', 'test_type'
2092
+ }:
2093
+ import importlib
2094
+ importable = getattr(
2095
+ importlib.import_module('ansible.module_utils.six'),
2096
+ importable_name
2097
+ )
2098
+ elif importable_name == 'map':
2099
+ importable = map
2100
+ elif importable_name == 'shlex_quote':
2101
+ importable = shlex.quote
2102
+ else:
2103
+ raise AttributeError(
2104
+ f'cannot import name {importable_name !r} '
2105
+ f"from '{__name__}' ({__file__ !s})"
2106
+ )
2107
+
2108
+ deprecate(
2109
+ msg=f"Importing '{importable_name}' from '{__name__}' is deprecated.",
2110
+ version="2.21",
2111
+ )
2112
+ return importable
@@ -6,8 +6,7 @@ Use `ansible.module_utils.six.moves.collections_abc` instead, which has been ava
6
6
  This module exists only for backwards compatibility.
7
7
  """
8
8
 
9
- from __future__ import absolute_import, division, print_function
10
- __metaclass__ = type
9
+ from __future__ import annotations
11
10
 
12
11
  # Although this was originally intended for internal use only, it has wide adoption in collections.
13
12
  # This is due in part to sanity tests previously recommending its use over `collections` imports.
@@ -1,14 +1,12 @@
1
1
  # Copyright (c) 2018, Ansible Project
2
2
  # Simplified BSD License (see licenses/simplified_bsd.txt or https://opensource.org/licenses/BSD-2-Clause)
3
3
 
4
- from __future__ import absolute_import, division, print_function
5
- __metaclass__ = type
6
-
7
4
 
8
5
  """
9
6
  Modules in _utils are waiting to find a better home. If you need to use them, be prepared for them
10
7
  to move to a different location in the future.
11
8
  """
9
+ from __future__ import annotations
12
10
 
13
11
 
14
12
  def get_all_subclasses(cls):
@@ -2,8 +2,7 @@
2
2
  # Copyright (c) 2021 Ansible Project
3
3
  # Simplified BSD License (see licenses/simplified_bsd.txt or https://opensource.org/licenses/BSD-2-Clause)
4
4
 
5
- from __future__ import absolute_import, division, print_function
6
- __metaclass__ = type
5
+ from __future__ import annotations
7
6
 
8
7
  from copy import deepcopy
9
8
 
@@ -3,8 +3,7 @@
3
3
  # Simplified BSD License (see licenses/simplified_bsd.txt or https://opensource.org/licenses/BSD-2-Clause)
4
4
  """Collection of low-level utility functions."""
5
5
 
6
- from __future__ import absolute_import, division, print_function
7
- __metaclass__ = type
6
+ from __future__ import annotations
8
7
 
9
8
 
10
9
  from ansible.module_utils.six import binary_type, text_type
@@ -3,8 +3,7 @@
3
3
  # Copyright: (c) 2018, Ansible Project
4
4
  # GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
5
5
 
6
- from __future__ import absolute_import, division, print_function
7
- __metaclass__ = type
6
+ from __future__ import annotations
8
7
 
9
8
 
10
9
  import re