ansible-core 2.17.6rc1__py3-none-any.whl → 2.18.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 (325) hide show
  1. ansible/__main__.py +2 -17
  2. ansible/cli/__init__.py +3 -15
  3. ansible/cli/config.py +187 -24
  4. ansible/cli/console.py +1 -1
  5. ansible/cli/doc.py +38 -16
  6. ansible/cli/galaxy.py +3 -49
  7. ansible/cli/inventory.py +2 -2
  8. ansible/cli/pull.py +2 -2
  9. ansible/cli/scripts/ansible_connection_cli_stub.py +1 -10
  10. ansible/config/base.yml +127 -57
  11. ansible/config/manager.py +89 -11
  12. ansible/constants.py +32 -9
  13. ansible/errors/__init__.py +5 -0
  14. ansible/executor/interpreter_discovery.py +1 -1
  15. ansible/executor/play_iterator.py +16 -0
  16. ansible/executor/playbook_executor.py +1 -4
  17. ansible/executor/powershell/become_wrapper.ps1 +4 -5
  18. ansible/executor/powershell/bootstrap_wrapper.ps1 +2 -3
  19. ansible/executor/powershell/exec_wrapper.ps1 +1 -1
  20. ansible/executor/powershell/module_manifest.py +2 -2
  21. ansible/executor/task_executor.py +50 -39
  22. ansible/executor/task_queue_manager.py +1 -1
  23. ansible/executor/task_result.py +1 -1
  24. ansible/galaxy/api.py +3 -4
  25. ansible/galaxy/collection/__init__.py +21 -10
  26. ansible/galaxy/collection/concrete_artifact_manager.py +2 -2
  27. ansible/galaxy/collection/galaxy_api_proxy.py +10 -16
  28. ansible/galaxy/collection/gpg.py +17 -23
  29. ansible/galaxy/data/COPYING +7 -0
  30. ansible/galaxy/data/apb/Dockerfile.j2 +1 -0
  31. ansible/galaxy/data/apb/Makefile.j2 +1 -0
  32. ansible/galaxy/data/apb/README.md +7 -3
  33. ansible/galaxy/data/apb/apb.yml.j2 +1 -0
  34. ansible/galaxy/data/apb/defaults/main.yml.j2 +1 -0
  35. ansible/galaxy/data/apb/handlers/main.yml.j2 +1 -0
  36. ansible/galaxy/data/apb/meta/main.yml.j2 +1 -0
  37. ansible/galaxy/data/apb/playbooks/deprovision.yml.j2 +1 -0
  38. ansible/galaxy/data/apb/playbooks/provision.yml.j2 +1 -0
  39. ansible/galaxy/data/apb/tasks/main.yml.j2 +1 -0
  40. ansible/galaxy/data/apb/tests/ansible.cfg +1 -0
  41. ansible/galaxy/data/apb/tests/inventory +1 -0
  42. ansible/galaxy/data/apb/tests/test.yml.j2 +1 -0
  43. ansible/galaxy/data/apb/vars/main.yml.j2 +1 -0
  44. ansible/galaxy/data/collections_galaxy_meta.yml +1 -0
  45. ansible/galaxy/data/container/defaults/main.yml.j2 +1 -0
  46. ansible/galaxy/data/container/handlers/main.yml.j2 +1 -0
  47. ansible/galaxy/data/container/meta/container.yml.j2 +1 -0
  48. ansible/galaxy/data/container/meta/main.yml.j2 +1 -0
  49. ansible/galaxy/data/container/tasks/main.yml.j2 +1 -0
  50. ansible/galaxy/data/container/tests/ansible.cfg +1 -0
  51. ansible/galaxy/data/container/tests/inventory +1 -0
  52. ansible/galaxy/data/container/tests/test.yml.j2 +1 -0
  53. ansible/galaxy/data/container/vars/main.yml.j2 +1 -0
  54. ansible/galaxy/data/default/collection/README.md.j2 +1 -0
  55. ansible/galaxy/data/default/collection/galaxy.yml.j2 +1 -0
  56. ansible/galaxy/data/default/collection/meta/runtime.yml +1 -0
  57. ansible/galaxy/data/default/collection/plugins/README.md.j2 +1 -0
  58. ansible/galaxy/data/default/role/defaults/main.yml.j2 +1 -0
  59. ansible/galaxy/data/default/role/handlers/main.yml.j2 +1 -0
  60. ansible/galaxy/data/default/role/meta/main.yml.j2 +1 -0
  61. ansible/galaxy/data/default/role/tasks/main.yml.j2 +1 -0
  62. ansible/galaxy/data/default/role/tests/inventory +1 -0
  63. ansible/galaxy/data/default/role/tests/test.yml.j2 +1 -0
  64. ansible/galaxy/data/default/role/vars/main.yml.j2 +1 -0
  65. ansible/galaxy/data/network/cliconf_plugins/example.py.j2 +1 -0
  66. ansible/galaxy/data/network/defaults/main.yml.j2 +1 -0
  67. ansible/galaxy/data/network/library/example_command.py.j2 +1 -0
  68. ansible/galaxy/data/network/library/example_config.py.j2 +1 -0
  69. ansible/galaxy/data/network/library/example_facts.py.j2 +1 -0
  70. ansible/galaxy/data/network/meta/main.yml.j2 +1 -0
  71. ansible/galaxy/data/network/module_utils/example.py.j2 +1 -0
  72. ansible/galaxy/data/network/netconf_plugins/example.py.j2 +1 -0
  73. ansible/galaxy/data/network/tasks/main.yml.j2 +1 -0
  74. ansible/galaxy/data/network/terminal_plugins/example.py.j2 +1 -0
  75. ansible/galaxy/data/network/tests/inventory +1 -0
  76. ansible/galaxy/data/network/tests/test.yml.j2 +1 -0
  77. ansible/galaxy/data/network/vars/main.yml.j2 +1 -0
  78. ansible/galaxy/dependency_resolution/providers.py +3 -3
  79. ansible/galaxy/role.py +1 -1
  80. ansible/galaxy/token.py +20 -8
  81. ansible/keyword_desc.yml +1 -1
  82. ansible/module_utils/_internal/__init__.py +0 -0
  83. ansible/module_utils/_internal/_concurrent/__init__.py +0 -0
  84. ansible/module_utils/_internal/_concurrent/_daemon_threading.py +28 -0
  85. ansible/module_utils/_internal/_concurrent/_futures.py +21 -0
  86. ansible/module_utils/ansible_release.py +2 -2
  87. ansible/module_utils/api.py +2 -2
  88. ansible/module_utils/basic.py +8 -8
  89. ansible/module_utils/common/collections.py +1 -1
  90. ansible/module_utils/common/file.py +0 -6
  91. ansible/module_utils/common/process.py +22 -9
  92. ansible/module_utils/common/text/converters.py +5 -8
  93. ansible/module_utils/common/text/formatters.py +20 -4
  94. ansible/module_utils/common/validation.py +33 -25
  95. ansible/module_utils/compat/paramiko.py +6 -1
  96. ansible/module_utils/compat/selinux.py +2 -2
  97. ansible/module_utils/connection.py +8 -24
  98. ansible/module_utils/csharp/Ansible.Become.cs +14 -25
  99. ansible/module_utils/csharp/Ansible.Process.cs +1 -1
  100. ansible/module_utils/distro/__init__.py +1 -1
  101. ansible/module_utils/distro/_distro.py +8 -4
  102. ansible/module_utils/facts/collector.py +2 -0
  103. ansible/module_utils/facts/default_collectors.py +3 -1
  104. ansible/module_utils/facts/hardware/aix.py +54 -52
  105. ansible/module_utils/facts/hardware/darwin.py +37 -34
  106. ansible/module_utils/facts/hardware/freebsd.py +55 -15
  107. ansible/module_utils/facts/hardware/hpux.py +3 -0
  108. ansible/module_utils/facts/hardware/linux.py +101 -57
  109. ansible/module_utils/facts/hardware/netbsd.py +3 -0
  110. ansible/module_utils/facts/hardware/openbsd.py +4 -1
  111. ansible/module_utils/facts/hardware/sunos.py +7 -1
  112. ansible/module_utils/facts/network/aix.py +16 -17
  113. ansible/module_utils/facts/network/fc_wwn.py +4 -1
  114. ansible/module_utils/facts/network/hpux.py +21 -4
  115. ansible/module_utils/facts/network/iscsi.py +7 -8
  116. ansible/module_utils/facts/network/linux.py +0 -2
  117. ansible/module_utils/facts/other/facter.py +9 -4
  118. ansible/module_utils/facts/other/ohai.py +5 -5
  119. ansible/module_utils/facts/packages.py +49 -7
  120. ansible/module_utils/facts/sysctl.py +33 -31
  121. ansible/module_utils/facts/system/distribution.py +1 -1
  122. ansible/module_utils/facts/system/local.py +12 -22
  123. ansible/module_utils/facts/system/service_mgr.py +3 -1
  124. ansible/module_utils/facts/system/systemd.py +47 -0
  125. ansible/module_utils/powershell/Ansible.ModuleUtils.AddType.psm1 +1 -1
  126. ansible/module_utils/powershell/Ansible.ModuleUtils.CamelConversion.psm1 +1 -1
  127. ansible/module_utils/splitter.py +1 -1
  128. ansible/modules/add_host.py +1 -1
  129. ansible/modules/apt.py +43 -32
  130. ansible/modules/apt_key.py +6 -6
  131. ansible/modules/apt_repository.py +23 -14
  132. ansible/modules/assemble.py +7 -2
  133. ansible/modules/assert.py +4 -4
  134. ansible/modules/blockinfile.py +3 -6
  135. ansible/modules/command.py +1 -1
  136. ansible/modules/copy.py +4 -4
  137. ansible/modules/cron.py +13 -10
  138. ansible/modules/deb822_repository.py +16 -17
  139. ansible/modules/debconf.py +9 -9
  140. ansible/modules/debug.py +1 -1
  141. ansible/modules/dnf.py +79 -164
  142. ansible/modules/dnf5.py +54 -29
  143. ansible/modules/dpkg_selections.py +2 -2
  144. ansible/modules/expect.py +2 -2
  145. ansible/modules/fetch.py +2 -2
  146. ansible/modules/file.py +5 -3
  147. ansible/modules/find.py +40 -12
  148. ansible/modules/gather_facts.py +4 -2
  149. ansible/modules/get_url.py +29 -24
  150. ansible/modules/git.py +35 -35
  151. ansible/modules/group.py +71 -1
  152. ansible/modules/hostname.py +2 -4
  153. ansible/modules/include_vars.py +5 -5
  154. ansible/modules/iptables.py +13 -16
  155. ansible/modules/known_hosts.py +16 -13
  156. ansible/modules/lineinfile.py +1 -4
  157. ansible/modules/meta.py +6 -1
  158. ansible/modules/mount_facts.py +651 -0
  159. ansible/modules/package_facts.py +63 -80
  160. ansible/modules/pause.py +4 -3
  161. ansible/modules/pip.py +14 -14
  162. ansible/modules/replace.py +1 -4
  163. ansible/modules/rpm_key.py +31 -11
  164. ansible/modules/service.py +8 -8
  165. ansible/modules/service_facts.py +20 -5
  166. ansible/modules/set_stats.py +1 -1
  167. ansible/modules/setup.py +3 -3
  168. ansible/modules/stat.py +3 -3
  169. ansible/modules/subversion.py +1 -1
  170. ansible/modules/systemd.py +16 -10
  171. ansible/modules/systemd_service.py +16 -10
  172. ansible/modules/sysvinit.py +4 -4
  173. ansible/modules/unarchive.py +35 -22
  174. ansible/modules/uri.py +24 -18
  175. ansible/modules/user.py +145 -12
  176. ansible/modules/validate_argument_spec.py +3 -3
  177. ansible/modules/wait_for_connection.py +2 -1
  178. ansible/modules/yum_repository.py +136 -179
  179. ansible/parsing/dataloader.py +2 -2
  180. ansible/parsing/mod_args.py +11 -10
  181. ansible/parsing/vault/__init__.py +8 -3
  182. ansible/parsing/yaml/constructor.py +10 -8
  183. ansible/parsing/yaml/objects.py +1 -1
  184. ansible/playbook/base.py +12 -23
  185. ansible/playbook/helpers.py +4 -0
  186. ansible/playbook/loop_control.py +8 -0
  187. ansible/playbook/play.py +4 -22
  188. ansible/playbook/play_context.py +0 -16
  189. ansible/playbook/playbook_include.py +2 -2
  190. ansible/playbook/role/__init__.py +2 -2
  191. ansible/plugins/__init__.py +2 -0
  192. ansible/plugins/action/__init__.py +7 -9
  193. ansible/plugins/action/dnf.py +7 -5
  194. ansible/plugins/action/package.py +5 -4
  195. ansible/plugins/action/reboot.py +2 -2
  196. ansible/plugins/become/__init__.py +1 -1
  197. ansible/plugins/callback/__init__.py +44 -3
  198. ansible/plugins/callback/default.py +1 -1
  199. ansible/plugins/cliconf/__init__.py +1 -1
  200. ansible/plugins/connection/paramiko_ssh.py +2 -80
  201. ansible/plugins/connection/psrp.py +33 -82
  202. ansible/plugins/connection/ssh.py +0 -8
  203. ansible/plugins/connection/winrm.py +46 -1
  204. ansible/plugins/doc_fragments/connection_pipelining.py +2 -2
  205. ansible/plugins/doc_fragments/constructed.py +10 -10
  206. ansible/plugins/doc_fragments/default_callback.py +8 -8
  207. ansible/plugins/doc_fragments/files.py +5 -5
  208. ansible/plugins/doc_fragments/inventory_cache.py +2 -2
  209. ansible/plugins/doc_fragments/result_format_callback.py +6 -6
  210. ansible/plugins/doc_fragments/return_common.py +1 -1
  211. ansible/plugins/doc_fragments/shell_common.py +2 -10
  212. ansible/plugins/doc_fragments/shell_windows.py +0 -9
  213. ansible/plugins/doc_fragments/url.py +2 -2
  214. ansible/plugins/doc_fragments/url_windows.py +4 -5
  215. ansible/plugins/doc_fragments/validate.py +1 -1
  216. ansible/plugins/filter/core.py +2 -0
  217. ansible/plugins/filter/human_to_bytes.yml +9 -0
  218. ansible/plugins/filter/password_hash.yml +1 -1
  219. ansible/plugins/filter/strftime.yml +1 -1
  220. ansible/plugins/filter/to_nice_json.yml +7 -3
  221. ansible/plugins/filter/to_uuid.yml +1 -1
  222. ansible/plugins/inventory/script.py +1 -1
  223. ansible/plugins/list.py +1 -1
  224. ansible/plugins/loader.py +0 -11
  225. ansible/plugins/lookup/config.py +1 -1
  226. ansible/plugins/lookup/csvfile.py +21 -9
  227. ansible/plugins/lookup/env.py +8 -9
  228. ansible/plugins/lookup/ini.py +10 -1
  229. ansible/plugins/lookup/random_choice.py +2 -2
  230. ansible/plugins/lookup/url.py +7 -2
  231. ansible/plugins/shell/__init__.py +15 -20
  232. ansible/plugins/shell/powershell.py +9 -6
  233. ansible/plugins/strategy/__init__.py +16 -7
  234. ansible/plugins/test/core.py +23 -1
  235. ansible/plugins/test/issubset.yml +1 -1
  236. ansible/plugins/test/subset.yml +1 -1
  237. ansible/plugins/test/timedout.yml +20 -0
  238. ansible/plugins/test/vault_encrypted.yml +6 -6
  239. ansible/plugins/test/vaulted_file.yml +19 -0
  240. ansible/release.py +2 -2
  241. ansible/template/__init__.py +3 -8
  242. ansible/utils/collection_loader/_collection_finder.py +23 -55
  243. ansible/utils/display.py +44 -31
  244. ansible/utils/jsonrpc.py +1 -1
  245. ansible/utils/listify.py +1 -5
  246. ansible/utils/path.py +3 -0
  247. ansible/utils/vars.py +18 -27
  248. ansible/vars/manager.py +7 -150
  249. ansible/vars/plugins.py +1 -1
  250. ansible_core-2.18.0.dist-info/Apache-License.txt +202 -0
  251. {ansible_core-2.17.6rc1.dist-info → ansible_core-2.18.0.dist-info}/METADATA +36 -23
  252. ansible_core-2.18.0.dist-info/MIT-license.txt +14 -0
  253. ansible_core-2.18.0.dist-info/PSF-license.txt +48 -0
  254. {ansible_core-2.17.6rc1.dist-info → ansible_core-2.18.0.dist-info}/RECORD +316 -311
  255. {ansible_core-2.17.6rc1.dist-info → ansible_core-2.18.0.dist-info}/entry_points.txt +1 -1
  256. ansible_core-2.18.0.dist-info/simplified_bsd.txt +8 -0
  257. ansible_test/_data/completion/docker.txt +7 -7
  258. ansible_test/_data/completion/remote.txt +5 -4
  259. ansible_test/_data/completion/windows.txt +4 -4
  260. ansible_test/_data/requirements/ansible-test.txt +1 -2
  261. ansible_test/_data/requirements/constraints.txt +1 -2
  262. ansible_test/_data/requirements/sanity.ansible-doc.txt +3 -3
  263. ansible_test/_data/requirements/sanity.changelog.in +1 -1
  264. ansible_test/_data/requirements/sanity.changelog.txt +4 -4
  265. ansible_test/_data/requirements/sanity.import.plugin.txt +2 -2
  266. ansible_test/_data/requirements/sanity.import.txt +1 -1
  267. ansible_test/_data/requirements/sanity.integration-aliases.txt +1 -1
  268. ansible_test/_data/requirements/sanity.pep8.txt +1 -1
  269. ansible_test/_data/requirements/sanity.pylint.txt +6 -8
  270. ansible_test/_data/requirements/sanity.runtime-metadata.txt +2 -2
  271. ansible_test/_data/requirements/sanity.validate-modules.txt +3 -3
  272. ansible_test/_data/requirements/sanity.yamllint.in +1 -0
  273. ansible_test/_data/requirements/sanity.yamllint.txt +1 -1
  274. ansible_test/_internal/ansible_util.py +8 -35
  275. ansible_test/_internal/ci/azp.py +1 -1
  276. ansible_test/_internal/classification/__init__.py +0 -2
  277. ansible_test/_internal/cli/parsers/key_value_parsers.py +3 -0
  278. ansible_test/_internal/commands/integration/cloud/hcloud.py +1 -1
  279. ansible_test/_internal/commands/integration/cloud/httptester.py +1 -1
  280. ansible_test/_internal/commands/integration/cloud/nios.py +1 -1
  281. ansible_test/_internal/commands/sanity/__init__.py +96 -19
  282. ansible_test/_internal/commands/sanity/pylint.py +20 -24
  283. ansible_test/_internal/completion.py +2 -0
  284. ansible_test/_internal/constants.py +0 -1
  285. ansible_test/_internal/coverage_util.py +1 -2
  286. ansible_test/_internal/docker_util.py +1 -1
  287. ansible_test/_internal/encoding.py +4 -4
  288. ansible_test/_internal/host_configs.py +10 -0
  289. ansible_test/_internal/host_profiles.py +9 -13
  290. ansible_test/_internal/pypi_proxy.py +1 -1
  291. ansible_test/_internal/python_requirements.py +5 -14
  292. ansible_test/_internal/timeout.py +1 -1
  293. ansible_test/_internal/util.py +40 -0
  294. ansible_test/_internal/util_common.py +5 -1
  295. ansible_test/_util/controller/sanity/code-smell/action-plugin-docs.json +3 -1
  296. ansible_test/_util/controller/sanity/code-smell/action-plugin-docs.py +6 -3
  297. ansible_test/_util/controller/sanity/code-smell/empty-init.json +0 -2
  298. ansible_test/_util/controller/sanity/pylint/config/ansible-test-target.cfg +5 -0
  299. ansible_test/_util/controller/sanity/pylint/config/ansible-test.cfg +5 -0
  300. ansible_test/_util/controller/sanity/pylint/config/code-smell.cfg +5 -0
  301. ansible_test/_util/controller/sanity/pylint/config/collection.cfg +6 -0
  302. ansible_test/_util/controller/sanity/pylint/config/default.cfg +6 -0
  303. ansible_test/_util/controller/sanity/pylint/plugins/deprecated.py +1 -19
  304. ansible_test/_util/controller/sanity/shellcheck/exclude.txt +1 -0
  305. ansible_test/_util/controller/sanity/validate-modules/validate_modules/main.py +67 -2
  306. ansible_test/_util/controller/sanity/validate-modules/validate_modules/schema.py +27 -5
  307. ansible_test/_util/target/cli/ansible_test_cli_stub.py +0 -0
  308. ansible_test/_util/target/common/constants.py +2 -2
  309. ansible_test/_util/target/injector/python.py +5 -0
  310. ansible_test/_util/target/pytest/plugins/ansible_pytest_coverage.py +6 -0
  311. ansible_test/_util/target/sanity/import/importer.py +1 -1
  312. ansible_test/_util/target/setup/bootstrap.sh +6 -17
  313. ansible_test/_util/target/setup/requirements.py +18 -24
  314. ansible_test/config/config.yml +1 -1
  315. ansible_core-2.17.6rc1.data/scripts/ansible-test +0 -44
  316. ansible_test/_data/requirements/sanity.mypy.in +0 -10
  317. ansible_test/_data/requirements/sanity.mypy.txt +0 -18
  318. ansible_test/_internal/commands/sanity/mypy.py +0 -274
  319. ansible_test/_util/controller/sanity/mypy/ansible-core.ini +0 -116
  320. ansible_test/_util/controller/sanity/mypy/ansible-test.ini +0 -27
  321. ansible_test/_util/controller/sanity/mypy/modules.ini +0 -92
  322. ansible_test/_util/controller/sanity/mypy/packaging.ini +0 -20
  323. {ansible_core-2.17.6rc1.dist-info → ansible_core-2.18.0.dist-info}/COPYING +0 -0
  324. {ansible_core-2.17.6rc1.dist-info → ansible_core-2.18.0.dist-info}/WHEEL +0 -0
  325. {ansible_core-2.17.6rc1.dist-info → ansible_core-2.18.0.dist-info}/top_level.txt +0 -0
@@ -1,3 +1,4 @@
1
+ #SPDX-License-Identifier: MIT-0
1
2
  ---
2
3
  - hosts: localhost
3
4
  gather_facts: no
@@ -1,2 +1,3 @@
1
+ #SPDX-License-Identifier: MIT-0
1
2
  ---
2
3
  # vars file for {{ role_name }}
@@ -1,3 +1,4 @@
1
+ #SPDX-License-Identifier: MIT-0
1
2
  # Copyright (c) 2019 Ansible Project
2
3
  # GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
3
4
 
@@ -1,2 +1,3 @@
1
+ #SPDX-License-Identifier: MIT-0
1
2
  ---
2
3
  # defaults file for {{ role_name }}
@@ -1,2 +1,3 @@
1
+ #SPDX-License-Identifier: MIT-0
1
2
  ---
2
3
  # handlers file for {{ role_name }}
@@ -1,3 +1,4 @@
1
+ #SPDX-License-Identifier: MIT-0
1
2
  # Add your Ansible Container service definitions here.
2
3
  # For example:
3
4
  #
@@ -1,3 +1,4 @@
1
+ #SPDX-License-Identifier: MIT-0
1
2
  galaxy_info:
2
3
  author: {{ author }}
3
4
  description: {{ description }}
@@ -1,2 +1,3 @@
1
+ #SPDX-License-Identifier: MIT-0
1
2
  ---
2
3
  # tasks file for {{ role_name }}
@@ -1,2 +1,3 @@
1
+ #SPDX-License-Identifier: MIT-0
1
2
  [defaults]
2
3
  inventory=./inventory
@@ -1,3 +1,4 @@
1
+ #SPDX-License-Identifier: MIT-0
1
2
  localhost
2
3
 
3
4
 
@@ -1,3 +1,4 @@
1
+ #SPDX-License-Identifier: MIT-0
1
2
  ---
2
3
  - hosts: localhost
3
4
  gather_facts: no
@@ -1,2 +1,3 @@
1
+ #SPDX-License-Identifier: MIT-0
1
2
  ---
2
3
  # vars file for {{ role_name }}
@@ -1,3 +1,4 @@
1
+ {# SPDX-License-Identifier: MIT-0 #}
1
2
  # Ansible Collection - {{ namespace }}.{{ collection_name }}
2
3
 
3
4
  Documentation for the collection.
@@ -1,3 +1,4 @@
1
+ #SPDX-License-Identifier: MIT-0
1
2
  ### REQUIRED
2
3
  {% for option in required_config %}
3
4
  {{ option.description | comment_ify }}
@@ -1,3 +1,4 @@
1
+ #SPDX-License-Identifier: MIT-0
1
2
  ---
2
3
  # Collections must specify a minimum required ansible version to upload
3
4
  # to galaxy
@@ -1,3 +1,4 @@
1
+ {# SPDX-License-Identifier: MIT-0 #}
1
2
  # Collections Plugins Directory
2
3
 
3
4
  This directory can be used to ship various plugins inside an Ansible collection. Each plugin is placed in a folder that
@@ -1,2 +1,3 @@
1
+ #SPDX-License-Identifier: MIT-0
1
2
  ---
2
3
  # defaults file for {{ role_name }}
@@ -1,2 +1,3 @@
1
+ #SPDX-License-Identifier: MIT-0
1
2
  ---
2
3
  # handlers file for {{ role_name }}
@@ -1,3 +1,4 @@
1
+ #SPDX-License-Identifier: MIT-0
1
2
  galaxy_info:
2
3
  author: {{ author }}
3
4
  description: {{ description }}
@@ -1,2 +1,3 @@
1
+ #SPDX-License-Identifier: MIT-0
1
2
  ---
2
3
  # tasks file for {{ role_name }}
@@ -1,2 +1,3 @@
1
+ #SPDX-License-Identifier: MIT-0
1
2
  localhost
2
3
 
@@ -1,3 +1,4 @@
1
+ #SPDX-License-Identifier: MIT-0
1
2
  ---
2
3
  - hosts: localhost
3
4
  remote_user: root
@@ -1,2 +1,3 @@
1
+ #SPDX-License-Identifier: MIT-0
1
2
  ---
2
3
  # vars file for {{ role_name }}
@@ -1,3 +1,4 @@
1
+ #SPDX-License-Identifier: MIT-0
1
2
  #
2
3
  # (c) 2018 Red Hat Inc.
3
4
  #
@@ -1,2 +1,3 @@
1
+ #SPDX-License-Identifier: MIT-0
1
2
  ---
2
3
  # defaults file for {{ role_name }}
@@ -1,3 +1,4 @@
1
+ #SPDX-License-Identifier: MIT-0
1
2
  #
2
3
  # (c) 2018 Red Hat Inc.
3
4
  #
@@ -1,3 +1,4 @@
1
+ #SPDX-License-Identifier: MIT-0
1
2
  #
2
3
  # (c) 2018 Red Hat Inc.
3
4
  #
@@ -1,3 +1,4 @@
1
+ #SPDX-License-Identifier: MIT-0
1
2
  #
2
3
  # (c) 2018 Red Hat Inc.
3
4
  #
@@ -1,3 +1,4 @@
1
+ #SPDX-License-Identifier: MIT-0
1
2
  galaxy_info:
2
3
  author: {{ author }}
3
4
  description: {{ description }}
@@ -1,3 +1,4 @@
1
+ #SPDX-License-Identifier: MIT-0
1
2
  #
2
3
  # (c) 2018 Red Hat Inc.
3
4
  #
@@ -1,3 +1,4 @@
1
+ #SPDX-License-Identifier: MIT-0
1
2
  #
2
3
  # (c) 2018 Red Hat Inc.
3
4
  #
@@ -1,2 +1,3 @@
1
+ #SPDX-License-Identifier: MIT-0
1
2
  ---
2
3
  # tasks file for {{ role_name }}
@@ -1,3 +1,4 @@
1
+ #SPDX-License-Identifier: MIT-0
1
2
  #
2
3
  # (c) 2018 Red Hat Inc.
3
4
  #
@@ -1,2 +1,3 @@
1
+ #SPDX-License-Identifier: MIT-0
1
2
  localhost
2
3
 
@@ -1,3 +1,4 @@
1
+ #SPDX-License-Identifier: MIT-0
1
2
  ---
2
3
  - hosts: localhost
3
4
  connection: network_cli
@@ -1,2 +1,3 @@
1
+ #SPDX-License-Identifier: MIT-0
1
2
  ---
2
3
  # vars file for {{ role_name }}
@@ -126,7 +126,7 @@ class CollectionDependencyProviderBase(AbstractProvider):
126
126
  the current candidate list
127
127
 
128
128
  * ``parent`` specifies the candidate that provides
129
- (dependend on) the requirement, or `None`
129
+ (depended on) the requirement, or `None`
130
130
  to indicate a root requirement.
131
131
 
132
132
  resolvelib >=0.7.0, < 0.8.0
@@ -202,7 +202,7 @@ class CollectionDependencyProviderBase(AbstractProvider):
202
202
  remote archives), the one-and-only match is returned
203
203
 
204
204
  For a "named" requirement, Galaxy-compatible APIs are consulted
205
- to find concrete candidates for this requirement. Of theres a
205
+ to find concrete candidates for this requirement. If there's a
206
206
  pre-installed candidate, it's prepended in front of others.
207
207
 
208
208
  resolvelib >=0.5.3, <0.6.0
@@ -437,7 +437,7 @@ class CollectionDependencyProviderBase(AbstractProvider):
437
437
  # FIXME: differs. So how do we resolve this case? Priority?
438
438
  # FIXME: Taking into account a pinned hash? Exploding on
439
439
  # FIXME: any differences?
440
- # NOTE: The underlying implmentation currently uses first found
440
+ # NOTE: The underlying implementation currently uses first found
441
441
  req_map = self._api_proxy.get_collection_dependencies(candidate)
442
442
 
443
443
  # NOTE: This guard expression MUST perform an early exit only
ansible/galaxy/role.py CHANGED
@@ -256,7 +256,7 @@ class GalaxyRole(object):
256
256
  display.display("- downloading role from %s" % archive_url)
257
257
 
258
258
  try:
259
- url_file = open_url(archive_url, validate_certs=self._validate_certs, http_agent=user_agent())
259
+ url_file = open_url(archive_url, validate_certs=self._validate_certs, http_agent=user_agent(), timeout=60)
260
260
  temp_file = tempfile.NamedTemporaryFile(delete=False)
261
261
  data = url_file.read()
262
262
  while data:
ansible/galaxy/token.py CHANGED
@@ -21,11 +21,14 @@
21
21
  from __future__ import annotations
22
22
 
23
23
  import base64
24
- import os
25
24
  import json
25
+ import os
26
+ import time
26
27
  from stat import S_IRUSR, S_IWUSR
28
+ from urllib.error import HTTPError
27
29
 
28
30
  from ansible import constants as C
31
+ from ansible.galaxy.api import GalaxyError
29
32
  from ansible.galaxy.user_agent import user_agent
30
33
  from ansible.module_utils.common.text.converters import to_bytes, to_native, to_text
31
34
  from ansible.module_utils.common.yaml import yaml_dump, yaml_load
@@ -57,12 +60,16 @@ class KeycloakToken(object):
57
60
  self.client_id = client_id
58
61
  if self.client_id is None:
59
62
  self.client_id = 'cloud-services'
63
+ self._expiration = None
60
64
 
61
65
  def _form_payload(self):
62
66
  return 'grant_type=refresh_token&client_id=%s&refresh_token=%s' % (self.client_id,
63
67
  self.access_token)
64
68
 
65
69
  def get(self):
70
+ if self._expiration and time.time() >= self._expiration:
71
+ self._token = None
72
+
66
73
  if self._token:
67
74
  return self._token
68
75
 
@@ -76,15 +83,20 @@ class KeycloakToken(object):
76
83
  # or 'azp' (Authorized party - the party to which the ID Token was issued)
77
84
  payload = self._form_payload()
78
85
 
79
- resp = open_url(to_native(self.auth_url),
80
- data=payload,
81
- validate_certs=self.validate_certs,
82
- method='POST',
83
- http_agent=user_agent())
86
+ try:
87
+ resp = open_url(to_native(self.auth_url),
88
+ data=payload,
89
+ validate_certs=self.validate_certs,
90
+ method='POST',
91
+ http_agent=user_agent())
92
+ except HTTPError as e:
93
+ raise GalaxyError(e, 'Unable to get access token')
84
94
 
85
- # TODO: handle auth errors
95
+ data = json.load(resp)
86
96
 
87
- data = json.loads(to_text(resp.read(), errors='surrogate_or_strict'))
97
+ # So that we have a buffer, expire the token in ~2/3 the given value
98
+ expires_in = data['expires_in'] // 3 * 2
99
+ self._expiration = time.time() + expires_in
88
100
 
89
101
  # - extract 'access_token'
90
102
  self._token = data.get('access_token')
ansible/keyword_desc.yml CHANGED
@@ -61,7 +61,7 @@ serial: Explicitly define how Ansible batches the execution of the current play
61
61
  strategy: Allows you to choose the strategy plugin to use for the play. See :ref:`strategy_plugins`.
62
62
  tags: Tags applied to the task or included tasks, this allows selecting subsets of tasks from the command line.
63
63
  tasks: Main list of tasks to execute in the play, they run after :term:`roles` and before :term:`post_tasks`.
64
- timeout: Time limit for the task to execute in, if exceeded Ansible will interrupt and fail the task.
64
+ timeout: Time limit for the task action to execute in, if exceeded, Ansible will interrupt the process. Timeout does not include templating or looping.
65
65
  throttle: Limit the number of concurrent task runs on task, block and playbook level. This is independent of the forks and serial settings, but cannot be set higher than those limits. For example, if forks is set to 10 and the throttle is set to 15, at most 10 hosts will be operated on in parallel.
66
66
  until: "This keyword implies a ':term:`retries` loop' that will go on until the condition supplied here is met or we hit the :term:`retries` limit."
67
67
  vars: Dictionary/map of variables
File without changes
File without changes
@@ -0,0 +1,28 @@
1
+ """Proxy stdlib threading module that only supports non-joinable daemon threads."""
2
+ # NB: all new local module attrs are _ prefixed to ensure an identical public attribute surface area to the module we're proxying
3
+
4
+ from __future__ import annotations as _annotations
5
+
6
+ import threading as _threading
7
+ import typing as _t
8
+
9
+
10
+ class _DaemonThread(_threading.Thread):
11
+ """
12
+ Daemon-only Thread subclass; prevents running threads of this type from blocking interpreter shutdown and process exit.
13
+ The join() method is a no-op.
14
+ """
15
+
16
+ def __init__(self, *args, daemon: bool | None = None, **kwargs) -> None:
17
+ super().__init__(*args, daemon=daemon or True, **kwargs)
18
+
19
+ def join(self, timeout=None) -> None:
20
+ """ThreadPoolExecutor's atexit handler joins all queue threads before allowing shutdown; prevent them from blocking."""
21
+
22
+
23
+ Thread = _DaemonThread # shadow the real Thread attr with our _DaemonThread
24
+
25
+
26
+ def __getattr__(name: str) -> _t.Any:
27
+ """Delegate anything not defined locally to the real `threading` module."""
28
+ return getattr(_threading, name)
@@ -0,0 +1,21 @@
1
+ """Utilities for concurrent code execution using futures."""
2
+
3
+ from __future__ import annotations
4
+
5
+ import concurrent.futures
6
+ import types
7
+
8
+ from . import _daemon_threading
9
+
10
+
11
+ class DaemonThreadPoolExecutor(concurrent.futures.ThreadPoolExecutor):
12
+ """ThreadPoolExecutor subclass that creates non-joinable daemon threads for non-blocking pool and process shutdown with abandoned threads."""
13
+
14
+ atc = concurrent.futures.ThreadPoolExecutor._adjust_thread_count
15
+
16
+ # clone the base class `_adjust_thread_count` method with a copy of its globals dict
17
+ _adjust_thread_count = types.FunctionType(atc.__code__, atc.__globals__.copy(), name=atc.__name__, argdefs=atc.__defaults__, closure=atc.__closure__)
18
+ # patch the method closure's `threading` module import to use our daemon-only thread factory instead
19
+ _adjust_thread_count.__globals__.update(threading=_daemon_threading)
20
+
21
+ del atc # don't expose this as a class attribute
@@ -17,6 +17,6 @@
17
17
 
18
18
  from __future__ import annotations
19
19
 
20
- __version__ = '2.17.6rc1'
20
+ __version__ = '2.18.0'
21
21
  __author__ = 'Ansible, Inc.'
22
- __codename__ = "Gallows Pole"
22
+ __codename__ = "Fool in the Rain"
@@ -28,7 +28,7 @@ from __future__ import annotations
28
28
  import copy
29
29
  import functools
30
30
  import itertools
31
- import random
31
+ import secrets
32
32
  import sys
33
33
  import time
34
34
 
@@ -131,7 +131,7 @@ def generate_jittered_backoff(retries=10, delay_base=3, delay_threshold=60):
131
131
  :param delay_threshold: The maximum time in seconds for any delay.
132
132
  """
133
133
  for retry in range(0, retries):
134
- yield random.randint(0, min(delay_threshold, delay_base * 2 ** retry))
134
+ yield secrets.randbelow(min(delay_threshold, delay_base * 2 ** retry))
135
135
 
136
136
 
137
137
  def retry_never(exception_or_result):
@@ -9,7 +9,7 @@ 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
- _PY_MIN = (3, 7)
12
+ _PY_MIN = (3, 8)
13
13
 
14
14
  if sys.version_info < _PY_MIN:
15
15
  print(json.dumps(dict(
@@ -458,7 +458,7 @@ class AnsibleModule(object):
458
458
  self._selinux_mls_enabled = None
459
459
  self._selinux_initial_context = None
460
460
 
461
- # finally, make sure we're in a sane working dir
461
+ # finally, make sure we're in a logical working dir
462
462
  self._set_cwd()
463
463
 
464
464
  @property
@@ -1202,6 +1202,7 @@ class AnsibleModule(object):
1202
1202
  setattr(self, PASS_VARS[k][0], PASS_VARS[k][1])
1203
1203
 
1204
1204
  def safe_eval(self, value, locals=None, include_exceptions=False):
1205
+ # deprecated: description='no longer used in the codebase' core_version='2.21'
1205
1206
  return safe_eval(value, locals, include_exceptions)
1206
1207
 
1207
1208
  def _load_params(self):
@@ -1353,9 +1354,10 @@ class AnsibleModule(object):
1353
1354
  Find system executable in PATH.
1354
1355
 
1355
1356
  :param arg: The executable to find.
1356
- :param required: if executable is not found and required is ``True``, fail_json
1357
+ :param required: if the executable is not found and required is ``True``, fail_json
1357
1358
  :param opt_dirs: optional list of directories to search in addition to ``PATH``
1358
- :returns: if found return full path; otherwise return None
1359
+ :returns: if found return full path; otherwise return original arg, unless 'warning' then return None
1360
+ :raises: Sysexit: if arg is not found and required=True (via fail_json)
1359
1361
  '''
1360
1362
 
1361
1363
  bin_path = None
@@ -1364,8 +1366,6 @@ class AnsibleModule(object):
1364
1366
  except ValueError as e:
1365
1367
  if required:
1366
1368
  self.fail_json(msg=to_text(e))
1367
- else:
1368
- return bin_path
1369
1369
 
1370
1370
  return bin_path
1371
1371
 
@@ -1432,7 +1432,7 @@ class AnsibleModule(object):
1432
1432
  kwargs['deprecations'] = deprecations
1433
1433
 
1434
1434
  # preserve bools/none from no_log
1435
- # TODO: once python version on target high enough, dict comprh
1435
+ # TODO: once python version on target high enough, dict comprehensions
1436
1436
  preserved = {}
1437
1437
  for k, v in kwargs.items():
1438
1438
  if v is None or isinstance(v, bool):
@@ -2061,7 +2061,7 @@ class AnsibleModule(object):
2061
2061
  # not as exact as above, but should be good enough for most platforms that fail the previous call
2062
2062
  buffer_size = select.PIPE_BUF
2063
2063
  except Exception:
2064
- buffer_size = 9000 # use sane default JIC
2064
+ buffer_size = 9000 # use logical default JIC
2065
2065
 
2066
2066
  return buffer_size
2067
2067
 
@@ -65,7 +65,7 @@ class ImmutableDict(Hashable, Mapping):
65
65
 
66
66
 
67
67
  def is_string(seq):
68
- """Identify whether the input has a string-like type (inclding bytes)."""
68
+ """Identify whether the input has a string-like type (including bytes)."""
69
69
  # AnsibleVaultEncryptedUnicode inherits from Sequence, but is expected to be a string like object
70
70
  return isinstance(seq, (text_type, binary_type)) or getattr(seq, '__ENCRYPTED__', False)
71
71
 
@@ -7,12 +7,6 @@ import os
7
7
  import stat
8
8
  import re
9
9
 
10
- try:
11
- import selinux # pylint: disable=unused-import
12
- HAVE_SELINUX = True
13
- except ImportError:
14
- HAVE_SELINUX = False
15
-
16
10
 
17
11
  FILE_ATTRIBUTES = {
18
12
  'A': 'noatime',
@@ -12,13 +12,18 @@ from ansible.module_utils.common.warnings import deprecate
12
12
  def get_bin_path(arg, opt_dirs=None, required=None):
13
13
  '''
14
14
  Find system executable in PATH. Raises ValueError if the executable is not found.
15
- Optional arguments:
16
- - required: [Deprecated] Before 2.10, if executable is not found and required is true it raises an Exception.
17
- In 2.10 and later, an Exception is always raised. This parameter will be removed in 2.21.
18
- - opt_dirs: optional list of directories to search in addition to PATH
15
+
16
+ :param arg: the executable to find
17
+ :type arg: string
18
+ :param opt_dirs: optional list of directories to search in addition to PATH
19
+ :type opt_dirs: list of strings
20
+ :param required: DEPRECATED. This parameter will be removed in 2.21
21
+ :type required: boolean
22
+ :returns: path to arg (should be abs path unless PATH or opt_dirs are relative paths)
23
+ :raises: ValueError: if arg is not found
24
+
19
25
  In addition to PATH and opt_dirs, this function also looks through /sbin, /usr/sbin and /usr/local/sbin. A lot of
20
26
  modules, especially for gathering facts, depend on this behaviour.
21
- If found return full path, otherwise raise ValueError.
22
27
  '''
23
28
  if required is not None:
24
29
  deprecate(
@@ -27,26 +32,34 @@ def get_bin_path(arg, opt_dirs=None, required=None):
27
32
  collection_name="ansible.builtin",
28
33
  )
29
34
 
35
+ paths = []
36
+ sbin_paths = ['/sbin', '/usr/sbin', '/usr/local/sbin']
30
37
  opt_dirs = [] if opt_dirs is None else opt_dirs
31
38
 
32
- sbin_paths = ['/sbin', '/usr/sbin', '/usr/local/sbin']
33
- paths = []
39
+ # Construct possible paths with precedence
40
+ # passed in paths
34
41
  for d in opt_dirs:
35
42
  if d is not None and os.path.exists(d):
36
43
  paths.append(d)
44
+ # system configured paths
37
45
  paths += os.environ.get('PATH', '').split(os.pathsep)
38
- bin_path = None
39
- # mangle PATH to include /sbin dirs
46
+
47
+ # existing /sbin dirs, if not there already
40
48
  for p in sbin_paths:
41
49
  if p not in paths and os.path.exists(p):
42
50
  paths.append(p)
51
+
52
+ # Search for binary
53
+ bin_path = None
43
54
  for d in paths:
44
55
  if not d:
45
56
  continue
46
57
  path = os.path.join(d, arg)
47
58
  if os.path.exists(path) and not os.path.isdir(path) and is_executable(path):
59
+ # fist found wins
48
60
  bin_path = path
49
61
  break
62
+
50
63
  if bin_path is None:
51
64
  raise ValueError('Failed to find required executable "%s" in paths: %s' % (arg, os.pathsep.join(paths)))
52
65
 
@@ -267,14 +267,11 @@ def _json_encode_fallback(obj):
267
267
 
268
268
 
269
269
  def jsonify(data, **kwargs):
270
- # After 2.18, we should remove this loop, and hardcode to utf-8 in alignment with requiring utf-8 module responses
271
- for encoding in ("utf-8", "latin-1"):
272
- try:
273
- new_data = container_to_text(data, encoding=encoding)
274
- except UnicodeDecodeError:
275
- continue
276
- return json.dumps(new_data, default=_json_encode_fallback, **kwargs)
277
- raise UnicodeError('Invalid unicode encoding encountered')
270
+ try:
271
+ new_data = container_to_text(data, encoding='utf-8')
272
+ except UnicodeDecodeError:
273
+ raise UnicodeError('Invalid unicode encoding encountered')
274
+ return json.dumps(new_data, default=_json_encode_fallback, **kwargs)
278
275
 
279
276
 
280
277
  def container_to_bytes(d, encoding='utf-8', errors='surrogate_or_strict'):
@@ -20,6 +20,18 @@ SIZE_RANGES = {
20
20
  'B': 1,
21
21
  }
22
22
 
23
+ VALID_UNITS = {
24
+ 'B': (('byte', 'B'), ('bit', 'b')),
25
+ 'K': (('kilobyte', 'KB'), ('kilobit', 'Kb')),
26
+ 'M': (('megabyte', 'MB'), ('megabit', 'Mb')),
27
+ 'G': (('gigabyte', 'GB'), ('gigabit', 'Gb')),
28
+ 'T': (('terabyte', 'TB'), ('terabit', 'Tb')),
29
+ 'P': (('petabyte', 'PB'), ('petabit', 'Pb')),
30
+ 'E': (('exabyte', 'EB'), ('exabit', 'Eb')),
31
+ 'Z': (('zetabyte', 'ZB'), ('zetabit', 'Zb')),
32
+ 'Y': (('yottabyte', 'YB'), ('yottabit', 'Yb')),
33
+ }
34
+
23
35
 
24
36
  def lenient_lowercase(lst):
25
37
  """Lowercase elements of a list.
@@ -53,7 +65,8 @@ def human_to_bytes(number, default_unit=None, isbits=False):
53
65
  The function expects 'b' (lowercase) as a bit identifier, e.g. 'Mb'/'Kb'/etc.
54
66
  if 'MB'/'KB'/... is passed, the ValueError will be rased.
55
67
  """
56
- m = re.search(r'^\s*(\d*\.?\d*)\s*([A-Za-z]+)?', str(number), flags=re.IGNORECASE)
68
+ m = re.search(r'^([0-9]*\.?[0-9]+)(?:\s*([A-Za-z]+))?\s*$', str(number))
69
+
57
70
  if m is None:
58
71
  raise ValueError("human_to_bytes() can't interpret following string: %s" % str(number))
59
72
  try:
@@ -86,10 +99,13 @@ def human_to_bytes(number, default_unit=None, isbits=False):
86
99
  expect_message = 'expect %s%s or %s' % (range_key, unit_class, range_key)
87
100
  if range_key == 'B':
88
101
  expect_message = 'expect %s or %s' % (unit_class, unit_class_name)
89
-
90
- if unit_class_name in unit.lower():
102
+ unit_group = VALID_UNITS.get(range_key, None)
103
+ if unit_group is None:
104
+ raise ValueError(f"human_to_bytes() can't interpret a valid unit for {range_key}")
105
+ isbits_flag = 1 if isbits else 0
106
+ if unit.lower() == unit_group[isbits_flag][0]:
91
107
  pass
92
- elif unit[1] != unit_class:
108
+ elif unit != unit_group[isbits_flag][1]:
93
109
  raise ValueError("human_to_bytes() failed to convert %s. Value is not a valid string (%s)" % (number, expect_message))
94
110
 
95
111
  return int(round(num * limit))