ansible-core 2.17.4__py3-none-any.whl → 2.18.0b1__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 (320) 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 +30 -53
  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 +14 -11
  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 +48 -31
  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/playbook/task.py +1 -1
  192. ansible/plugins/__init__.py +2 -0
  193. ansible/plugins/action/__init__.py +7 -9
  194. ansible/plugins/action/reboot.py +2 -2
  195. ansible/plugins/become/__init__.py +1 -1
  196. ansible/plugins/callback/__init__.py +44 -3
  197. ansible/plugins/callback/default.py +1 -1
  198. ansible/plugins/cliconf/__init__.py +1 -1
  199. ansible/plugins/connection/paramiko_ssh.py +2 -80
  200. ansible/plugins/connection/psrp.py +33 -82
  201. ansible/plugins/connection/ssh.py +0 -8
  202. ansible/plugins/connection/winrm.py +46 -1
  203. ansible/plugins/doc_fragments/connection_pipelining.py +2 -2
  204. ansible/plugins/doc_fragments/constructed.py +10 -10
  205. ansible/plugins/doc_fragments/default_callback.py +8 -8
  206. ansible/plugins/doc_fragments/files.py +5 -5
  207. ansible/plugins/doc_fragments/inventory_cache.py +2 -2
  208. ansible/plugins/doc_fragments/result_format_callback.py +6 -6
  209. ansible/plugins/doc_fragments/return_common.py +1 -1
  210. ansible/plugins/doc_fragments/shell_common.py +2 -10
  211. ansible/plugins/doc_fragments/shell_windows.py +0 -9
  212. ansible/plugins/doc_fragments/url.py +2 -2
  213. ansible/plugins/doc_fragments/url_windows.py +4 -5
  214. ansible/plugins/doc_fragments/validate.py +1 -1
  215. ansible/plugins/filter/core.py +2 -0
  216. ansible/plugins/filter/human_to_bytes.yml +9 -0
  217. ansible/plugins/filter/password_hash.yml +1 -1
  218. ansible/plugins/filter/strftime.yml +1 -1
  219. ansible/plugins/filter/to_nice_json.yml +7 -3
  220. ansible/plugins/filter/to_uuid.yml +1 -1
  221. ansible/plugins/inventory/script.py +1 -1
  222. ansible/plugins/list.py +1 -1
  223. ansible/plugins/loader.py +0 -11
  224. ansible/plugins/lookup/config.py +1 -1
  225. ansible/plugins/lookup/csvfile.py +21 -9
  226. ansible/plugins/lookup/env.py +8 -9
  227. ansible/plugins/lookup/ini.py +10 -1
  228. ansible/plugins/lookup/random_choice.py +2 -2
  229. ansible/plugins/lookup/url.py +7 -2
  230. ansible/plugins/shell/__init__.py +15 -20
  231. ansible/plugins/shell/powershell.py +9 -6
  232. ansible/plugins/strategy/__init__.py +16 -7
  233. ansible/plugins/test/core.py +23 -1
  234. ansible/plugins/test/issubset.yml +1 -1
  235. ansible/plugins/test/subset.yml +1 -1
  236. ansible/plugins/test/timedout.yml +20 -0
  237. ansible/plugins/test/vault_encrypted.yml +6 -6
  238. ansible/plugins/test/vaulted_file.yml +19 -0
  239. ansible/release.py +2 -2
  240. ansible/template/__init__.py +3 -8
  241. ansible/utils/collection_loader/_collection_finder.py +23 -55
  242. ansible/utils/display.py +44 -31
  243. ansible/utils/jsonrpc.py +1 -1
  244. ansible/utils/listify.py +1 -5
  245. ansible/utils/path.py +3 -0
  246. ansible/utils/vars.py +18 -27
  247. ansible/vars/manager.py +7 -150
  248. ansible/vars/plugins.py +1 -1
  249. ansible_core-2.18.0b1.dist-info/Apache-License.txt +202 -0
  250. {ansible_core-2.17.4.dist-info → ansible_core-2.18.0b1.dist-info}/METADATA +36 -23
  251. ansible_core-2.18.0b1.dist-info/MIT-license.txt +14 -0
  252. ansible_core-2.18.0b1.dist-info/PSF-license.txt +48 -0
  253. {ansible_core-2.17.4.dist-info → ansible_core-2.18.0b1.dist-info}/RECORD +311 -306
  254. {ansible_core-2.17.4.dist-info → ansible_core-2.18.0b1.dist-info}/WHEEL +1 -1
  255. {ansible_core-2.17.4.dist-info → ansible_core-2.18.0b1.dist-info}/entry_points.txt +1 -1
  256. ansible_core-2.18.0b1.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 +5 -7
  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/host_configs.py +10 -0
  288. ansible_test/_internal/host_profiles.py +9 -13
  289. ansible_test/_internal/pypi_proxy.py +1 -1
  290. ansible_test/_internal/python_requirements.py +5 -14
  291. ansible_test/_internal/timeout.py +1 -1
  292. ansible_test/_internal/util.py +40 -0
  293. ansible_test/_internal/util_common.py +5 -1
  294. ansible_test/_util/controller/sanity/code-smell/action-plugin-docs.json +3 -1
  295. ansible_test/_util/controller/sanity/code-smell/action-plugin-docs.py +6 -3
  296. ansible_test/_util/controller/sanity/code-smell/empty-init.json +0 -2
  297. ansible_test/_util/controller/sanity/pylint/config/collection.cfg +1 -0
  298. ansible_test/_util/controller/sanity/pylint/config/default.cfg +1 -0
  299. ansible_test/_util/controller/sanity/pylint/plugins/deprecated.py +1 -19
  300. ansible_test/_util/controller/sanity/shellcheck/exclude.txt +1 -0
  301. ansible_test/_util/controller/sanity/validate-modules/validate_modules/main.py +67 -2
  302. ansible_test/_util/controller/sanity/validate-modules/validate_modules/schema.py +27 -5
  303. ansible_test/_util/target/cli/ansible_test_cli_stub.py +0 -0
  304. ansible_test/_util/target/common/constants.py +2 -2
  305. ansible_test/_util/target/injector/python.py +5 -0
  306. ansible_test/_util/target/pytest/plugins/ansible_pytest_coverage.py +6 -0
  307. ansible_test/_util/target/sanity/import/importer.py +1 -1
  308. ansible_test/_util/target/setup/bootstrap.sh +6 -17
  309. ansible_test/_util/target/setup/requirements.py +14 -20
  310. ansible_test/config/config.yml +1 -1
  311. ansible_core-2.17.4.data/scripts/ansible-test +0 -44
  312. ansible_test/_data/requirements/sanity.mypy.in +0 -10
  313. ansible_test/_data/requirements/sanity.mypy.txt +0 -18
  314. ansible_test/_internal/commands/sanity/mypy.py +0 -274
  315. ansible_test/_util/controller/sanity/mypy/ansible-core.ini +0 -116
  316. ansible_test/_util/controller/sanity/mypy/ansible-test.ini +0 -27
  317. ansible_test/_util/controller/sanity/mypy/modules.ini +0 -92
  318. ansible_test/_util/controller/sanity/mypy/packaging.ini +0 -20
  319. {ansible_core-2.17.4.dist-info → ansible_core-2.18.0b1.dist-info}/COPYING +0 -0
  320. {ansible_core-2.17.4.dist-info → ansible_core-2.18.0b1.dist-info}/top_level.txt +0 -0
ansible/cli/galaxy.py CHANGED
@@ -55,7 +55,6 @@ from ansible.module_utils.common.yaml import yaml_dump, yaml_load
55
55
  from ansible.module_utils.common.text.converters import to_bytes, to_native, to_text
56
56
  from ansible.module_utils import six
57
57
  from ansible.parsing.dataloader import DataLoader
58
- from ansible.parsing.yaml.loader import AnsibleLoader
59
58
  from ansible.playbook.role.requirement import RoleRequirement
60
59
  from ansible.template import Templar
61
60
  from ansible.utils.collection_loader import AnsibleCollectionConfig
@@ -66,27 +65,6 @@ from ansible.utils.vars import load_extra_vars
66
65
  display = Display()
67
66
  urlparse = six.moves.urllib.parse.urlparse
68
67
 
69
- # config definition by position: name, required, type
70
- SERVER_DEF = [
71
- ('url', True, 'str'),
72
- ('username', False, 'str'),
73
- ('password', False, 'str'),
74
- ('token', False, 'str'),
75
- ('auth_url', False, 'str'),
76
- ('api_version', False, 'int'),
77
- ('validate_certs', False, 'bool'),
78
- ('client_id', False, 'str'),
79
- ('timeout', False, 'int'),
80
- ]
81
-
82
- # config definition fields
83
- SERVER_ADDITIONAL = {
84
- 'api_version': {'default': None, 'choices': [2, 3]},
85
- 'validate_certs': {'cli': [{'name': 'validate_certs'}]},
86
- 'timeout': {'default': C.GALAXY_SERVER_TIMEOUT, 'cli': [{'name': 'timeout'}]},
87
- 'token': {'default': None},
88
- }
89
-
90
68
 
91
69
  def with_collection_artifacts_manager(wrapped_method):
92
70
  """Inject an artifacts manager if not passed explicitly.
@@ -490,12 +468,31 @@ class GalaxyCLI(CLI):
490
468
  ignore_errors_help = 'Ignore errors during installation and continue with the next specified ' \
491
469
  'collection. This will not ignore dependency conflict errors.'
492
470
  else:
493
- args_kwargs['help'] = 'Role name, URL or tar file'
471
+ args_kwargs['help'] = 'Role name, URL or tar file. This is mutually exclusive with -r.'
494
472
  ignore_errors_help = 'Ignore errors and continue with the next specified role.'
495
473
 
474
+ if self._implicit_role:
475
+ # might install both roles and collections
476
+ description_text = (
477
+ 'Install roles and collections from file(s), URL(s) or Ansible '
478
+ 'Galaxy to the first entry in the config COLLECTIONS_PATH for collections '
479
+ 'and first entry in the config ROLES_PATH for roles. '
480
+ 'The first entry in the config ROLES_PATH can be overridden by --roles-path '
481
+ 'or -p, but this will result in only roles being installed.'
482
+ )
483
+ prog = 'ansible-galaxy install'
484
+ else:
485
+ prog = f"ansible-galaxy {galaxy_type} install"
486
+ description_text = (
487
+ 'Install {0}(s) from file(s), URL(s) or Ansible '
488
+ 'Galaxy to the first entry in the config {1}S_PATH '
489
+ 'unless overridden by --{0}s-path.'.format(galaxy_type, galaxy_type.upper())
490
+ )
496
491
  install_parser = parser.add_parser('install', parents=parents,
497
492
  help='Install {0}(s) from file(s), URL(s) or Ansible '
498
- 'Galaxy'.format(galaxy_type))
493
+ 'Galaxy'.format(galaxy_type),
494
+ description=description_text,
495
+ prog=prog,)
499
496
  install_parser.set_defaults(func=self.execute_install)
500
497
 
501
498
  install_parser.add_argument('args', metavar='{0}_name'.format(galaxy_type), nargs='*', **args_kwargs)
@@ -548,8 +545,12 @@ class GalaxyCLI(CLI):
548
545
  'This does not apply to collections in remote Git repositories or URLs to remote tarballs.'
549
546
  )
550
547
  else:
551
- install_parser.add_argument('-r', '--role-file', dest='requirements',
552
- help='A file containing a list of roles to be installed.')
548
+ if self._implicit_role:
549
+ install_parser.add_argument('-r', '--role-file', dest='requirements',
550
+ help='A file containing a list of collections and roles to be installed.')
551
+ else:
552
+ install_parser.add_argument('-r', '--role-file', dest='requirements',
553
+ help='A file containing a list of roles to be installed.')
553
554
 
554
555
  r_re = re.compile(r'^(?<!-)-[a-zA-Z]*r[a-zA-Z]*') # -r, -fr
555
556
  contains_r = bool([a for a in self._raw_args if r_re.match(a)])
@@ -618,25 +619,8 @@ class GalaxyCLI(CLI):
618
619
 
619
620
  self.galaxy = Galaxy()
620
621
 
621
- def server_config_def(section, key, required, option_type):
622
- config_def = {
623
- 'description': 'The %s of the %s Galaxy server' % (key, section),
624
- 'ini': [
625
- {
626
- 'section': 'galaxy_server.%s' % section,
627
- 'key': key,
628
- }
629
- ],
630
- 'env': [
631
- {'name': 'ANSIBLE_GALAXY_SERVER_%s_%s' % (section.upper(), key.upper())},
632
- ],
633
- 'required': required,
634
- 'type': option_type,
635
- }
636
- if key in SERVER_ADDITIONAL:
637
- config_def.update(SERVER_ADDITIONAL[key])
638
-
639
- return config_def
622
+ # dynamically add per server config depending on declared servers
623
+ C.config.load_galaxy_server_defs(C.GALAXY_SERVER_LIST)
640
624
 
641
625
  galaxy_options = {}
642
626
  for optional_key in ['clear_response_cache', 'no_cache']:
@@ -644,19 +628,12 @@ class GalaxyCLI(CLI):
644
628
  galaxy_options[optional_key] = context.CLIARGS[optional_key]
645
629
 
646
630
  config_servers = []
647
-
648
631
  # Need to filter out empty strings or non truthy values as an empty server list env var is equal to [''].
649
632
  server_list = [s for s in C.GALAXY_SERVER_LIST or [] if s]
650
633
  for server_priority, server_key in enumerate(server_list, start=1):
651
- # Abuse the 'plugin config' by making 'galaxy_server' a type of plugin
652
- # Config definitions are looked up dynamically based on the C.GALAXY_SERVER_LIST entry. We look up the
653
- # section [galaxy_server.<server>] for the values url, username, password, and token.
654
- config_dict = dict((k, server_config_def(server_key, k, req, ensure_type)) for k, req, ensure_type in SERVER_DEF)
655
- defs = AnsibleLoader(yaml_dump(config_dict)).get_single_data()
656
- C.config.initialize_plugin_configuration_definitions('galaxy_server', server_key, defs)
657
634
 
658
635
  # resolve the config created options above with existing config and user options
659
- server_options = C.config.get_plugin_options('galaxy_server', server_key)
636
+ server_options = C.config.get_plugin_options(plugin_type='galaxy_server', name=server_key)
660
637
 
661
638
  # auth_url is used to create the token, but not directly by GalaxyAPI, so
662
639
  # it doesn't need to be passed as kwarg to GalaxyApi, same for others we pop here
ansible/cli/inventory.py CHANGED
@@ -73,12 +73,12 @@ class InventoryCLI(CLI):
73
73
 
74
74
  # list
75
75
  self.parser.add_argument("--export", action="store_true", default=C.INVENTORY_EXPORT, dest='export',
76
- help="When doing an --list, represent in a way that is optimized for export,"
76
+ help="When doing --list, represent in a way that is optimized for export,"
77
77
  "not as an accurate representation of how Ansible has processed it")
78
78
  self.parser.add_argument('--output', default=None, dest='output_file',
79
79
  help="When doing --list, send the inventory to a file instead of to the screen")
80
80
  # self.parser.add_argument("--ignore-vars-plugins", action="store_true", default=False, dest='ignore_vars_plugins',
81
- # help="When doing an --list, skip vars data from vars plugins, by default, this would include group_vars/ and host_vars/")
81
+ # help="When doing --list, skip vars data from vars plugins, by default, this would include group_vars/ and host_vars/")
82
82
 
83
83
  def post_process_args(self, options):
84
84
  options = super(InventoryCLI, self).post_process_args(options)
ansible/cli/pull.py CHANGED
@@ -12,7 +12,7 @@ from ansible.cli import CLI
12
12
  import datetime
13
13
  import os
14
14
  import platform
15
- import random
15
+ import secrets
16
16
  import shlex
17
17
  import shutil
18
18
  import socket
@@ -140,7 +140,7 @@ class PullCLI(CLI):
140
140
 
141
141
  if options.sleep:
142
142
  try:
143
- secs = random.randint(0, int(options.sleep))
143
+ secs = secrets.randbelow(int(options.sleep))
144
144
  options.sleep = secs
145
145
  except ValueError:
146
146
  raise AnsibleOptionsError("%s is not a number." % options.sleep)
@@ -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}"