ansible-core 2.15.4rc1__py3-none-any.whl → 2.16.0b2__py3-none-any.whl

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

Potentially problematic release.


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

Files changed (427) hide show
  1. ansible/cli/__init__.py +3 -3
  2. ansible/cli/adhoc.py +1 -1
  3. ansible/cli/arguments/option_helpers.py +15 -5
  4. ansible/cli/config.py +2 -2
  5. ansible/cli/console.py +21 -17
  6. ansible/cli/doc.py +8 -9
  7. ansible/cli/galaxy.py +60 -27
  8. ansible/cli/inventory.py +1 -1
  9. ansible/cli/playbook.py +1 -1
  10. ansible/cli/pull.py +2 -2
  11. ansible/cli/scripts/ansible_connection_cli_stub.py +1 -1
  12. ansible/cli/vault.py +11 -6
  13. ansible/collections/__init__.py +0 -29
  14. ansible/collections/list.py +23 -44
  15. ansible/config/ansible_builtin_runtime.yml +8 -4
  16. ansible/config/base.yml +34 -22
  17. ansible/config/manager.py +1 -1
  18. ansible/constants.py +3 -5
  19. ansible/errors/__init__.py +1 -1
  20. ansible/executor/interpreter_discovery.py +1 -1
  21. ansible/executor/module_common.py +39 -32
  22. ansible/executor/play_iterator.py +0 -15
  23. ansible/executor/playbook_executor.py +3 -3
  24. ansible/executor/powershell/module_manifest.py +1 -1
  25. ansible/executor/powershell/module_wrapper.ps1 +4 -1
  26. ansible/executor/process/worker.py +22 -7
  27. ansible/executor/task_executor.py +39 -40
  28. ansible/executor/task_queue_manager.py +8 -11
  29. ansible/galaxy/__init__.py +1 -1
  30. ansible/galaxy/api.py +8 -11
  31. ansible/galaxy/collection/__init__.py +17 -4
  32. ansible/galaxy/collection/concrete_artifact_manager.py +7 -2
  33. ansible/galaxy/collection/galaxy_api_proxy.py +1 -1
  34. ansible/galaxy/data/container/README.md +3 -5
  35. ansible/galaxy/dependency_resolution/__init__.py +1 -6
  36. ansible/galaxy/dependency_resolution/dataclasses.py +22 -1
  37. ansible/galaxy/dependency_resolution/providers.py +61 -69
  38. ansible/galaxy/role.py +31 -13
  39. ansible/galaxy/token.py +2 -2
  40. ansible/inventory/group.py +1 -1
  41. ansible/inventory/manager.py +1 -1
  42. ansible/module_utils/ansible_release.py +2 -2
  43. ansible/module_utils/basic.py +11 -41
  44. ansible/module_utils/common/file.py +0 -100
  45. ansible/module_utils/common/json.py +1 -1
  46. ansible/module_utils/common/locale.py +1 -1
  47. ansible/module_utils/common/text/converters.py +2 -2
  48. ansible/module_utils/common/validation.py +1 -1
  49. ansible/module_utils/compat/_selectors2.py +4 -4
  50. ansible/module_utils/compat/datetime.py +40 -0
  51. ansible/module_utils/compat/selinux.py +1 -1
  52. ansible/module_utils/compat/typing.py +1 -1
  53. ansible/module_utils/connection.py +1 -1
  54. ansible/module_utils/facts/hardware/linux.py +2 -2
  55. ansible/module_utils/facts/hardware/openbsd.py +1 -1
  56. ansible/module_utils/facts/network/linux.py +3 -3
  57. ansible/module_utils/facts/other/facter.py +8 -15
  58. ansible/module_utils/facts/sysctl.py +1 -1
  59. ansible/module_utils/facts/system/date_time.py +2 -2
  60. ansible/module_utils/facts/system/distribution.py +1 -1
  61. ansible/module_utils/facts/system/local.py +6 -2
  62. ansible/module_utils/facts/system/pkg_mgr.py +6 -1
  63. ansible/module_utils/facts/system/service_mgr.py +4 -2
  64. ansible/module_utils/parsing/convert_bool.py +1 -1
  65. ansible/module_utils/service.py +9 -6
  66. ansible/module_utils/urls.py +40 -22
  67. ansible/modules/add_host.py +2 -2
  68. ansible/modules/apt.py +48 -31
  69. ansible/modules/apt_key.py +4 -4
  70. ansible/modules/apt_repository.py +5 -5
  71. ansible/modules/assemble.py +7 -7
  72. ansible/modules/assert.py +1 -1
  73. ansible/modules/async_status.py +11 -7
  74. ansible/modules/async_wrapper.py +1 -1
  75. ansible/modules/blockinfile.py +60 -17
  76. ansible/modules/command.py +37 -15
  77. ansible/modules/copy.py +35 -30
  78. ansible/modules/cron.py +14 -14
  79. ansible/modules/deb822_repository.py +4 -3
  80. ansible/modules/debconf.py +35 -14
  81. ansible/modules/debug.py +1 -1
  82. ansible/modules/dnf.py +29 -27
  83. ansible/modules/dnf5.py +22 -22
  84. ansible/modules/dpkg_selections.py +9 -2
  85. ansible/modules/expect.py +4 -4
  86. ansible/modules/fetch.py +7 -7
  87. ansible/modules/file.py +30 -30
  88. ansible/modules/find.py +82 -22
  89. ansible/modules/gather_facts.py +6 -2
  90. ansible/modules/get_url.py +29 -29
  91. ansible/modules/getent.py +4 -4
  92. ansible/modules/git.py +27 -27
  93. ansible/modules/group.py +5 -12
  94. ansible/modules/hostname.py +21 -2
  95. ansible/modules/include_role.py +5 -5
  96. ansible/modules/include_tasks.py +2 -2
  97. ansible/modules/include_vars.py +5 -5
  98. ansible/modules/iptables.py +70 -65
  99. ansible/modules/known_hosts.py +7 -7
  100. ansible/modules/lineinfile.py +33 -33
  101. ansible/modules/meta.py +13 -13
  102. ansible/modules/package.py +8 -8
  103. ansible/modules/package_facts.py +3 -3
  104. ansible/modules/pause.py +2 -2
  105. ansible/modules/ping.py +5 -5
  106. ansible/modules/pip.py +80 -46
  107. ansible/modules/reboot.py +8 -4
  108. ansible/modules/replace.py +20 -15
  109. ansible/modules/rpm_key.py +2 -2
  110. ansible/modules/script.py +16 -10
  111. ansible/modules/service.py +26 -98
  112. ansible/modules/service_facts.py +36 -12
  113. ansible/modules/set_fact.py +2 -2
  114. ansible/modules/set_stats.py +2 -2
  115. ansible/modules/setup.py +18 -18
  116. ansible/modules/shell.py +3 -3
  117. ansible/modules/stat.py +9 -30
  118. ansible/modules/subversion.py +9 -9
  119. ansible/modules/systemd.py +20 -19
  120. ansible/modules/systemd_service.py +20 -19
  121. ansible/modules/sysvinit.py +26 -21
  122. ansible/modules/tempfile.py +5 -4
  123. ansible/modules/template.py +60 -6
  124. ansible/modules/unarchive.py +21 -18
  125. ansible/modules/uri.py +39 -39
  126. ansible/modules/user.py +81 -53
  127. ansible/modules/wait_for.py +22 -21
  128. ansible/modules/wait_for_connection.py +4 -4
  129. ansible/modules/yum.py +38 -38
  130. ansible/modules/yum_repository.py +58 -80
  131. ansible/parsing/dataloader.py +27 -27
  132. ansible/parsing/mod_args.py +1 -1
  133. ansible/parsing/plugin_docs.py +3 -3
  134. ansible/parsing/splitter.py +14 -16
  135. ansible/parsing/utils/yaml.py +1 -1
  136. ansible/parsing/vault/__init__.py +8 -6
  137. ansible/parsing/yaml/constructor.py +1 -1
  138. ansible/parsing/yaml/objects.py +1 -1
  139. ansible/playbook/__init__.py +1 -1
  140. ansible/playbook/base.py +2 -2
  141. ansible/playbook/block.py +0 -1
  142. ansible/playbook/conditional.py +40 -114
  143. ansible/playbook/helpers.py +5 -28
  144. ansible/playbook/included_file.py +8 -7
  145. ansible/playbook/play.py +1 -1
  146. ansible/playbook/play_context.py +2 -2
  147. ansible/playbook/playbook_include.py +2 -2
  148. ansible/playbook/role/__init__.py +1 -1
  149. ansible/playbook/role/include.py +1 -1
  150. ansible/playbook/role/metadata.py +1 -1
  151. ansible/playbook/role_include.py +1 -1
  152. ansible/playbook/task.py +2 -2
  153. ansible/playbook/task_include.py +1 -24
  154. ansible/plugins/__init__.py +13 -5
  155. ansible/plugins/action/__init__.py +17 -43
  156. ansible/plugins/action/add_host.py +2 -3
  157. ansible/plugins/action/assemble.py +1 -1
  158. ansible/plugins/action/assert.py +2 -1
  159. ansible/plugins/action/copy.py +2 -2
  160. ansible/plugins/action/debug.py +2 -1
  161. ansible/plugins/action/fail.py +1 -0
  162. ansible/plugins/action/fetch.py +3 -1
  163. ansible/plugins/action/gather_facts.py +37 -13
  164. ansible/plugins/action/group_by.py +1 -0
  165. ansible/plugins/action/include_vars.py +3 -2
  166. ansible/plugins/action/normal.py +3 -3
  167. ansible/plugins/action/pause.py +1 -1
  168. ansible/plugins/action/reboot.py +21 -16
  169. ansible/plugins/action/script.py +23 -8
  170. ansible/plugins/action/set_fact.py +1 -0
  171. ansible/plugins/action/set_stats.py +1 -0
  172. ansible/plugins/action/shell.py +6 -0
  173. ansible/plugins/action/template.py +1 -1
  174. ansible/plugins/action/unarchive.py +1 -1
  175. ansible/plugins/action/uri.py +1 -1
  176. ansible/plugins/action/validate_argument_spec.py +1 -0
  177. ansible/plugins/action/wait_for_connection.py +4 -4
  178. ansible/plugins/become/__init__.py +1 -1
  179. ansible/plugins/become/su.py +1 -1
  180. ansible/plugins/cache/__init__.py +1 -1
  181. ansible/plugins/callback/junit.py +1 -1
  182. ansible/plugins/callback/oneline.py +1 -1
  183. ansible/plugins/callback/tree.py +1 -1
  184. ansible/plugins/cliconf/__init__.py +2 -2
  185. ansible/plugins/connection/__init__.py +65 -37
  186. ansible/plugins/connection/local.py +9 -8
  187. ansible/plugins/connection/paramiko_ssh.py +34 -28
  188. ansible/plugins/connection/psrp.py +56 -43
  189. ansible/plugins/connection/ssh.py +67 -43
  190. ansible/plugins/connection/winrm.py +77 -30
  191. ansible/plugins/doc_fragments/constructed.py +4 -4
  192. ansible/plugins/doc_fragments/files.py +12 -12
  193. ansible/plugins/doc_fragments/inventory_cache.py +0 -6
  194. ansible/plugins/doc_fragments/result_format_callback.py +5 -5
  195. ansible/plugins/doc_fragments/shell_common.py +2 -2
  196. ansible/plugins/doc_fragments/shell_windows.py +1 -1
  197. ansible/plugins/doc_fragments/template_common.py +6 -6
  198. ansible/plugins/doc_fragments/url.py +10 -10
  199. ansible/plugins/doc_fragments/url_windows.py +15 -15
  200. ansible/plugins/doc_fragments/vars_plugin_staging.py +4 -4
  201. ansible/plugins/filter/b64decode.yml +1 -1
  202. ansible/plugins/filter/b64encode.yml +2 -2
  203. ansible/plugins/filter/bool.yml +5 -5
  204. ansible/plugins/filter/combine.yml +1 -1
  205. ansible/plugins/filter/commonpath.yml +2 -1
  206. ansible/plugins/filter/core.py +6 -8
  207. ansible/plugins/filter/dict2items.yml +11 -1
  208. ansible/plugins/filter/difference.yml +1 -0
  209. ansible/plugins/filter/encryption.py +1 -1
  210. ansible/plugins/filter/extract.yml +1 -1
  211. ansible/plugins/filter/flatten.yml +1 -1
  212. ansible/plugins/filter/from_yaml.yml +1 -1
  213. ansible/plugins/filter/from_yaml_all.yml +2 -2
  214. ansible/plugins/filter/hash.yml +1 -1
  215. ansible/plugins/filter/human_readable.yml +1 -1
  216. ansible/plugins/filter/human_to_bytes.yml +2 -2
  217. ansible/plugins/filter/intersect.yml +1 -0
  218. ansible/plugins/filter/mandatory.yml +7 -0
  219. ansible/plugins/filter/mathstuff.py +15 -17
  220. ansible/plugins/filter/normpath.yml +1 -1
  221. ansible/plugins/filter/path_join.yml +8 -1
  222. ansible/plugins/filter/realpath.yml +3 -2
  223. ansible/plugins/filter/regex_findall.yml +8 -2
  224. ansible/plugins/filter/regex_replace.yml +9 -3
  225. ansible/plugins/filter/regex_search.yml +8 -2
  226. ansible/plugins/filter/relpath.yml +2 -2
  227. ansible/plugins/filter/root.yml +1 -1
  228. ansible/plugins/filter/splitext.yml +1 -1
  229. ansible/plugins/filter/subelements.yml +2 -2
  230. ansible/plugins/filter/symmetric_difference.yml +1 -0
  231. ansible/plugins/filter/ternary.yml +5 -5
  232. ansible/plugins/filter/to_json.yml +7 -7
  233. ansible/plugins/filter/to_nice_json.yml +5 -5
  234. ansible/plugins/filter/to_yaml.yml +2 -2
  235. ansible/plugins/filter/type_debug.yml +1 -1
  236. ansible/plugins/filter/union.yml +1 -0
  237. ansible/plugins/filter/unvault.yml +2 -2
  238. ansible/plugins/filter/urldecode.yml +13 -32
  239. ansible/plugins/filter/urlsplit.py +1 -1
  240. ansible/plugins/filter/vault.yml +1 -1
  241. ansible/plugins/filter/zip.yml +1 -1
  242. ansible/plugins/filter/zip_longest.yml +1 -1
  243. ansible/plugins/inventory/__init__.py +1 -1
  244. ansible/plugins/inventory/advanced_host_list.py +1 -1
  245. ansible/plugins/inventory/constructed.py +2 -2
  246. ansible/plugins/inventory/host_list.py +1 -1
  247. ansible/plugins/inventory/ini.py +6 -3
  248. ansible/plugins/inventory/script.py +8 -2
  249. ansible/plugins/inventory/toml.py +1 -1
  250. ansible/plugins/inventory/yaml.py +1 -1
  251. ansible/plugins/list.py +21 -17
  252. ansible/plugins/loader.py +66 -88
  253. ansible/plugins/lookup/__init__.py +1 -1
  254. ansible/plugins/lookup/config.py +16 -6
  255. ansible/plugins/lookup/csvfile.py +7 -4
  256. ansible/plugins/lookup/env.py +1 -1
  257. ansible/plugins/lookup/file.py +5 -2
  258. ansible/plugins/lookup/fileglob.py +5 -2
  259. ansible/plugins/lookup/first_found.py +20 -14
  260. ansible/plugins/lookup/ini.py +6 -3
  261. ansible/plugins/lookup/lines.py +2 -1
  262. ansible/plugins/lookup/password.py +7 -7
  263. ansible/plugins/lookup/pipe.py +1 -0
  264. ansible/plugins/lookup/random_choice.py +2 -2
  265. ansible/plugins/lookup/sequence.py +1 -1
  266. ansible/plugins/lookup/subelements.py +2 -2
  267. ansible/plugins/lookup/template.py +4 -1
  268. ansible/plugins/lookup/unvault.py +4 -1
  269. ansible/plugins/lookup/url.py +6 -6
  270. ansible/plugins/lookup/varnames.py +1 -1
  271. ansible/plugins/netconf/__init__.py +3 -3
  272. ansible/plugins/shell/__init__.py +1 -1
  273. ansible/plugins/shell/cmd.py +7 -7
  274. ansible/plugins/shell/powershell.py +1 -1
  275. ansible/plugins/strategy/__init__.py +8 -10
  276. ansible/plugins/strategy/free.py +1 -1
  277. ansible/plugins/strategy/linear.py +3 -3
  278. ansible/plugins/terminal/__init__.py +2 -2
  279. ansible/plugins/test/abs.yml +1 -1
  280. ansible/plugins/test/all.yml +1 -1
  281. ansible/plugins/test/any.yml +1 -1
  282. ansible/plugins/test/change.yml +2 -2
  283. ansible/plugins/test/changed.yml +2 -2
  284. ansible/plugins/test/contains.yml +1 -1
  285. ansible/plugins/test/core.py +1 -1
  286. ansible/plugins/test/directory.yml +1 -1
  287. ansible/plugins/test/exists.yml +3 -2
  288. ansible/plugins/test/failed.yml +2 -2
  289. ansible/plugins/test/failure.yml +2 -2
  290. ansible/plugins/test/falsy.yml +2 -2
  291. ansible/plugins/test/file.yml +1 -1
  292. ansible/plugins/test/finished.yml +2 -2
  293. ansible/plugins/test/is_abs.yml +1 -1
  294. ansible/plugins/test/is_dir.yml +1 -1
  295. ansible/plugins/test/is_file.yml +1 -1
  296. ansible/plugins/test/is_link.yml +1 -1
  297. ansible/plugins/test/is_mount.yml +1 -1
  298. ansible/plugins/test/is_same_file.yml +1 -1
  299. ansible/plugins/test/isnan.yml +1 -1
  300. ansible/plugins/test/issubset.yml +1 -2
  301. ansible/plugins/test/issuperset.yml +1 -2
  302. ansible/plugins/test/link.yml +1 -1
  303. ansible/plugins/test/link_exists.yml +1 -1
  304. ansible/plugins/test/match.yml +2 -2
  305. ansible/plugins/test/mount.yml +1 -1
  306. ansible/plugins/test/nan.yml +1 -1
  307. ansible/plugins/test/reachable.yml +2 -2
  308. ansible/plugins/test/regex.yml +1 -1
  309. ansible/plugins/test/same_file.yml +1 -1
  310. ansible/plugins/test/search.yml +2 -2
  311. ansible/plugins/test/skip.yml +3 -3
  312. ansible/plugins/test/skipped.yml +3 -3
  313. ansible/plugins/test/started.yml +2 -2
  314. ansible/plugins/test/subset.yml +1 -2
  315. ansible/plugins/test/succeeded.yml +2 -2
  316. ansible/plugins/test/success.yml +2 -2
  317. ansible/plugins/test/successful.yml +2 -2
  318. ansible/plugins/test/superset.yml +1 -2
  319. ansible/plugins/test/truthy.yml +3 -3
  320. ansible/plugins/test/unreachable.yml +2 -2
  321. ansible/plugins/test/uri.yml +1 -1
  322. ansible/plugins/test/url.yml +1 -1
  323. ansible/plugins/test/urn.yml +1 -1
  324. ansible/plugins/test/vault_encrypted.yml +1 -1
  325. ansible/plugins/test/version.yml +7 -7
  326. ansible/plugins/test/version_compare.yml +7 -7
  327. ansible/plugins/vars/host_group_vars.py +1 -1
  328. ansible/release.py +2 -2
  329. ansible/template/__init__.py +24 -26
  330. ansible/template/native_helpers.py +1 -1
  331. ansible/template/vars.py +1 -1
  332. ansible/utils/_junit_xml.py +1 -1
  333. ansible/utils/cmd_functions.py +1 -1
  334. ansible/utils/collection_loader/_collection_finder.py +12 -1
  335. ansible/utils/display.py +113 -62
  336. ansible/utils/encrypt.py +11 -14
  337. ansible/utils/hashing.py +1 -1
  338. ansible/utils/jsonrpc.py +1 -1
  339. ansible/utils/path.py +1 -1
  340. ansible/utils/plugin_docs.py +1 -1
  341. ansible/utils/py3compat.py +1 -1
  342. ansible/utils/shlex.py +2 -10
  343. ansible/utils/ssh_functions.py +5 -4
  344. ansible/utils/unicode.py +1 -1
  345. ansible/utils/unsafe_proxy.py +1 -1
  346. ansible/utils/vars.py +4 -29
  347. ansible/vars/hostvars.py +1 -2
  348. ansible/vars/manager.py +13 -9
  349. ansible/vars/plugins.py +2 -2
  350. {ansible_core-2.15.4rc1.dist-info → ansible_core-2.16.0b2.dist-info}/COPYING +4 -5
  351. {ansible_core-2.15.4rc1.dist-info → ansible_core-2.16.0b2.dist-info}/METADATA +2 -4
  352. {ansible_core-2.15.4rc1.dist-info → ansible_core-2.16.0b2.dist-info}/RECORD +424 -425
  353. ansible_test/_data/completion/docker.txt +9 -9
  354. ansible_test/_data/completion/remote.txt +4 -7
  355. ansible_test/_data/completion/windows.txt +0 -2
  356. ansible_test/_data/requirements/ansible-test.txt +2 -1
  357. ansible_test/_data/requirements/ansible.txt +0 -3
  358. ansible_test/_data/requirements/constraints.txt +0 -2
  359. ansible_test/_data/requirements/sanity.ansible-doc.txt +3 -5
  360. ansible_test/_data/requirements/sanity.changelog.in +1 -2
  361. ansible_test/_data/requirements/sanity.changelog.txt +4 -6
  362. ansible_test/_data/requirements/sanity.import.plugin.txt +2 -4
  363. ansible_test/_data/requirements/sanity.import.txt +1 -3
  364. ansible_test/_data/requirements/sanity.integration-aliases.txt +1 -3
  365. ansible_test/_data/requirements/sanity.mypy.txt +12 -12
  366. ansible_test/_data/requirements/sanity.pep8.txt +1 -1
  367. ansible_test/_data/requirements/sanity.pylint.txt +6 -12
  368. ansible_test/_data/requirements/sanity.runtime-metadata.txt +1 -3
  369. ansible_test/_data/requirements/sanity.validate-modules.in +1 -1
  370. ansible_test/_data/requirements/sanity.validate-modules.txt +3 -5
  371. ansible_test/_data/requirements/sanity.yamllint.txt +3 -5
  372. ansible_test/_data/requirements/units.txt +0 -1
  373. ansible_test/_internal/ci/azp.py +4 -4
  374. ansible_test/_internal/cli/environments.py +0 -13
  375. ansible_test/_internal/commands/coverage/analyze/targets/__init__.py +4 -4
  376. ansible_test/_internal/commands/coverage/combine.py +1 -1
  377. ansible_test/_internal/commands/integration/cloud/acme.py +6 -8
  378. ansible_test/_internal/commands/integration/cloud/cs.py +4 -9
  379. ansible_test/_internal/commands/integration/cloud/galaxy.py +103 -96
  380. ansible_test/_internal/commands/integration/cloud/httptester.py +0 -3
  381. ansible_test/_internal/commands/integration/cloud/nios.py +7 -9
  382. ansible_test/_internal/commands/integration/cloud/openshift.py +2 -7
  383. ansible_test/_internal/commands/integration/cloud/vcenter.py +11 -95
  384. ansible_test/_internal/commands/sanity/__init__.py +10 -0
  385. ansible_test/_internal/commands/sanity/import.py +8 -2
  386. ansible_test/_internal/commands/sanity/pylint.py +27 -1
  387. ansible_test/_internal/commands/units/__init__.py +2 -1
  388. ansible_test/_internal/config.py +0 -7
  389. ansible_test/_internal/containers.py +11 -56
  390. ansible_test/_internal/core_ci.py +0 -7
  391. ansible_test/_internal/coverage_util.py +8 -3
  392. ansible_test/_internal/delegation.py +0 -1
  393. ansible_test/_internal/diff.py +1 -1
  394. ansible_test/_internal/docker_util.py +9 -2
  395. ansible_test/_internal/host_profiles.py +6 -6
  396. ansible_test/_internal/http.py +1 -1
  397. ansible_test/_internal/junit_xml.py +1 -1
  398. ansible_test/_internal/pypi_proxy.py +1 -1
  399. ansible_test/_internal/python_requirements.py +3 -8
  400. ansible_test/_internal/util.py +1 -6
  401. ansible_test/_util/controller/sanity/code-smell/no-get-exception.json +4 -0
  402. ansible_test/_util/controller/sanity/code-smell/replace-urlopen.json +4 -0
  403. ansible_test/_util/controller/sanity/code-smell/use-compat-six.json +4 -0
  404. ansible_test/_util/controller/sanity/mypy/ansible-core.ini +3 -0
  405. ansible_test/_util/controller/sanity/pylint/config/ansible-test-target.cfg +2 -0
  406. ansible_test/_util/controller/sanity/pylint/config/ansible-test.cfg +0 -1
  407. ansible_test/_util/controller/sanity/pylint/config/collection.cfg +1 -0
  408. ansible_test/_util/controller/sanity/pylint/plugins/deprecated.py +172 -10
  409. ansible_test/_util/controller/sanity/pylint/plugins/string_format.py +13 -2
  410. ansible_test/_util/controller/sanity/pylint/plugins/unwanted.py +7 -1
  411. ansible_test/_util/controller/sanity/validate-modules/validate_modules/main.py +6 -6
  412. ansible_test/_util/controller/sanity/validate-modules/validate_modules/module_args.py +1 -1
  413. ansible_test/_util/controller/sanity/validate-modules/validate_modules/utils.py +1 -1
  414. ansible_test/_util/controller/sanity/yamllint/yamllinter.py +3 -3
  415. ansible_test/_util/controller/tools/collection_detail.py +2 -2
  416. ansible_test/_util/target/common/constants.py +2 -2
  417. ansible_test/_util/target/pytest/plugins/ansible_forked.py +103 -0
  418. ansible_test/_util/target/sanity/import/importer.py +0 -8
  419. ansible_test/_util/target/setup/bootstrap.sh +36 -16
  420. ansible_test/_util/target/setup/quiet_pip.py +0 -4
  421. ansible/modules/_include.py +0 -80
  422. ansible_test/_internal/commands/integration/cloud/foreman.py +0 -102
  423. ansible_test/_util/target/setup/ConfigureRemotingForAnsible.ps1 +0 -435
  424. {ansible_core-2.15.4rc1.data → ansible_core-2.16.0b2.data}/scripts/ansible-test +0 -0
  425. {ansible_core-2.15.4rc1.dist-info → ansible_core-2.16.0b2.dist-info}/WHEEL +0 -0
  426. {ansible_core-2.15.4rc1.dist-info → ansible_core-2.16.0b2.dist-info}/entry_points.txt +0 -0
  427. {ansible_core-2.15.4rc1.dist-info → ansible_core-2.16.0b2.dist-info}/top_level.txt +0 -0
ansible/modules/apt.py CHANGED
@@ -20,15 +20,15 @@ version_added: "0.0.2"
20
20
  options:
21
21
  name:
22
22
  description:
23
- - A list of package names, like C(foo), or package specifier with version, like C(foo=1.0) or C(foo>=1.0).
24
- Name wildcards (fnmatch) like C(apt*) and version wildcards like C(foo=1.0*) are also supported.
23
+ - A list of package names, like V(foo), or package specifier with version, like V(foo=1.0) or V(foo>=1.0).
24
+ Name wildcards (fnmatch) like V(apt*) and version wildcards like V(foo=1.0*) are also supported.
25
25
  aliases: [ package, pkg ]
26
26
  type: list
27
27
  elements: str
28
28
  state:
29
29
  description:
30
- - Indicates the desired package state. C(latest) ensures that the latest version is installed. C(build-dep) ensures the package build dependencies
31
- are installed. C(fixed) attempt to correct a system with broken dependencies in place.
30
+ - Indicates the desired package state. V(latest) ensures that the latest version is installed. V(build-dep) ensures the package build dependencies
31
+ are installed. V(fixed) attempt to correct a system with broken dependencies in place.
32
32
  type: str
33
33
  default: present
34
34
  choices: [ absent, build-dep, latest, present, fixed ]
@@ -40,25 +40,25 @@ options:
40
40
  type: bool
41
41
  update_cache_retries:
42
42
  description:
43
- - Amount of retries if the cache update fails. Also see I(update_cache_retry_max_delay).
43
+ - Amount of retries if the cache update fails. Also see O(update_cache_retry_max_delay).
44
44
  type: int
45
45
  default: 5
46
46
  version_added: '2.10'
47
47
  update_cache_retry_max_delay:
48
48
  description:
49
- - Use an exponential backoff delay for each retry (see I(update_cache_retries)) up to this max delay in seconds.
49
+ - Use an exponential backoff delay for each retry (see O(update_cache_retries)) up to this max delay in seconds.
50
50
  type: int
51
51
  default: 12
52
52
  version_added: '2.10'
53
53
  cache_valid_time:
54
54
  description:
55
- - Update the apt cache if it is older than the I(cache_valid_time). This option is set in seconds.
56
- - As of Ansible 2.4, if explicitly set, this sets I(update_cache=yes).
55
+ - Update the apt cache if it is older than the O(cache_valid_time). This option is set in seconds.
56
+ - As of Ansible 2.4, if explicitly set, this sets O(update_cache=yes).
57
57
  type: int
58
58
  default: 0
59
59
  purge:
60
60
  description:
61
- - Will force purging of configuration files if the module state is set to I(absent).
61
+ - Will force purging of configuration files if O(state=absent) or O(autoremove=yes).
62
62
  type: bool
63
63
  default: 'no'
64
64
  default_release:
@@ -68,13 +68,13 @@ options:
68
68
  type: str
69
69
  install_recommends:
70
70
  description:
71
- - Corresponds to the C(--no-install-recommends) option for I(apt). C(true) installs recommended packages. C(false) does not install
71
+ - Corresponds to the C(--no-install-recommends) option for I(apt). V(true) installs recommended packages. V(false) does not install
72
72
  recommended packages. By default, Ansible will use the same defaults as the operating system. Suggested packages are never installed.
73
73
  aliases: [ install-recommends ]
74
74
  type: bool
75
75
  force:
76
76
  description:
77
- - 'Corresponds to the C(--force-yes) to I(apt-get) and implies C(allow_unauthenticated: yes) and C(allow_downgrade: yes)'
77
+ - 'Corresponds to the C(--force-yes) to I(apt-get) and implies O(allow_unauthenticated=yes) and O(allow_downgrade=yes)'
78
78
  - "This option will disable checking both the packages' signatures and the certificates of the
79
79
  web servers they are downloaded from."
80
80
  - 'This option *is not* the equivalent of passing the C(-f) flag to I(apt-get) on the command line'
@@ -93,7 +93,7 @@ options:
93
93
  allow_unauthenticated:
94
94
  description:
95
95
  - Ignore if packages cannot be authenticated. This is useful for bootstrapping environments that manage their own apt-key setup.
96
- - 'C(allow_unauthenticated) is only supported with state: I(install)/I(present)'
96
+ - 'O(allow_unauthenticated) is only supported with O(state): V(install)/V(present)'
97
97
  aliases: [ allow-unauthenticated ]
98
98
  type: bool
99
99
  default: 'no'
@@ -102,8 +102,9 @@ options:
102
102
  description:
103
103
  - Corresponds to the C(--allow-downgrades) option for I(apt).
104
104
  - This option enables the named package and version to replace an already installed higher version of that package.
105
- - Note that setting I(allow_downgrade=true) can make this module behave in a non-idempotent way.
105
+ - Note that setting O(allow_downgrade=true) can make this module behave in a non-idempotent way.
106
106
  - (The task could end up with a set of packages that does not match the complete list of specified packages to install).
107
+ - 'O(allow_downgrade) is only supported by C(apt) and will be ignored if C(aptitude) is detected or specified.'
107
108
  aliases: [ allow-downgrade, allow_downgrades, allow-downgrades ]
108
109
  type: bool
109
110
  default: 'no'
@@ -141,14 +142,14 @@ options:
141
142
  version_added: "1.6"
142
143
  autoremove:
143
144
  description:
144
- - If C(true), remove unused dependency packages for all module states except I(build-dep). It can also be used as the only option.
145
+ - If V(true), remove unused dependency packages for all module states except V(build-dep). It can also be used as the only option.
145
146
  - Previous to version 2.4, autoclean was also an alias for autoremove, now it is its own separate command. See documentation for further information.
146
147
  type: bool
147
148
  default: 'no'
148
149
  version_added: "2.1"
149
150
  autoclean:
150
151
  description:
151
- - If C(true), cleans the local repository of retrieved package files that can no longer be downloaded.
152
+ - If V(true), cleans the local repository of retrieved package files that can no longer be downloaded.
152
153
  type: bool
153
154
  default: 'no'
154
155
  version_added: "2.4"
@@ -157,7 +158,7 @@ options:
157
158
  - Force the exit code of /usr/sbin/policy-rc.d.
158
159
  - For example, if I(policy_rc_d=101) the installed package will not trigger a service start.
159
160
  - If /usr/sbin/policy-rc.d already exists, it is backed up and restored after the package installation.
160
- - If C(null), the /usr/sbin/policy-rc.d isn't created/changed.
161
+ - If V(null), the /usr/sbin/policy-rc.d isn't created/changed.
161
162
  type: int
162
163
  default: null
163
164
  version_added: "2.8"
@@ -170,8 +171,9 @@ options:
170
171
  fail_on_autoremove:
171
172
  description:
172
173
  - 'Corresponds to the C(--no-remove) option for C(apt).'
173
- - 'If C(true), it is ensured that no packages will be removed or the task will fail.'
174
- - 'C(fail_on_autoremove) is only supported with state except C(absent)'
174
+ - 'If V(true), it is ensured that no packages will be removed or the task will fail.'
175
+ - 'O(fail_on_autoremove) is only supported with O(state) except V(absent).'
176
+ - 'O(fail_on_autoremove) is only supported by C(apt) and will be ignored if C(aptitude) is detected or specified.'
175
177
  type: bool
176
178
  default: 'no'
177
179
  version_added: "2.11"
@@ -202,15 +204,15 @@ attributes:
202
204
  platform:
203
205
  platforms: debian
204
206
  notes:
205
- - Three of the upgrade modes (C(full), C(safe) and its alias C(true)) required C(aptitude) up to 2.3, since 2.4 C(apt-get) is used as a fall-back.
207
+ - Three of the upgrade modes (V(full), V(safe) and its alias V(true)) required C(aptitude) up to 2.3, since 2.4 C(apt-get) is used as a fall-back.
206
208
  - In most cases, packages installed with apt will start newly installed services by default. Most distributions have mechanisms to avoid this.
207
209
  For example when installing Postgresql-9.5 in Debian 9, creating an excutable shell script (/usr/sbin/policy-rc.d) that throws
208
210
  a return code of 101 will stop Postgresql 9.5 starting up after install. Remove the file or remove its execute permission afterwards.
209
211
  - The apt-get commandline supports implicit regex matches here but we do not because it can let typos through easier
210
212
  (If you typo C(foo) as C(fo) apt-get would install packages that have "fo" in their name with a warning and a prompt for the user.
211
213
  Since we don't have warnings and prompts before installing we disallow this.Use an explicit fnmatch pattern if you want wildcarding)
212
- - When used with a C(loop:) each package will be processed individually, it is much more efficient to pass the list directly to the I(name) option.
213
- - When C(default_release) is used, an implicit priority of 990 is used. This is the same behavior as C(apt-get -t).
214
+ - 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
+ - When O(default_release) is used, an implicit priority of 990 is used. This is the same behavior as C(apt-get -t).
214
216
  - When an exact version is specified, an implicit priority of 1001 is used.
215
217
  '''
216
218
 
@@ -314,6 +316,11 @@ EXAMPLES = '''
314
316
  ansible.builtin.apt:
315
317
  autoremove: yes
316
318
 
319
+ - name: Remove dependencies that are no longer required and purge their configuration files
320
+ ansible.builtin.apt:
321
+ autoremove: yes
322
+ purge: true
323
+
317
324
  - name: Run the equivalent of "apt-get clean" as a separate step
318
325
  apt:
319
326
  clean: yes
@@ -365,7 +372,7 @@ import time
365
372
  from ansible.module_utils.basic import AnsibleModule
366
373
  from ansible.module_utils.common.locale import get_best_parsable_locale
367
374
  from ansible.module_utils.common.respawn import has_respawned, probe_interpreters_for_module, respawn_module
368
- from ansible.module_utils._text import to_native, to_text
375
+ from ansible.module_utils.common.text.converters import to_native, to_text
369
376
  from ansible.module_utils.six import PY3, string_types
370
377
  from ansible.module_utils.urls import fetch_file
371
378
 
@@ -1031,15 +1038,13 @@ def cleanup(m, purge=False, force=False, operation=None,
1031
1038
 
1032
1039
  def aptclean(m):
1033
1040
  clean_rc, clean_out, clean_err = m.run_command(['apt-get', 'clean'])
1034
- if m._diff:
1035
- clean_diff = parse_diff(clean_out)
1036
- else:
1037
- clean_diff = {}
1041
+ clean_diff = parse_diff(clean_out) if m._diff else {}
1042
+
1038
1043
  if clean_rc:
1039
1044
  m.fail_json(msg="apt-get clean failed", stdout=clean_out, rc=clean_rc)
1040
1045
  if clean_err:
1041
1046
  m.fail_json(msg="apt-get clean failed: %s" % clean_err, stdout=clean_out, rc=clean_rc)
1042
- return clean_out, clean_err
1047
+ return (clean_out, clean_err, clean_diff)
1043
1048
 
1044
1049
 
1045
1050
  def upgrade(m, mode="yes", force=False, default_release=None,
@@ -1088,13 +1093,24 @@ def upgrade(m, mode="yes", force=False, default_release=None,
1088
1093
  force_yes = ''
1089
1094
 
1090
1095
  if fail_on_autoremove:
1091
- fail_on_autoremove = '--no-remove'
1096
+ if apt_cmd == APT_GET_CMD:
1097
+ fail_on_autoremove = '--no-remove'
1098
+ else:
1099
+ m.warn("APTITUDE does not support '--no-remove', ignoring the 'fail_on_autoremove' parameter.")
1100
+ fail_on_autoremove = ''
1092
1101
  else:
1093
1102
  fail_on_autoremove = ''
1094
1103
 
1095
1104
  allow_unauthenticated = '--allow-unauthenticated' if allow_unauthenticated else ''
1096
1105
 
1097
- allow_downgrade = '--allow-downgrades' if allow_downgrade else ''
1106
+ if allow_downgrade:
1107
+ if apt_cmd == APT_GET_CMD:
1108
+ allow_downgrade = '--allow-downgrades'
1109
+ else:
1110
+ m.warn("APTITUDE does not support '--allow-downgrades', ignoring the 'allow_downgrade' parameter.")
1111
+ allow_downgrade = ''
1112
+ else:
1113
+ allow_downgrade = ''
1098
1114
 
1099
1115
  if apt_cmd is None:
1100
1116
  if use_apt_get:
@@ -1293,7 +1309,7 @@ def main():
1293
1309
  p = module.params
1294
1310
 
1295
1311
  if p['clean'] is True:
1296
- aptclean_stdout, aptclean_stderr = aptclean(module)
1312
+ aptclean_stdout, aptclean_stderr, aptclean_diff = aptclean(module)
1297
1313
  # If there is nothing else to do exit. This will set state as
1298
1314
  # changed based on if the cache was updated.
1299
1315
  if not p['package'] and not p['upgrade'] and not p['deb']:
@@ -1301,7 +1317,8 @@ def main():
1301
1317
  changed=True,
1302
1318
  msg=aptclean_stdout,
1303
1319
  stdout=aptclean_stdout,
1304
- stderr=aptclean_stderr
1320
+ stderr=aptclean_stderr,
1321
+ diff=aptclean_diff
1305
1322
  )
1306
1323
 
1307
1324
  if p['upgrade'] == 'no':
@@ -32,7 +32,7 @@ notes:
32
32
  - As a sanity check, downloaded key id must match the one specified.
33
33
  - "Use full fingerprint (40 characters) key ids to avoid key collisions.
34
34
  To generate a full-fingerprint imported key: C(apt-key adv --list-public-keys --with-fingerprint --with-colons)."
35
- - If you specify both the key id and the URL with C(state=present), the task can verify or add the key as needed.
35
+ - If you specify both the key id and the URL with O(state=present), the task can verify or add the key as needed.
36
36
  - Adding a new key requires an apt cache update (e.g. using the M(ansible.builtin.apt) module's update_cache option).
37
37
  requirements:
38
38
  - gpg
@@ -44,7 +44,7 @@ options:
44
44
  - The identifier of the key.
45
45
  - Including this allows check mode to correctly report the changed state.
46
46
  - If specifying a subkey's id be aware that apt-key does not understand how to remove keys via a subkey id. Specify the primary key's id instead.
47
- - This parameter is required when C(state) is set to C(absent).
47
+ - This parameter is required when O(state) is set to V(absent).
48
48
  type: str
49
49
  data:
50
50
  description:
@@ -76,7 +76,7 @@ options:
76
76
  default: present
77
77
  validate_certs:
78
78
  description:
79
- - If C(false), SSL certificates for the target url will not be validated. This should only be used
79
+ - If V(false), SSL certificates for the target url will not be validated. This should only be used
80
80
  on personally controlled sites using self-signed certificates.
81
81
  type: bool
82
82
  default: 'yes'
@@ -174,7 +174,7 @@ import os
174
174
  # FIXME: standardize into module_common
175
175
  from traceback import format_exc
176
176
 
177
- from ansible.module_utils._text import to_native
177
+ from ansible.module_utils.common.text.converters import to_native
178
178
  from ansible.module_utils.basic import AnsibleModule
179
179
  from ansible.module_utils.common.locale import get_best_parsable_locale
180
180
  from ansible.module_utils.urls import fetch_url
@@ -54,19 +54,19 @@ options:
54
54
  aliases: [ update-cache ]
55
55
  update_cache_retries:
56
56
  description:
57
- - Amount of retries if the cache update fails. Also see I(update_cache_retry_max_delay).
57
+ - Amount of retries if the cache update fails. Also see O(update_cache_retry_max_delay).
58
58
  type: int
59
59
  default: 5
60
60
  version_added: '2.10'
61
61
  update_cache_retry_max_delay:
62
62
  description:
63
- - Use an exponential backoff delay for each retry (see I(update_cache_retries)) up to this max delay in seconds.
63
+ - Use an exponential backoff delay for each retry (see O(update_cache_retries)) up to this max delay in seconds.
64
64
  type: int
65
65
  default: 12
66
66
  version_added: '2.10'
67
67
  validate_certs:
68
68
  description:
69
- - If C(false), SSL certificates for the target repo will not be validated. This should only be used
69
+ - If V(false), SSL certificates for the target repo will not be validated. This should only be used
70
70
  on personally controlled sites using self-signed certificates.
71
71
  type: bool
72
72
  default: 'yes'
@@ -91,7 +91,7 @@ options:
91
91
  Without this library, the module does not work.
92
92
  - Runs C(apt-get install python-apt) for Python 2, and C(apt-get install python3-apt) for Python 3.
93
93
  - Only works with the system Python 2 or Python 3. If you are using a Python on the remote that is not
94
- the system Python, set I(install_python_apt=false) and ensure that the Python apt library
94
+ the system Python, set O(install_python_apt=false) and ensure that the Python apt library
95
95
  for your Python version is installed some other way.
96
96
  type: bool
97
97
  default: true
@@ -182,7 +182,7 @@ import time
182
182
 
183
183
  from ansible.module_utils.basic import AnsibleModule
184
184
  from ansible.module_utils.common.respawn import has_respawned, probe_interpreters_for_module, respawn_module
185
- from ansible.module_utils._text import to_native
185
+ from ansible.module_utils.common.text.converters import to_native
186
186
  from ansible.module_utils.six import PY3
187
187
  from ansible.module_utils.urls import fetch_url
188
188
 
@@ -17,7 +17,7 @@ description:
17
17
  - Assembles a configuration file from fragments.
18
18
  - Often a particular program will take a single configuration file and does not support a
19
19
  C(conf.d) style structure where it is easy to build up the configuration
20
- from multiple sources. C(assemble) will take a directory of files that can be
20
+ from multiple sources. M(ansible.builtin.assemble) will take a directory of files that can be
21
21
  local or have already been transferred to the system, and concatenate them
22
22
  together to produce a destination file.
23
23
  - Files are assembled in string sorting order.
@@ -36,7 +36,7 @@ options:
36
36
  required: true
37
37
  backup:
38
38
  description:
39
- - Create a backup file (if C(true)), including the timestamp information so
39
+ - Create a backup file (if V(true)), including the timestamp information so
40
40
  you can get the original file back if you somehow clobbered it
41
41
  incorrectly.
42
42
  type: bool
@@ -48,16 +48,16 @@ options:
48
48
  version_added: '1.4'
49
49
  remote_src:
50
50
  description:
51
- - If C(false), it will search for src at originating/master machine.
52
- - If C(true), it will go to the remote/target machine for the src.
51
+ - If V(false), it will search for src at originating/master machine.
52
+ - If V(true), it will go to the remote/target machine for the src.
53
53
  type: bool
54
54
  default: yes
55
55
  version_added: '1.4'
56
56
  regexp:
57
57
  description:
58
- - Assemble files only if C(regex) matches the filename.
58
+ - Assemble files only if the given regular expression matches the filename.
59
59
  - If not set, all files are assembled.
60
- - Every C(\) (backslash) must be escaped as C(\\) to comply to YAML syntax.
60
+ - Every V(\\) (backslash) must be escaped as V(\\\\) to comply to YAML syntax.
61
61
  - Uses L(Python regular expressions,https://docs.python.org/3/library/re.html).
62
62
  type: str
63
63
  ignore_hidden:
@@ -133,7 +133,7 @@ import tempfile
133
133
 
134
134
  from ansible.module_utils.basic import AnsibleModule
135
135
  from ansible.module_utils.six import b, indexbytes
136
- from ansible.module_utils._text import to_native
136
+ from ansible.module_utils.common.text.converters import to_native
137
137
 
138
138
 
139
139
  def assemble_from_fragments(src_path, delimiter=None, compiled_regexp=None, ignore_hidden=False, tmpdir=None):
ansible/modules/assert.py CHANGED
@@ -36,7 +36,7 @@ options:
36
36
  version_added: "2.7"
37
37
  quiet:
38
38
  description:
39
- - Set this to C(true) to avoid verbose output.
39
+ - Set this to V(true) to avoid verbose output.
40
40
  type: bool
41
41
  default: no
42
42
  version_added: "2.8"
@@ -23,8 +23,8 @@ options:
23
23
  required: true
24
24
  mode:
25
25
  description:
26
- - If C(status), obtain the status.
27
- - If C(cleanup), clean up the async job cache (by default in C(~/.ansible_async/)) for the specified job I(jid).
26
+ - If V(status), obtain the status.
27
+ - If V(cleanup), clean up the async job cache (by default in C(~/.ansible_async/)) for the specified job O(jid), without waiting for it to finish.
28
28
  type: str
29
29
  choices: [ cleanup, status ]
30
30
  default: status
@@ -70,6 +70,11 @@ EXAMPLES = r'''
70
70
  until: job_result.finished
71
71
  retries: 100
72
72
  delay: 10
73
+
74
+ - name: Clean up async file
75
+ ansible.builtin.async_status:
76
+ jid: '{{ yum_sleeper.ansible_job_id }}'
77
+ mode: cleanup
73
78
  '''
74
79
 
75
80
  RETURN = r'''
@@ -79,12 +84,12 @@ ansible_job_id:
79
84
  type: str
80
85
  sample: '360874038559.4169'
81
86
  finished:
82
- description: Whether the asynchronous job has finished (C(1)) or not (C(0))
87
+ description: Whether the asynchronous job has finished (V(1)) or not (V(0))
83
88
  returned: always
84
89
  type: int
85
90
  sample: 1
86
91
  started:
87
- description: Whether the asynchronous job has started (C(1)) or not (C(0))
92
+ description: Whether the asynchronous job has started (V(1)) or not (V(0))
88
93
  returned: always
89
94
  type: int
90
95
  sample: 1
@@ -107,7 +112,7 @@ import os
107
112
 
108
113
  from ansible.module_utils.basic import AnsibleModule
109
114
  from ansible.module_utils.six import iteritems
110
- from ansible.module_utils._text import to_native
115
+ from ansible.module_utils.common.text.converters import to_native
111
116
 
112
117
 
113
118
  def main():
@@ -124,8 +129,7 @@ def main():
124
129
  async_dir = module.params['_async_dir']
125
130
 
126
131
  # setup logging directory
127
- logdir = os.path.expanduser(async_dir)
128
- log_path = os.path.join(logdir, jid)
132
+ log_path = os.path.join(async_dir, jid)
129
133
 
130
134
  if not os.path.exists(log_path):
131
135
  module.fail_json(msg="could not find job", ansible_job_id=jid, started=1, finished=1)
@@ -20,7 +20,7 @@ import time
20
20
  import syslog
21
21
  import multiprocessing
22
22
 
23
- from ansible.module_utils._text import to_text, to_bytes
23
+ from ansible.module_utils.common.text.converters import to_text, to_bytes
24
24
 
25
25
  PY3 = sys.version_info[0] == 3
26
26
 
@@ -21,7 +21,7 @@ options:
21
21
  path:
22
22
  description:
23
23
  - The file to modify.
24
- - Before Ansible 2.3 this option was only usable as I(dest), I(destfile) and I(name).
24
+ - Before Ansible 2.3 this option was only usable as O(dest), O(destfile) and O(name).
25
25
  type: path
26
26
  required: yes
27
27
  aliases: [ dest, destfile, name ]
@@ -34,24 +34,24 @@ options:
34
34
  marker:
35
35
  description:
36
36
  - The marker line template.
37
- - C({mark}) will be replaced with the values in C(marker_begin) (default="BEGIN") and C(marker_end) (default="END").
37
+ - C({mark}) will be replaced with the values in O(marker_begin) (default="BEGIN") and O(marker_end) (default="END").
38
38
  - Using a custom marker without the C({mark}) variable may result in the block being repeatedly inserted on subsequent playbook runs.
39
39
  - Multi-line markers are not supported and will result in the block being repeatedly inserted on subsequent playbook runs.
40
- - A newline is automatically appended by the module to C(marker_begin) and C(marker_end).
40
+ - A newline is automatically appended by the module to O(marker_begin) and O(marker_end).
41
41
  type: str
42
42
  default: '# {mark} ANSIBLE MANAGED BLOCK'
43
43
  block:
44
44
  description:
45
45
  - The text to insert inside the marker lines.
46
- - If it is missing or an empty string, the block will be removed as if C(state) were specified to C(absent).
46
+ - If it is missing or an empty string, the block will be removed as if O(state) were specified to V(absent).
47
47
  type: str
48
48
  default: ''
49
49
  aliases: [ content ]
50
50
  insertafter:
51
51
  description:
52
- - If specified and no begin/ending C(marker) lines are found, the block will be inserted after the last match of specified regular expression.
53
- - A special value is available; C(EOF) for inserting the block at the end of the file.
54
- - If specified regular expression has no matches, C(EOF) will be used instead.
52
+ - If specified and no begin/ending O(marker) lines are found, the block will be inserted after the last match of specified regular expression.
53
+ - A special value is available; V(EOF) for inserting the block at the end of the file.
54
+ - If specified regular expression has no matches, V(EOF) will be used instead.
55
55
  - The presence of the multiline flag (?m) in the regular expression controls whether the match is done line by line or with multiple lines.
56
56
  This behaviour was added in ansible-core 2.14.
57
57
  type: str
@@ -59,8 +59,8 @@ options:
59
59
  default: EOF
60
60
  insertbefore:
61
61
  description:
62
- - If specified and no begin/ending C(marker) lines are found, the block will be inserted before the last match of specified regular expression.
63
- - A special value is available; C(BOF) for inserting the block at the beginning of the file.
62
+ - If specified and no begin/ending O(marker) lines are found, the block will be inserted before the last match of specified regular expression.
63
+ - A special value is available; V(BOF) for inserting the block at the beginning of the file.
64
64
  - If specified regular expression has no matches, the block will be inserted at the end of the file.
65
65
  - The presence of the multiline flag (?m) in the regular expression controls whether the match is done line by line or with multiple lines.
66
66
  This behaviour was added in ansible-core 2.14.
@@ -79,22 +79,39 @@ options:
79
79
  default: no
80
80
  marker_begin:
81
81
  description:
82
- - This will be inserted at C({mark}) in the opening ansible block marker.
82
+ - This will be inserted at C({mark}) in the opening ansible block O(marker).
83
83
  type: str
84
84
  default: BEGIN
85
85
  version_added: '2.5'
86
86
  marker_end:
87
87
  required: false
88
88
  description:
89
- - This will be inserted at C({mark}) in the closing ansible block marker.
89
+ - This will be inserted at C({mark}) in the closing ansible block O(marker).
90
90
  type: str
91
91
  default: END
92
92
  version_added: '2.5'
93
+ append_newline:
94
+ required: false
95
+ description:
96
+ - Append a blank line to the inserted block, if this does not appear at the end of the file.
97
+ - Note that this attribute is not considered when C(state) is set to C(absent)
98
+ type: bool
99
+ default: no
100
+ version_added: '2.16'
101
+ prepend_newline:
102
+ required: false
103
+ description:
104
+ - Prepend a blank line to the inserted block, if this does not appear at the beginning of the file.
105
+ - Note that this attribute is not considered when C(state) is set to C(absent)
106
+ type: bool
107
+ default: no
108
+ version_added: '2.16'
93
109
  notes:
94
110
  - When using 'with_*' loops be aware that if you do not set a unique mark the block will be overwritten on each iteration.
95
- - As of Ansible 2.3, the I(dest) option has been changed to I(path) as default, but I(dest) still works as well.
96
- - Option I(follow) has been removed in Ansible 2.5, because this module modifies the contents of the file so I(follow=no) doesn't make sense.
97
- - When more then one block should be handled in one file you must change the I(marker) per task.
111
+ - As of Ansible 2.3, the O(dest) option has been changed to O(path) as default, but O(dest) still works as well.
112
+ - Option O(ignore:follow) has been removed in Ansible 2.5, because this module modifies the contents of the file
113
+ so O(ignore:follow=no) does not make sense.
114
+ - When more then one block should be handled in one file you must change the O(marker) per task.
98
115
  extends_documentation_fragment:
99
116
  - action_common_attributes
100
117
  - action_common_attributes.files
@@ -116,9 +133,11 @@ attributes:
116
133
 
117
134
  EXAMPLES = r'''
118
135
  # Before Ansible 2.3, option 'dest' or 'name' was used instead of 'path'
119
- - name: Insert/Update "Match User" configuration block in /etc/ssh/sshd_config
136
+ - name: Insert/Update "Match User" configuration block in /etc/ssh/sshd_config prepending and appending a new line
120
137
  ansible.builtin.blockinfile:
121
138
  path: /etc/ssh/sshd_config
139
+ append_newline: true
140
+ prepend_newline: true
122
141
  block: |
123
142
  Match User ansible-agent
124
143
  PasswordAuthentication no
@@ -179,7 +198,7 @@ import os
179
198
  import tempfile
180
199
  from ansible.module_utils.six import b
181
200
  from ansible.module_utils.basic import AnsibleModule
182
- from ansible.module_utils._text import to_bytes, to_native
201
+ from ansible.module_utils.common.text.converters import to_bytes, to_native
183
202
 
184
203
 
185
204
  def write_changes(module, contents, path):
@@ -230,6 +249,8 @@ def main():
230
249
  validate=dict(type='str'),
231
250
  marker_begin=dict(type='str', default='BEGIN'),
232
251
  marker_end=dict(type='str', default='END'),
252
+ append_newline=dict(type='bool', default=False),
253
+ prepend_newline=dict(type='bool', default=False),
233
254
  ),
234
255
  mutually_exclusive=[['insertbefore', 'insertafter']],
235
256
  add_file_common_args=True,
@@ -251,8 +272,10 @@ def main():
251
272
  if not os.path.exists(destpath) and not module.check_mode:
252
273
  try:
253
274
  os.makedirs(destpath)
275
+ except OSError as e:
276
+ module.fail_json(msg='Error creating %s Error code: %s Error description: %s' % (destpath, e.errno, e.strerror))
254
277
  except Exception as e:
255
- module.fail_json(msg='Error creating %s Error code: %s Error description: %s' % (destpath, e[0], e[1]))
278
+ module.fail_json(msg='Error creating %s Error: %s' % (destpath, to_native(e)))
256
279
  original = None
257
280
  lines = []
258
281
  else:
@@ -273,6 +296,7 @@ def main():
273
296
  block = to_bytes(params['block'])
274
297
  marker = to_bytes(params['marker'])
275
298
  present = params['state'] == 'present'
299
+ blank_line = [b(os.linesep)]
276
300
 
277
301
  if not present and not path_exists:
278
302
  module.exit_json(changed=False, msg="File %s not present" % path)
@@ -336,7 +360,26 @@ def main():
336
360
  if not lines[n0 - 1].endswith(b(os.linesep)):
337
361
  lines[n0 - 1] += b(os.linesep)
338
362
 
363
+ # Before the block: check if we need to prepend a blank line
364
+ # If yes, we need to add the blank line if we are not at the beginning of the file
365
+ # and the previous line is not a blank line
366
+ # In both cases, we need to shift by one on the right the inserting position of the block
367
+ if params['prepend_newline'] and present:
368
+ if n0 != 0 and lines[n0 - 1] != b(os.linesep):
369
+ lines[n0:n0] = blank_line
370
+ n0 += 1
371
+
372
+ # Insert the block
339
373
  lines[n0:n0] = blocklines
374
+
375
+ # After the block: check if we need to append a blank line
376
+ # If yes, we need to add the blank line if we are not at the end of the file
377
+ # and the line right after is not a blank line
378
+ if params['append_newline'] and present:
379
+ line_after_block = n0 + len(blocklines)
380
+ if line_after_block < len(lines) and lines[line_after_block] != b(os.linesep):
381
+ lines[line_after_block:line_after_block] = blank_line
382
+
340
383
  if lines:
341
384
  result = b''.join(lines)
342
385
  else: