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,10 +1,8 @@
1
- #!/usr/bin/env python
2
1
  # Copyright: (c) 2017, Ansible Project
3
2
  # GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
4
3
  from __future__ import annotations
5
4
 
6
5
  import fcntl
7
- import hashlib
8
6
  import io
9
7
  import os
10
8
  import pickle
@@ -40,13 +38,6 @@ def read_stream(byte_stream):
40
38
  if len(data) < size:
41
39
  raise Exception("EOF found before data was complete")
42
40
 
43
- data_hash = to_text(byte_stream.readline().strip())
44
- if data_hash != hashlib.sha1(data).hexdigest():
45
- raise Exception("Read {0} bytes, but data did not match checksum".format(size))
46
-
47
- # restore escaped loose \r characters
48
- data = data.replace(br'\r', b'\r')
49
-
50
41
  return data
51
42
 
52
43
 
@@ -221,7 +212,7 @@ def main(args=None):
221
212
  """ Called to initiate the connect to the remote device
222
213
  """
223
214
 
224
- parser = opt_help.create_base_parser(prog='ansible-connection')
215
+ parser = opt_help.create_base_parser(prog=None)
225
216
  opt_help.add_verbosity_options(parser)
226
217
  parser.add_argument('playbook_pid')
227
218
  parser.add_argument('task_uuid')
ansible/config/base.yml CHANGED
@@ -1,6 +1,14 @@
1
1
  # Copyright (c) 2017 Ansible Project
2
2
  # GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
3
3
  ---
4
+ _ANSIBLE_CONNECTION_PATH:
5
+ env:
6
+ - name: _ANSIBLE_CONNECTION_PATH
7
+ name: Overrides the location of the Ansible persistent connection helper script.
8
+ description:
9
+ - For internal use only.
10
+ type: path
11
+ version_added: "2.18"
4
12
  ANSIBLE_HOME:
5
13
  name: The Ansible home path
6
14
  description:
@@ -25,6 +33,9 @@ ANSIBLE_CONNECTION_PATH:
25
33
  - {key: ansible_connection_path, section: persistent_connection}
26
34
  yaml: {key: persistent_connection.ansible_connection_path}
27
35
  version_added: "2.8"
36
+ deprecated:
37
+ why: This setting has no effect.
38
+ version: "2.22"
28
39
  ANSIBLE_COW_SELECTION:
29
40
  name: Cowsay filter selection
30
41
  default: default
@@ -293,6 +304,14 @@ COLOR_HIGHLIGHT:
293
304
  env: [{name: ANSIBLE_COLOR_HIGHLIGHT}]
294
305
  ini:
295
306
  - {key: highlight, section: colors}
307
+ COLOR_INCLUDED:
308
+ name: Color for 'included' task status
309
+ default: cyan
310
+ description: Defines the color to use when showing 'Included' task status.
311
+ env: [{name: ANSIBLE_COLOR_INCLUDED}]
312
+ ini:
313
+ - {key: included, section: colors}
314
+ version_added: '2.18'
296
315
  COLOR_OK:
297
316
  name: Color for 'ok' task status
298
317
  default: green
@@ -328,6 +347,54 @@ COLOR_WARN:
328
347
  env: [{name: ANSIBLE_COLOR_WARN}]
329
348
  ini:
330
349
  - {key: warn, section: colors}
350
+ COLOR_DOC_MODULE:
351
+ name: Color for module name in the ansible-doc output
352
+ default: yellow
353
+ description: Defines the color to use when emitting a module name in the ansible-doc output.
354
+ env: [{name: ANSIBLE_COLOR_DOC_MODULE}]
355
+ ini:
356
+ - {key: doc_module, section: colors}
357
+ version_added: '2.18'
358
+ COLOR_DOC_REFERENCE:
359
+ name: Color for cross-reference in the ansible-doc output
360
+ default: magenta
361
+ description: Defines the color to use when emitting cross-reference in the ansible-doc output.
362
+ env: [{name: ANSIBLE_COLOR_DOC_REFERENCE}]
363
+ ini:
364
+ - {key: doc_reference, section: colors}
365
+ version_added: '2.18'
366
+ COLOR_DOC_LINK:
367
+ name: Color for Link in ansible-doc output
368
+ default: cyan
369
+ description: Defines the color to use when emitting a link in the ansible-doc output.
370
+ env: [{name: ANSIBLE_COLOR_DOC_LINK}]
371
+ ini:
372
+ - {key: doc_link, section: colors}
373
+ version_added: '2.18'
374
+ COLOR_DOC_DEPRECATED:
375
+ name: Color for deprecated value in ansible-doc output
376
+ default: magenta
377
+ description: Defines the color to use when emitting a deprecated value in the ansible-doc output.
378
+ env: [{name: ANSIBLE_COLOR_DOC_DEPRECATED}]
379
+ ini:
380
+ - {key: doc_deprecated, section: colors}
381
+ version_added: '2.18'
382
+ COLOR_DOC_CONSTANT:
383
+ name: Color for constant in ansible-doc output
384
+ default: dark gray
385
+ description: Defines the color to use when emitting a constant in the ansible-doc output.
386
+ env: [{name: ANSIBLE_COLOR_DOC_CONSTANT}]
387
+ ini:
388
+ - {key: doc_constant, section: colors}
389
+ version_added: '2.18'
390
+ COLOR_DOC_PLUGIN:
391
+ name: Color for the plugin in ansible-doc output
392
+ default: yellow
393
+ description: Defines the color to use when emitting a plugin name in the ansible-doc output.
394
+ env: [{name: ANSIBLE_COLOR_DOC_PLUGIN}]
395
+ ini:
396
+ - {key: doc_plugin, section: colors}
397
+ version_added: '2.18'
331
398
  CONNECTION_PASSWORD_FILE:
332
399
  name: Connection password file
333
400
  default: ~
@@ -582,24 +649,6 @@ DEFAULT_EXECUTABLE:
582
649
  env: [{name: ANSIBLE_EXECUTABLE}]
583
650
  ini:
584
651
  - {key: executable, section: defaults}
585
- DEFAULT_FACT_PATH:
586
- name: local fact path
587
- description:
588
- - "This option allows you to globally configure a custom path for 'local_facts' for the implied :ref:`ansible_collections.ansible.builtin.setup_module` task when using fact gathering."
589
- - "If not set, it will fall back to the default from the ``ansible.builtin.setup`` module: ``/etc/ansible/facts.d``."
590
- - "This does **not** affect user defined tasks that use the ``ansible.builtin.setup`` module."
591
- - The real action being created by the implicit task is currently ``ansible.legacy.gather_facts`` module, which then calls the configured fact modules,
592
- by default this will be ``ansible.builtin.setup`` for POSIX systems but other platforms might have different defaults.
593
- env: [{name: ANSIBLE_FACT_PATH}]
594
- ini:
595
- - {key: fact_path, section: defaults}
596
- type: string
597
- deprecated:
598
- # TODO: when removing set playbook/play.py to default=None
599
- why: the module_defaults keyword is a more generic version and can apply to all calls to the
600
- M(ansible.builtin.gather_facts) or M(ansible.builtin.setup) actions
601
- version: "2.18"
602
- alternatives: module_defaults
603
652
  DEFAULT_FILTER_PLUGIN_PATH:
604
653
  name: Jinja2 Filter Plugins Path
605
654
  default: '{{ ANSIBLE_HOME ~ "/plugins/filter:/usr/share/ansible/plugins/filter" }}'
@@ -643,39 +692,6 @@ DEFAULT_GATHERING:
643
692
  implicit: "the cache plugin will be ignored and facts will be gathered per play unless 'gather_facts: False' is set."
644
693
  explicit: facts will not be gathered unless directly requested in the play.
645
694
  smart: each new host that has no facts discovered will be scanned, but if the same host is addressed in multiple plays it will not be contacted again in the run.
646
- DEFAULT_GATHER_SUBSET:
647
- name: Gather facts subset
648
- description:
649
- - Set the `gather_subset` option for the :ref:`ansible_collections.ansible.builtin.setup_module` task in the implicit fact gathering.
650
- See the module documentation for specifics.
651
- - "It does **not** apply to user defined ``ansible.builtin.setup`` tasks."
652
- env: [{name: ANSIBLE_GATHER_SUBSET}]
653
- ini:
654
- - key: gather_subset
655
- section: defaults
656
- version_added: "2.1"
657
- type: list
658
- deprecated:
659
- # TODO: when removing set playbook/play.py to default=None
660
- why: the module_defaults keyword is a more generic version and can apply to all calls to the
661
- M(ansible.builtin.gather_facts) or M(ansible.builtin.setup) actions
662
- version: "2.18"
663
- alternatives: module_defaults
664
- DEFAULT_GATHER_TIMEOUT:
665
- name: Gather facts timeout
666
- description:
667
- - Set the timeout in seconds for the implicit fact gathering, see the module documentation for specifics.
668
- - "It does **not** apply to user defined :ref:`ansible_collections.ansible.builtin.setup_module` tasks."
669
- env: [{name: ANSIBLE_GATHER_TIMEOUT}]
670
- ini:
671
- - {key: gather_timeout, section: defaults}
672
- type: integer
673
- deprecated:
674
- # TODO: when removing set playbook/play.py to default=None
675
- why: the module_defaults keyword is a more generic version and can apply to all calls to the
676
- M(ansible.builtin.gather_facts) or M(ansible.builtin.setup) actions
677
- version: "2.18"
678
- alternatives: module_defaults
679
695
  DEFAULT_HASH_BEHAVIOUR:
680
696
  name: Hash merge behaviour
681
697
  default: replace
@@ -810,7 +826,9 @@ DEFAULT_LOCAL_TMP:
810
826
  DEFAULT_LOG_PATH:
811
827
  name: Ansible log file path
812
828
  default: ~
813
- description: File to which Ansible will log on the controller. When empty logging is disabled.
829
+ description:
830
+ - File to which Ansible will log on the controller.
831
+ - When not set the logging is disabled.
814
832
  env: [{name: ANSIBLE_LOG_PATH}]
815
833
  ini:
816
834
  - {key: log_path, section: defaults}
@@ -1008,7 +1026,7 @@ DEFAULT_STDOUT_CALLBACK:
1008
1026
  EDITOR:
1009
1027
  name: editor application to use
1010
1028
  default: vi
1011
- descrioption:
1029
+ description:
1012
1030
  - for the cases in which Ansible needs to return a file within an editor, this chooses the application to use.
1013
1031
  ini:
1014
1032
  - section: defaults
@@ -1510,6 +1528,23 @@ GALAXY_REQUIRED_VALID_SIGNATURE_COUNT:
1510
1528
  - The number of signatures that must be successful during GPG signature verification while installing or verifying collections.
1511
1529
  - This should be a positive integer or all to indicate all signatures must successfully validate the collection.
1512
1530
  - Prepend + to the value to fail if no valid signatures are found for the collection.
1531
+ GALAXY_COLLECTION_IMPORT_POLL_INTERVAL:
1532
+ description:
1533
+ - The initial interval in seconds for polling the import status of a collection.
1534
+ - This interval increases exponentially based on the :ref:`galaxy_collection_import_poll_factor`, with a maximum delay of 30 seconds.
1535
+ type: float
1536
+ default: 2.0
1537
+ env:
1538
+ - name: ANSIBLE_GALAXY_COLLECTION_IMPORT_POLL_INTERVAL
1539
+ version_added: '2.18'
1540
+ GALAXY_COLLECTION_IMPORT_POLL_FACTOR:
1541
+ description:
1542
+ - The multiplier used to increase the :ref:`galaxy_collection_import_poll_interval` when checking the collection import status.
1543
+ type: float
1544
+ default: 1.5
1545
+ env:
1546
+ - name: ANSIBLE_GALAXY_COLLECTION_IMPORT_POLL_FACTOR
1547
+ version_added: "2.18"
1513
1548
  HOST_KEY_CHECKING:
1514
1549
  # NOTE: constant not in use by ssh/paramiko plugins anymore, but they do support the same configuration sources
1515
1550
  # TODO: check non ssh connection plugins for use/migration
@@ -1562,12 +1597,12 @@ _INTERPRETER_PYTHON_DISTRO_MAP:
1562
1597
  INTERPRETER_PYTHON_FALLBACK:
1563
1598
  name: Ordered list of Python interpreters to check for in discovery
1564
1599
  default:
1600
+ - python3.13
1565
1601
  - python3.12
1566
1602
  - python3.11
1567
1603
  - python3.10
1568
1604
  - python3.9
1569
1605
  - python3.8
1570
- - python3.7
1571
1606
  - /usr/bin/python3
1572
1607
  - python3
1573
1608
  vars:
@@ -1771,7 +1806,7 @@ OLD_PLUGIN_CACHE_CLEARING:
1771
1806
  PAGER:
1772
1807
  name: pager application to use
1773
1808
  default: less
1774
- descrioption:
1809
+ description:
1775
1810
  - for the cases in which Ansible needs to return output in a pageable fashion, this chooses the application to use.
1776
1811
  ini:
1777
1812
  - section: defaults
@@ -1973,7 +2008,11 @@ TASK_TIMEOUT:
1973
2008
  name: Task Timeout
1974
2009
  default: 0
1975
2010
  description:
1976
- - Set the maximum time (in seconds) that a task can run for.
2011
+ - Set the maximum time (in seconds) for a task action to execute in.
2012
+ - Timeout runs independently from templating or looping.
2013
+ It applies per each attempt of executing the task's action and remains unchanged by the total time spent on a task.
2014
+ - When the action execution exceeds the timeout, Ansible interrupts the process.
2015
+ This is registered as a failure due to outside circumstances, not a task failure, to receive appropriate response and recovery process.
1977
2016
  - If set to 0 (the default) there is no timeout.
1978
2017
  env: [{name: ANSIBLE_TASK_TIMEOUT}]
1979
2018
  ini:
@@ -2104,4 +2143,35 @@ VERBOSE_TO_STDERR:
2104
2143
  - section: defaults
2105
2144
  key: verbose_to_stderr
2106
2145
  type: bool
2107
- ...
2146
+ _Z_TEST_ENTRY:
2147
+ name: testentry
2148
+ description: for tests
2149
+ env:
2150
+ - name: ANSIBLE_TEST_ENTRY
2151
+ - name: ANSIBLE_TEST_ENTRY_D
2152
+ deprecated:
2153
+ why: for testing
2154
+ version: '3.30'
2155
+ alternatives: nothing
2156
+ ini:
2157
+ - section: testing
2158
+ key: valid
2159
+ - section: testing
2160
+ key: deprecated
2161
+ deprecated:
2162
+ why: for testing
2163
+ version: '3.30'
2164
+ alternatives: nothing
2165
+ _Z_TEST_ENTRY_2:
2166
+ version_added: '2.18'
2167
+ name: testentry
2168
+ description: for tests
2169
+ deprecated:
2170
+ why: for testing
2171
+ version: '3.30'
2172
+ alternatives: nothing
2173
+ env:
2174
+ - name: ANSIBLE_TEST_ENTRY2
2175
+ ini:
2176
+ - section: testing
2177
+ key: valid2
ansible/config/manager.py CHANGED
@@ -4,6 +4,7 @@
4
4
  from __future__ import annotations
5
5
 
6
6
  import atexit
7
+ import decimal
7
8
  import configparser
8
9
  import os
9
10
  import os.path
@@ -15,7 +16,7 @@ from collections import namedtuple
15
16
  from collections.abc import Mapping, Sequence
16
17
  from jinja2.nativetypes import NativeEnvironment
17
18
 
18
- from ansible.errors import AnsibleOptionsError, AnsibleError
19
+ from ansible.errors import AnsibleOptionsError, AnsibleError, AnsibleRequiredOptionError
19
20
  from ansible.module_utils.common.text.converters import to_text, to_bytes, to_native
20
21
  from ansible.module_utils.common.yaml import yaml_load
21
22
  from ansible.module_utils.six import string_types
@@ -29,6 +30,26 @@ Setting = namedtuple('Setting', 'name value origin type')
29
30
 
30
31
  INTERNAL_DEFS = {'lookup': ('_terms',)}
31
32
 
33
+ GALAXY_SERVER_DEF = [
34
+ ('url', True, 'str'),
35
+ ('username', False, 'str'),
36
+ ('password', False, 'str'),
37
+ ('token', False, 'str'),
38
+ ('auth_url', False, 'str'),
39
+ ('api_version', False, 'int'),
40
+ ('validate_certs', False, 'bool'),
41
+ ('client_id', False, 'str'),
42
+ ('timeout', False, 'int'),
43
+ ]
44
+
45
+ # config definition fields
46
+ GALAXY_SERVER_ADDITIONAL = {
47
+ 'api_version': {'default': None, 'choices': [2, 3]},
48
+ 'validate_certs': {'cli': [{'name': 'validate_certs'}]},
49
+ 'timeout': {'cli': [{'name': 'timeout'}]},
50
+ 'token': {'default': None},
51
+ }
52
+
32
53
 
33
54
  def _get_entry(plugin_type, plugin_name, config):
34
55
  ''' construct entry for requested config '''
@@ -81,10 +102,18 @@ def ensure_type(value, value_type, origin=None, origin_ftype=None):
81
102
  value = boolean(value, strict=False)
82
103
 
83
104
  elif value_type in ('integer', 'int'):
84
- value = int(value)
105
+ if not isinstance(value, int):
106
+ try:
107
+ if (decimal_value := decimal.Decimal(value)) == (int_part := int(decimal_value)):
108
+ value = int_part
109
+ else:
110
+ errmsg = 'int'
111
+ except decimal.DecimalException as e:
112
+ raise ValueError from e
85
113
 
86
114
  elif value_type == 'float':
87
- value = float(value)
115
+ if not isinstance(value, float):
116
+ value = float(value)
88
117
 
89
118
  elif value_type == 'list':
90
119
  if isinstance(value, string_types):
@@ -153,7 +182,7 @@ def ensure_type(value, value_type, origin=None, origin_ftype=None):
153
182
  value = unquote(value)
154
183
 
155
184
  if errmsg:
156
- raise ValueError('Invalid type provided for "%s": %s' % (errmsg, to_native(value)))
185
+ raise ValueError(f'Invalid type provided for "{errmsg}": {value!r}')
157
186
 
158
187
  return to_text(value, errors='surrogate_or_strict', nonstring='passthru')
159
188
 
@@ -302,6 +331,42 @@ class ConfigManager(object):
302
331
  # ensure we always have config def entry
303
332
  self._base_defs['CONFIG_FILE'] = {'default': None, 'type': 'path'}
304
333
 
334
+ def load_galaxy_server_defs(self, server_list):
335
+
336
+ def server_config_def(section, key, required, option_type):
337
+ config_def = {
338
+ 'description': 'The %s of the %s Galaxy server' % (key, section),
339
+ 'ini': [
340
+ {
341
+ 'section': 'galaxy_server.%s' % section,
342
+ 'key': key,
343
+ }
344
+ ],
345
+ 'env': [
346
+ {'name': 'ANSIBLE_GALAXY_SERVER_%s_%s' % (section.upper(), key.upper())},
347
+ ],
348
+ 'required': required,
349
+ 'type': option_type,
350
+ }
351
+ if key in GALAXY_SERVER_ADDITIONAL:
352
+ config_def.update(GALAXY_SERVER_ADDITIONAL[key])
353
+ # ensure we always have a default timeout
354
+ if key == 'timeout' and 'default' not in config_def:
355
+ config_def['default'] = self.get_config_value('GALAXY_SERVER_TIMEOUT')
356
+
357
+ return config_def
358
+
359
+ if server_list:
360
+ for server_key in server_list:
361
+ if not server_key:
362
+ # To filter out empty strings or non truthy values as an empty server list env var is equal to [''].
363
+ continue
364
+
365
+ # Config definitions are looked up dynamically based on the C.GALAXY_SERVER_LIST entry. We look up the
366
+ # section [galaxy_server.<server>] for the values url, username, password, and token.
367
+ defs = dict((k, server_config_def(server_key, k, req, value_type)) for k, req, value_type in GALAXY_SERVER_DEF)
368
+ self.initialize_plugin_configuration_definitions('galaxy_server', server_key, defs)
369
+
305
370
  def template_default(self, value, variables):
306
371
  if isinstance(value, string_types) and (value.startswith('{{') and value.endswith('}}')) and variables is not None:
307
372
  # template default values if possible
@@ -357,7 +422,7 @@ class ConfigManager(object):
357
422
  def get_plugin_options(self, plugin_type, name, keys=None, variables=None, direct=None):
358
423
 
359
424
  options = {}
360
- defs = self.get_configuration_definitions(plugin_type, name)
425
+ defs = self.get_configuration_definitions(plugin_type=plugin_type, name=name)
361
426
  for option in defs:
362
427
  options[option] = self.get_config_value(option, plugin_type=plugin_type, plugin_name=name, keys=keys, variables=variables, direct=direct)
363
428
 
@@ -366,7 +431,7 @@ class ConfigManager(object):
366
431
  def get_plugin_vars(self, plugin_type, name):
367
432
 
368
433
  pvars = []
369
- for pdef in self.get_configuration_definitions(plugin_type, name).values():
434
+ for pdef in self.get_configuration_definitions(plugin_type=plugin_type, name=name).values():
370
435
  if 'vars' in pdef and pdef['vars']:
371
436
  for var_entry in pdef['vars']:
372
437
  pvars.append(var_entry['name'])
@@ -375,7 +440,7 @@ class ConfigManager(object):
375
440
  def get_plugin_options_from_var(self, plugin_type, name, variable):
376
441
 
377
442
  options = []
378
- for option_name, pdef in self.get_configuration_definitions(plugin_type, name).items():
443
+ for option_name, pdef in self.get_configuration_definitions(plugin_type=plugin_type, name=name).items():
379
444
  if 'vars' in pdef and pdef['vars']:
380
445
  for var_entry in pdef['vars']:
381
446
  if variable == var_entry['name']:
@@ -417,7 +482,6 @@ class ConfigManager(object):
417
482
  for cdef in list(ret.keys()):
418
483
  if cdef.startswith('_'):
419
484
  del ret[cdef]
420
-
421
485
  return ret
422
486
 
423
487
  def _loop_entries(self, container, entry_list):
@@ -472,7 +536,7 @@ class ConfigManager(object):
472
536
  origin = None
473
537
  origin_ftype = None
474
538
 
475
- defs = self.get_configuration_definitions(plugin_type, plugin_name)
539
+ defs = self.get_configuration_definitions(plugin_type=plugin_type, name=plugin_name)
476
540
  if config in defs:
477
541
 
478
542
  aliases = defs[config].get('aliases', [])
@@ -562,8 +626,8 @@ class ConfigManager(object):
562
626
  if value is None:
563
627
  if defs[config].get('required', False):
564
628
  if not plugin_type or config not in INTERNAL_DEFS.get(plugin_type, {}):
565
- raise AnsibleError("No setting was provided for required configuration %s" %
566
- to_native(_get_entry(plugin_type, plugin_name, config)))
629
+ raise AnsibleRequiredOptionError("No setting was provided for required configuration %s" %
630
+ to_native(_get_entry(plugin_type, plugin_name, config)))
567
631
  else:
568
632
  origin = 'default'
569
633
  value = self.template_default(defs[config].get('default'), variables)
@@ -617,3 +681,17 @@ class ConfigManager(object):
617
681
  self._plugins[plugin_type] = {}
618
682
 
619
683
  self._plugins[plugin_type][name] = defs
684
+
685
+ @staticmethod
686
+ def get_deprecated_msg_from_config(dep_docs, include_removal=False):
687
+
688
+ removal = ''
689
+ if include_removal:
690
+ if 'removed_at_date' in dep_docs:
691
+ removal = f"Will be removed in a release after {dep_docs['removed_at_date']}\n\t"
692
+ else:
693
+ removal = f"Will be removed in: Ansible {dep_docs['removed_in']}\n\t"
694
+
695
+ # TODO: choose to deprecate either singular or plural
696
+ alt = dep_docs.get('alternatives', dep_docs.get('alternative', 'none'))
697
+ return f"Reason: {dep_docs['why']}\n\t{removal}Alternatives: {alt}"
ansible/constants.py CHANGED
@@ -15,6 +15,10 @@ from ansible.module_utils.parsing.convert_bool import BOOLEANS_TRUE
15
15
  from ansible.release import __version__
16
16
  from ansible.utils.fqcn import add_internal_fqcns
17
17
 
18
+ # initialize config manager/config data to read/store global settings
19
+ # and generate 'pseudo constants' for app consumption.
20
+ config = ConfigManager()
21
+
18
22
 
19
23
  def _warning(msg):
20
24
  ''' display is not guaranteed here, nor it being the full class, but try anyways, fallback to sys.stderr.write '''
@@ -36,6 +40,28 @@ def _deprecated(msg, version):
36
40
  sys.stderr.write(' [DEPRECATED] %s, to be removed in %s\n' % (msg, version))
37
41
 
38
42
 
43
+ def handle_config_noise(display=None):
44
+
45
+ if display is not None:
46
+ w = display.warning
47
+ d = display.deprecated
48
+ else:
49
+ w = _warning
50
+ d = _deprecated
51
+
52
+ while config.WARNINGS:
53
+ warn = config.WARNINGS.pop()
54
+ w(warn)
55
+
56
+ while config.DEPRECATED:
57
+ # tuple with name and options
58
+ dep = config.DEPRECATED.pop(0)
59
+ msg = config.get_deprecated_msg_from_config(dep[1])
60
+ # use tabs only for ansible-doc?
61
+ msg = msg.replace("\t", "")
62
+ d(f"{dep[0]} option. {msg}", version=dep[1]['version'])
63
+
64
+
39
65
  def set_constant(name, value, export=vars()):
40
66
  ''' sets constants and returns resolved options dict '''
41
67
  export[name] = value
@@ -152,10 +178,10 @@ INTERNAL_STATIC_VARS = frozenset(
152
178
  ]
153
179
  )
154
180
  LOCALHOST = ('127.0.0.1', 'localhost', '::1')
155
- MODULE_REQUIRE_ARGS = tuple(add_internal_fqcns(('command', 'win_command', 'ansible.windows.win_command', 'shell', 'win_shell',
156
- 'ansible.windows.win_shell', 'raw', 'script')))
157
- MODULE_NO_JSON = tuple(add_internal_fqcns(('command', 'win_command', 'ansible.windows.win_command', 'shell', 'win_shell',
158
- 'ansible.windows.win_shell', 'raw')))
181
+ WIN_MOVED = ['ansible.windows.win_command', 'ansible.windows.win_shell']
182
+ MODULE_REQUIRE_ARGS_SIMPLE = ['command', 'raw', 'script', 'shell', 'win_command', 'win_shell']
183
+ MODULE_REQUIRE_ARGS = tuple(add_internal_fqcns(MODULE_REQUIRE_ARGS_SIMPLE) + WIN_MOVED)
184
+ MODULE_NO_JSON = tuple(add_internal_fqcns(('command', 'win_command', 'shell', 'win_shell', 'raw')) + WIN_MOVED)
159
185
  RESTRICTED_RESULT_KEYS = ('ansible_rsync_path', 'ansible_playbook_python', 'ansible_facts')
160
186
  SYNTHETIC_COLLECTIONS = ('ansible.builtin', 'ansible.legacy')
161
187
  TREE_DIR = None
@@ -218,11 +244,8 @@ MAGIC_VARIABLE_MAPPING = dict(
218
244
  )
219
245
 
220
246
  # POPULATE SETTINGS FROM CONFIG ###
221
- config = ConfigManager()
222
-
223
- # Generate constants from config
224
247
  for setting in config.get_configuration_definitions():
225
248
  set_constant(setting, config.get_config_value(setting, variables=vars()))
226
249
 
227
- for warn in config.WARNINGS:
228
- _warning(warn)
250
+ # emit any warnings or deprecations
251
+ handle_config_noise()
@@ -231,6 +231,11 @@ class AnsibleOptionsError(AnsibleError):
231
231
  pass
232
232
 
233
233
 
234
+ class AnsibleRequiredOptionError(AnsibleOptionsError):
235
+ ''' bad or incomplete options passed '''
236
+ pass
237
+
238
+
234
239
  class AnsibleParserError(AnsibleError):
235
240
  ''' something was detected early that is wrong about a playbook or data file '''
236
241
  pass
@@ -41,7 +41,7 @@ class InterpreterDiscoveryRequiredError(Exception):
41
41
  def discover_interpreter(action, interpreter_name, discovery_mode, task_vars):
42
42
  # interpreter discovery is a 2-step process with the target. First, we use a simple shell-agnostic bootstrap to
43
43
  # get the system type from uname, and find any random Python that can get us the info we need. For supported
44
- # target OS types, we'll dispatch a Python script that calls plaform.dist() (for older platforms, where available)
44
+ # target OS types, we'll dispatch a Python script that calls platform.dist() (for older platforms, where available)
45
45
  # and brings back /etc/os-release (if present). The proper Python path is looked up in a table of known
46
46
  # distros/versions with included Pythons; if nothing is found, depending on the discovery mode, either the
47
47
  # default fallback of /usr/bin/python is used (if we know it's there), or discovery fails.
@@ -653,3 +653,19 @@ class PlayIterator:
653
653
 
654
654
  def clear_notification(self, hostname: str, notification: str) -> None:
655
655
  self._host_states[hostname].handler_notifications.remove(notification)
656
+
657
+ def end_host(self, hostname: str) -> None:
658
+ """Used by ``end_host``, ``end_batch`` and ``end_play`` meta tasks to end executing given host."""
659
+ state = self.get_active_state(self.get_state_for_host(hostname))
660
+ if state.run_state == IteratingStates.RESCUE:
661
+ # This is a special case for when ending a host occurs in rescue.
662
+ # By definition the meta task responsible for ending the host
663
+ # is the last task, so we need to clear the fail state to mark
664
+ # the host as rescued.
665
+ # The reason we need to do that is because this operation is
666
+ # normally done when PlayIterator transitions from rescue to
667
+ # always when only then we can say that rescue didn't fail
668
+ # but with ending a host via meta task, we don't get to that transition.
669
+ self.set_fail_state_for_host(hostname, FailedStates.NONE)
670
+ self.set_run_state_for_host(hostname, IteratingStates.COMPLETE)
671
+ self._play._removed_hosts.append(hostname)
@@ -195,10 +195,7 @@ class PlaybookExecutor:
195
195
  result = self._tqm.RUN_FAILED_HOSTS
196
196
  break_play = True
197
197
 
198
- # check the number of failures here, to see if they're above the maximum
199
- # failure percentage allowed, or if any errors are fatal. If either of those
200
- # conditions are met, we break out, otherwise we only break out if the entire
201
- # batch failed
198
+ # check the number of failures here and break out if the entire batch failed
202
199
  failed_hosts_count = len(self._tqm._failed_hosts) + len(self._tqm._unreachable_hosts) - \
203
200
  (previously_failed + previously_unreachable)
204
201
 
@@ -116,12 +116,11 @@ Write-AnsibleLog "INFO - parsed become input, user: '$username', type: '$logon_t
116
116
  # set to Stop and cannot be changed. Also need to split the payload from the wrapper to prevent potentially
117
117
  # sensitive content from being logged by the scriptblock logger.
118
118
  $bootstrap_wrapper = {
119
- &chcp.com 65001 > $null
120
- $exec_wrapper_str = [System.Console]::In.ReadToEnd()
121
- $split_parts = $exec_wrapper_str.Split(@("`0`0`0`0"), 2, [StringSplitOptions]::RemoveEmptyEntries)
119
+ [Console]::InputEncoding = [Console]::OutputEncoding = New-Object System.Text.UTF8Encoding
120
+ $ew = [System.Console]::In.ReadToEnd()
121
+ $split_parts = $ew.Split(@("`0`0`0`0"), 2, [StringSplitOptions]::RemoveEmptyEntries)
122
122
  Set-Variable -Name json_raw -Value $split_parts[1]
123
- $exec_wrapper = [ScriptBlock]::Create($split_parts[0])
124
- &$exec_wrapper
123
+ &([ScriptBlock]::Create($split_parts[0]))
125
124
  }
126
125
  $exec_command = [System.Convert]::ToBase64String([System.Text.Encoding]::Unicode.GetBytes($bootstrap_wrapper.ToString()))
127
126
  $lp_command_line = "powershell.exe -NonInteractive -NoProfile -ExecutionPolicy Bypass -EncodedCommand $exec_command"
@@ -1,4 +1,4 @@
1
- &chcp.com 65001 > $null
1
+ try { [Console]::InputEncoding = [Console]::OutputEncoding = New-Object System.Text.UTF8Encoding } catch { $null = $_ }
2
2
 
3
3
  if ($PSVersionTable.PSVersion -lt [Version]"3.0") {
4
4
  '{"failed":true,"msg":"Ansible requires PowerShell v3.0 or newer"}'
@@ -9,5 +9,4 @@ $exec_wrapper_str = $input | Out-String
9
9
  $split_parts = $exec_wrapper_str.Split(@("`0`0`0`0"), 2, [StringSplitOptions]::RemoveEmptyEntries)
10
10
  If (-not $split_parts.Length -eq 2) { throw "invalid payload" }
11
11
  Set-Variable -Name json_raw -Value $split_parts[1]
12
- $exec_wrapper = [ScriptBlock]::Create($split_parts[0])
13
- &$exec_wrapper
12
+ & ([ScriptBlock]::Create($split_parts[0]))
@@ -16,7 +16,7 @@ begin {
16
16
  .SYNOPSIS
17
17
  Converts a JSON string to a Hashtable/Array in the fastest way
18
18
  possible. Unfortunately ConvertFrom-Json is still faster but outputs
19
- a PSCustomObject which is combersone for module consumption.
19
+ a PSCustomObject which is cumbersome for module consumption.
20
20
 
21
21
  .PARAMETER InputObject
22
22
  [String] The JSON string to deserialize.