ansible-core 2.17.4rc1__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.4rc1.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.4rc1.dist-info → ansible_core-2.18.0b1.dist-info}/RECORD +311 -306
  254. {ansible_core-2.17.4rc1.dist-info → ansible_core-2.18.0b1.dist-info}/WHEEL +1 -1
  255. {ansible_core-2.17.4rc1.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.4rc1.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.4rc1.dist-info → ansible_core-2.18.0b1.dist-info}/COPYING +0 -0
  320. {ansible_core-2.17.4rc1.dist-info → ansible_core-2.18.0b1.dist-info}/top_level.txt +0 -0
@@ -54,7 +54,7 @@ class OpenBSDHardware(Hardware):
54
54
  hardware_facts.update(self.get_dmi_facts())
55
55
  hardware_facts.update(self.get_uptime_facts())
56
56
 
57
- # storage devices notorioslly prone to hang/block so they are under a timeout
57
+ # storage devices notoriously prone to hang/block so they are under a timeout
58
58
  try:
59
59
  hardware_facts.update(self.get_mount_facts())
60
60
  except timeout.TimeoutError:
@@ -113,6 +113,9 @@ class OpenBSDHardware(Hardware):
113
113
  def get_uptime_facts(self):
114
114
  # On openbsd, we need to call it with -n to get this value as an int.
115
115
  sysctl_cmd = self.module.get_bin_path('sysctl')
116
+ if sysctl_cmd is None:
117
+ return {}
118
+
116
119
  cmd = [sysctl_cmd, '-n', 'kern.boottime']
117
120
 
118
121
  rc, out, err = self.module.run_command(cmd)
@@ -172,7 +172,13 @@ class SunOSHardware(Hardware):
172
172
  rc, platform, err = self.module.run_command('/usr/bin/uname -i')
173
173
  platform_sbin = '/usr/platform/' + platform.rstrip() + '/sbin'
174
174
 
175
- prtdiag_path = self.module.get_bin_path("prtdiag", opt_dirs=[platform_sbin])
175
+ prtdiag_path = self.module.get_bin_path(
176
+ "prtdiag",
177
+ opt_dirs=[platform_sbin]
178
+ )
179
+ if prtdiag_path is None:
180
+ return dmi_facts
181
+
176
182
  rc, out, err = self.module.run_command(prtdiag_path)
177
183
  # rc returns 1
178
184
  if out:
@@ -32,20 +32,21 @@ class AIXNetwork(GenericBsdIfconfigNetwork):
32
32
  interface = dict(v4={}, v6={})
33
33
 
34
34
  netstat_path = self.module.get_bin_path('netstat')
35
-
36
- if netstat_path:
37
- rc, out, err = self.module.run_command([netstat_path, '-nr'])
38
-
39
- lines = out.splitlines()
40
- for line in lines:
41
- words = line.split()
42
- if len(words) > 1 and words[0] == 'default':
43
- if '.' in words[1]:
44
- interface['v4']['gateway'] = words[1]
45
- interface['v4']['interface'] = words[5]
46
- elif ':' in words[1]:
47
- interface['v6']['gateway'] = words[1]
48
- interface['v6']['interface'] = words[5]
35
+ if netstat_path is None:
36
+ return interface['v4'], interface['v6']
37
+
38
+ rc, out, err = self.module.run_command([netstat_path, '-nr'])
39
+
40
+ lines = out.splitlines()
41
+ for line in lines:
42
+ words = line.split()
43
+ if len(words) > 1 and words[0] == 'default':
44
+ if '.' in words[1]:
45
+ interface['v4']['gateway'] = words[1]
46
+ interface['v4']['interface'] = words[5]
47
+ elif ':' in words[1]:
48
+ interface['v6']['gateway'] = words[1]
49
+ interface['v6']['interface'] = words[5]
49
50
 
50
51
  return interface['v4'], interface['v6']
51
52
 
@@ -58,9 +59,7 @@ class AIXNetwork(GenericBsdIfconfigNetwork):
58
59
  all_ipv6_addresses=[],
59
60
  )
60
61
 
61
- uname_rc = None
62
- uname_out = None
63
- uname_err = None
62
+ uname_rc = uname_out = uname_err = None
64
63
  uname_path = self.module.get_bin_path('uname')
65
64
  if uname_path:
66
65
  uname_rc, uname_out, uname_err = self.module.run_command([uname_path, '-W'])
@@ -82,7 +82,10 @@ class FcWwnInitiatorFactCollector(BaseFactCollector):
82
82
  fc_facts['fibre_channel_wwn'].append(data[-1].rstrip())
83
83
  elif sys.platform.startswith('hp-ux'):
84
84
  cmd = module.get_bin_path('ioscan')
85
- fcmsu_cmd = module.get_bin_path('fcmsutil', opt_dirs=['/opt/fcms/bin'])
85
+ fcmsu_cmd = module.get_bin_path(
86
+ 'fcmsutil',
87
+ opt_dirs=['/opt/fcms/bin'],
88
+ )
86
89
  # go ahead if we have both commands available
87
90
  if cmd and fcmsu_cmd:
88
91
  # ioscan / get list of available fibre-channel devices (fcd)
@@ -20,7 +20,7 @@ from ansible.module_utils.facts.network.base import Network, NetworkCollector
20
20
 
21
21
  class HPUXNetwork(Network):
22
22
  """
23
- HP-UX-specifig subclass of Network. Defines networking facts:
23
+ HP-UX-specific subclass of Network. Defines networking facts:
24
24
  - default_interface
25
25
  - interfaces (a list of interface names)
26
26
  - interface_<name> dictionary of ipv4 address information.
@@ -29,7 +29,10 @@ class HPUXNetwork(Network):
29
29
 
30
30
  def populate(self, collected_facts=None):
31
31
  network_facts = {}
32
- netstat_path = self.module.get_bin_path('netstat')
32
+ netstat_path = self.module.get_bin_path(
33
+ 'netstat',
34
+ opt_dirs=['/usr/bin']
35
+ )
33
36
 
34
37
  if netstat_path is None:
35
38
  return network_facts
@@ -46,7 +49,14 @@ class HPUXNetwork(Network):
46
49
 
47
50
  def get_default_interfaces(self):
48
51
  default_interfaces = {}
49
- rc, out, err = self.module.run_command("/usr/bin/netstat -nr")
52
+ netstat_path = self.module.get_bin_path(
53
+ 'netstat',
54
+ opt_dirs=['/usr/bin']
55
+ )
56
+
57
+ if netstat_path is None:
58
+ return default_interfaces
59
+ rc, out, err = self.module.run_command("%s -nr" % netstat_path)
50
60
  lines = out.splitlines()
51
61
  for line in lines:
52
62
  words = line.split()
@@ -59,7 +69,14 @@ class HPUXNetwork(Network):
59
69
 
60
70
  def get_interfaces_info(self):
61
71
  interfaces = {}
62
- rc, out, err = self.module.run_command("/usr/bin/netstat -niw")
72
+ netstat_path = self.module.get_bin_path(
73
+ 'netstat',
74
+ opt_dirs=['/usr/bin']
75
+ )
76
+
77
+ if netstat_path is None:
78
+ return interfaces
79
+ rc, out, err = self.module.run_command("%s -niw" % netstat_path)
63
80
  lines = out.splitlines()
64
81
  for line in lines:
65
82
  words = line.split()
@@ -21,7 +21,6 @@ import sys
21
21
 
22
22
  import ansible.module_utils.compat.typing as t
23
23
 
24
- from ansible.module_utils.common.process import get_bin_path
25
24
  from ansible.module_utils.facts.utils import get_file_content
26
25
  from ansible.module_utils.facts.network.base import NetworkCollector
27
26
 
@@ -80,9 +79,8 @@ class IscsiInitiatorNetworkCollector(NetworkCollector):
80
79
  iscsi_facts['iscsi_iqn'] = line.split('=', 1)[1]
81
80
  break
82
81
  elif sys.platform.startswith('aix'):
83
- try:
84
- cmd = get_bin_path('lsattr')
85
- except ValueError:
82
+ cmd = module.get_bin_path('lsattr')
83
+ if cmd is None:
86
84
  return iscsi_facts
87
85
 
88
86
  cmd += " -E -l iscsi0"
@@ -92,10 +90,11 @@ class IscsiInitiatorNetworkCollector(NetworkCollector):
92
90
  iscsi_facts['iscsi_iqn'] = line.split()[1].rstrip()
93
91
 
94
92
  elif sys.platform.startswith('hp-ux'):
95
- # try to find it in the default PATH and opt_dirs
96
- try:
97
- cmd = get_bin_path('iscsiutil', opt_dirs=['/opt/iscsi/bin'])
98
- except ValueError:
93
+ cmd = module.get_bin_path(
94
+ 'iscsiutil',
95
+ opt_dirs=['/opt/iscsi/bin']
96
+ )
97
+ if cmd is None:
99
98
  return iscsi_facts
100
99
 
101
100
  cmd += " -l"
@@ -295,8 +295,6 @@ class LinuxNetwork(Network):
295
295
  if not address == '::1':
296
296
  ips['all_ipv6_addresses'].append(address)
297
297
 
298
- ip_path = self.module.get_bin_path("ip")
299
-
300
298
  args = [ip_path, 'addr', 'show', 'primary', 'dev', device]
301
299
  rc, primary_data, stderr = self.module.run_command(args, errors='surrogate_then_replace')
302
300
  if rc == 0:
@@ -22,8 +22,14 @@ class FacterFactCollector(BaseFactCollector):
22
22
  namespace=namespace)
23
23
 
24
24
  def find_facter(self, module):
25
- facter_path = module.get_bin_path('facter', opt_dirs=['/opt/puppetlabs/bin'])
26
- cfacter_path = module.get_bin_path('cfacter', opt_dirs=['/opt/puppetlabs/bin'])
25
+ facter_path = module.get_bin_path(
26
+ 'facter',
27
+ opt_dirs=['/opt/puppetlabs/bin']
28
+ )
29
+ cfacter_path = module.get_bin_path(
30
+ 'cfacter',
31
+ opt_dirs=['/opt/puppetlabs/bin']
32
+ )
27
33
 
28
34
  # Prefer to use cfacter if available
29
35
  if cfacter_path is not None:
@@ -73,7 +79,6 @@ class FacterFactCollector(BaseFactCollector):
73
79
  try:
74
80
  facter_dict = json.loads(facter_output)
75
81
  except Exception:
76
- # FIXME: maybe raise a FactCollectorError with some info attrs?
77
- pass
82
+ module.warn("Failed to parse facter facts")
78
83
 
79
84
  return facter_dict
@@ -36,10 +36,11 @@ class OhaiFactCollector(BaseFactCollector):
36
36
  namespace=namespace)
37
37
 
38
38
  def find_ohai(self, module):
39
- ohai_path = module.get_bin_path('ohai')
40
- return ohai_path
39
+ return module.get_bin_path(
40
+ 'ohai'
41
+ )
41
42
 
42
- def run_ohai(self, module, ohai_path,):
43
+ def run_ohai(self, module, ohai_path):
43
44
  rc, out, err = module.run_command(ohai_path)
44
45
  return rc, out, err
45
46
 
@@ -67,7 +68,6 @@ class OhaiFactCollector(BaseFactCollector):
67
68
  try:
68
69
  ohai_facts = json.loads(ohai_output)
69
70
  except Exception:
70
- # FIXME: useful error, logging, something...
71
- pass
71
+ module.warn("Failed to gather ohai facts")
72
72
 
73
73
  return ohai_facts
@@ -3,24 +3,29 @@
3
3
 
4
4
  from __future__ import annotations
5
5
 
6
+ import ansible.module_utils.compat.typing as t
7
+
6
8
  from abc import ABCMeta, abstractmethod
7
9
 
8
10
  from ansible.module_utils.six import with_metaclass
11
+ from ansible.module_utils.basic import missing_required_lib
9
12
  from ansible.module_utils.common.process import get_bin_path
13
+ from ansible.module_utils.common.respawn import has_respawned, probe_interpreters_for_module, respawn_module
10
14
  from ansible.module_utils.common._utils import get_all_subclasses
11
15
 
12
16
 
13
17
  def get_all_pkg_managers():
14
18
 
15
- return {obj.__name__.lower(): obj for obj in get_all_subclasses(PkgMgr) if obj not in (CLIMgr, LibMgr)}
19
+ return {obj.__name__.lower(): obj for obj in get_all_subclasses(PkgMgr) if obj not in (CLIMgr, LibMgr, RespawningLibMgr)}
16
20
 
17
21
 
18
22
  class PkgMgr(with_metaclass(ABCMeta, object)): # type: ignore[misc]
19
23
 
20
24
  @abstractmethod
21
- def is_available(self):
25
+ def is_available(self, handle_exceptions):
22
26
  # This method is supposed to return True/False if the package manager is currently installed/usable
23
27
  # It can also 'prep' the required systems in the process of detecting availability
28
+ # If handle_exceptions is false it should raise exceptions related to manager discovery instead of handling them.
24
29
  pass
25
30
 
26
31
  @abstractmethod
@@ -58,16 +63,50 @@ class LibMgr(PkgMgr):
58
63
  self._lib = None
59
64
  super(LibMgr, self).__init__()
60
65
 
61
- def is_available(self):
66
+ def is_available(self, handle_exceptions=True):
62
67
  found = False
63
68
  try:
64
69
  self._lib = __import__(self.LIB)
65
70
  found = True
66
71
  except ImportError:
67
- pass
72
+ if not handle_exceptions:
73
+ raise Exception(missing_required_lib(self.LIB))
68
74
  return found
69
75
 
70
76
 
77
+ class RespawningLibMgr(LibMgr):
78
+
79
+ CLI_BINARIES = [] # type: t.List[str]
80
+ INTERPRETERS = ['/usr/bin/python3']
81
+
82
+ def is_available(self, handle_exceptions=True):
83
+ if super(RespawningLibMgr, self).is_available():
84
+ return True
85
+
86
+ for binary in self.CLI_BINARIES:
87
+ try:
88
+ bin_path = get_bin_path(binary)
89
+ except ValueError:
90
+ # Not an interesting exception to raise, just a speculative probe
91
+ continue
92
+ else:
93
+ # It looks like this package manager is installed
94
+ if not has_respawned():
95
+ # See if respawning will help
96
+ interpreter_path = probe_interpreters_for_module(self.INTERPRETERS, self.LIB)
97
+ if interpreter_path:
98
+ respawn_module(interpreter_path)
99
+ # The module will exit when the respawned copy completes
100
+
101
+ if not handle_exceptions:
102
+ raise Exception(f'Found executable at {bin_path}. {missing_required_lib(self.LIB)}')
103
+
104
+ if not handle_exceptions:
105
+ raise Exception(missing_required_lib(self.LIB))
106
+
107
+ return False
108
+
109
+
71
110
  class CLIMgr(PkgMgr):
72
111
 
73
112
  CLI = None # type: str | None
@@ -77,9 +116,12 @@ class CLIMgr(PkgMgr):
77
116
  self._cli = None
78
117
  super(CLIMgr, self).__init__()
79
118
 
80
- def is_available(self):
119
+ def is_available(self, handle_exceptions=True):
120
+ found = False
81
121
  try:
82
122
  self._cli = get_bin_path(self.CLI)
123
+ found = True
83
124
  except ValueError:
84
- return False
85
- return True
125
+ if not handle_exceptions:
126
+ raise
127
+ return found
@@ -21,41 +21,43 @@ from ansible.module_utils.common.text.converters import to_text
21
21
 
22
22
 
23
23
  def get_sysctl(module, prefixes):
24
- sysctl_cmd = module.get_bin_path('sysctl')
25
- cmd = [sysctl_cmd]
26
- cmd.extend(prefixes)
27
24
 
28
25
  sysctl = dict()
29
-
30
- try:
31
- rc, out, err = module.run_command(cmd)
32
- except (IOError, OSError) as e:
33
- module.warn('Unable to read sysctl: %s' % to_text(e))
34
- rc = 1
35
-
36
- if rc == 0:
37
- key = ''
38
- value = ''
39
- for line in out.splitlines():
40
- if not line.strip():
41
- continue
42
-
43
- if line.startswith(' '):
44
- # handle multiline values, they will not have a starting key
45
- # Add the newline back in so people can split on it to parse
46
- # lines if they need to.
47
- value += '\n' + line
48
- continue
26
+ sysctl_cmd = module.get_bin_path('sysctl')
27
+ if sysctl_cmd is not None:
28
+
29
+ cmd = [sysctl_cmd]
30
+ cmd.extend(prefixes)
31
+
32
+ try:
33
+ rc, out, err = module.run_command(cmd)
34
+ except (IOError, OSError) as e:
35
+ module.warn('Unable to read sysctl: %s' % to_text(e))
36
+ rc = 1
37
+
38
+ if rc == 0:
39
+ key = ''
40
+ value = ''
41
+ for line in out.splitlines():
42
+ if not line.strip():
43
+ continue
44
+
45
+ if line.startswith(' '):
46
+ # handle multiline values, they will not have a starting key
47
+ # Add the newline back in so people can split on it to parse
48
+ # lines if they need to.
49
+ value += '\n' + line
50
+ continue
51
+
52
+ if key:
53
+ sysctl[key] = value.strip()
54
+
55
+ try:
56
+ (key, value) = re.split(r'\s?=\s?|: ', line, maxsplit=1)
57
+ except Exception as e:
58
+ module.warn('Unable to split sysctl line (%s): %s' % (to_text(line), to_text(e)))
49
59
 
50
60
  if key:
51
61
  sysctl[key] = value.strip()
52
62
 
53
- try:
54
- (key, value) = re.split(r'\s?=\s?|: ', line, maxsplit=1)
55
- except Exception as e:
56
- module.warn('Unable to split sysctl line (%s): %s' % (to_text(line), to_text(e)))
57
-
58
- if key:
59
- sysctl[key] = value.strip()
60
-
61
63
  return sysctl
@@ -517,7 +517,7 @@ class Distribution(object):
517
517
  'Linux Mint', 'SteamOS', 'Devuan', 'Kali', 'Cumulus Linux',
518
518
  'Pop!_OS', 'Parrot', 'Pardus GNU/Linux', 'Uos', 'Deepin', 'OSMC'],
519
519
  'Suse': ['SuSE', 'SLES', 'SLED', 'openSUSE', 'openSUSE Tumbleweed',
520
- 'SLES_SAP', 'SUSE_LINUX', 'openSUSE Leap', 'ALP-Dolomite'],
520
+ 'SLES_SAP', 'SUSE_LINUX', 'openSUSE Leap', 'ALP-Dolomite', 'SL-Micro'],
521
521
  'Archlinux': ['Archlinux', 'Antergos', 'Manjaro'],
522
522
  'Mandrake': ['Mandrake', 'Mandriva'],
523
523
  'Solaris': ['Solaris', 'Nexenta', 'OmniOS', 'OpenIndiana', 'SmartOS'],
@@ -1,17 +1,5 @@
1
- # This file is part of Ansible
2
- #
3
- # Ansible is free software: you can redistribute it and/or modify
4
- # it under the terms of the GNU General Public License as published by
5
- # the Free Software Foundation, either version 3 of the License, or
6
- # (at your option) any later version.
7
- #
8
- # Ansible is distributed in the hope that it will be useful,
9
- # but WITHOUT ANY WARRANTY; without even the implied warranty of
10
- # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11
- # GNU General Public License for more details.
12
- #
13
- # You should have received a copy of the GNU General Public License
14
- # along with Ansible. If not, see <http://www.gnu.org/licenses/>.
1
+ # Copyright: Contributors to the Ansible project
2
+ # GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
15
3
 
16
4
  from __future__ import annotations
17
5
 
@@ -25,7 +13,6 @@ import ansible.module_utils.compat.typing as t
25
13
  from ansible.module_utils.common.text.converters import to_text
26
14
  from ansible.module_utils.facts.utils import get_file_content
27
15
  from ansible.module_utils.facts.collector import BaseFactCollector
28
- from ansible.module_utils.six import PY3
29
16
  from ansible.module_utils.six.moves import configparser, StringIO
30
17
 
31
18
 
@@ -91,12 +78,9 @@ class LocalFactCollector(BaseFactCollector):
91
78
  # if that fails read it with ConfigParser
92
79
  cp = configparser.ConfigParser()
93
80
  try:
94
- if PY3:
95
- cp.read_file(StringIO(out))
96
- else:
97
- cp.readfp(StringIO(out))
81
+ cp.read_file(StringIO(out))
98
82
  except configparser.Error:
99
- fact = "error loading facts as JSON or ini - please check content: %s" % fn
83
+ fact = f"error loading facts as JSON or ini - please check content: {fn}"
100
84
  module.warn(fact)
101
85
  else:
102
86
  fact = {}
@@ -104,8 +88,14 @@ class LocalFactCollector(BaseFactCollector):
104
88
  if sect not in fact:
105
89
  fact[sect] = {}
106
90
  for opt in cp.options(sect):
107
- val = cp.get(sect, opt)
108
- fact[sect][opt] = val
91
+ try:
92
+ val = cp.get(sect, opt)
93
+ except configparser.Error as ex:
94
+ fact = f"error loading facts as ini - please check content: {fn} ({ex})"
95
+ module.warn(fact)
96
+ continue
97
+ else:
98
+ fact[sect][opt] = val
109
99
  except Exception as e:
110
100
  fact = "Failed to convert (%s) to JSON: %s" % (fn, to_text(e))
111
101
  module.warn(fact)
@@ -106,7 +106,7 @@ class ServiceMgrFactCollector(BaseFactCollector):
106
106
  proc_1 = proc_1.strip()
107
107
 
108
108
  if proc_1 is not None and (proc_1 == 'init' or proc_1.endswith('sh')):
109
- # many systems return init, so this cannot be trusted, if it ends in 'sh' it probalby is a shell in a container
109
+ # many systems return init, so this cannot be trusted, if it ends in 'sh' it probably is a shell in a container
110
110
  proc_1 = None
111
111
 
112
112
  # if not init/None it should be an identifiable or custom init, so we are done!
@@ -144,6 +144,8 @@ class ServiceMgrFactCollector(BaseFactCollector):
144
144
  service_mgr_name = 'systemd'
145
145
  elif os.path.exists('/etc/init.d/'):
146
146
  service_mgr_name = 'sysvinit'
147
+ elif os.path.exists('/etc/dinit.d/'):
148
+ service_mgr_name = 'dinit'
147
149
 
148
150
  if not service_mgr_name:
149
151
  # if we cannot detect, fallback to generic 'service'
@@ -0,0 +1,47 @@
1
+ # Get systemd version and features
2
+ #
3
+ # This file is part of Ansible
4
+ #
5
+ # Ansible is free software: you can redistribute it and/or modify
6
+ # it under the terms of the GNU General Public License as published by
7
+ # the Free Software Foundation, either version 3 of the License, or
8
+ # (at your option) any later version.
9
+ #
10
+ # Ansible is distributed in the hope that it will be useful,
11
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
12
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13
+ # GNU General Public License for more details.
14
+ #
15
+ # You should have received a copy of the GNU General Public License
16
+ # along with Ansible. If not, see <http://www.gnu.org/licenses/>.
17
+
18
+ from __future__ import annotations
19
+
20
+ import ansible.module_utils.compat.typing as t
21
+
22
+ from ansible.module_utils.facts.collector import BaseFactCollector
23
+ from ansible.module_utils.facts.system.service_mgr import ServiceMgrFactCollector
24
+
25
+
26
+ class SystemdFactCollector(BaseFactCollector):
27
+ name = "systemd"
28
+ _fact_ids = set() # type: t.Set[str]
29
+
30
+ def collect(self, module=None, collected_facts=None):
31
+ systemctl_bin = module.get_bin_path("systemctl")
32
+ systemd_facts = {}
33
+ if systemctl_bin and ServiceMgrFactCollector.is_systemd_managed(module):
34
+ rc, stdout, dummy = module.run_command(
35
+ [systemctl_bin, "--version"],
36
+ check_rc=False,
37
+ )
38
+
39
+ if rc != 0:
40
+ return systemd_facts
41
+
42
+ systemd_facts["systemd"] = {
43
+ "features": str(stdout.split("\n")[1]),
44
+ "version": int(stdout.split(" ")[1]),
45
+ }
46
+
47
+ return systemd_facts
@@ -37,7 +37,7 @@ Function Add-CSharpType {
37
37
  .PARAMETER CompileSymbols
38
38
  [String[]] A list of symbols to be defined during compile time. These are
39
39
  added to the existing symbols, 'CORECLR', 'WINDOWS', 'UNIX' that are set
40
- conditionalls in this cmdlet.
40
+ conditionals in this cmdlet.
41
41
 
42
42
  .NOTES
43
43
  The following features were added to control the compiling options from the
@@ -4,7 +4,7 @@
4
4
  # used by Convert-DictToSnakeCase to convert a string in camelCase
5
5
  # format to snake_case
6
6
  Function Convert-StringToSnakeCase($string) {
7
- # cope with pluralized abbreaviations such as TargetGroupARNs
7
+ # cope with pluralized abbreviations such as TargetGroupARNs
8
8
  if ($string -cmatch "[A-Z]{3,}s") {
9
9
  $replacement_string = $string -creplace $matches[0], "_$($matches[0].ToLower())"
10
10
 
@@ -81,7 +81,7 @@ def split_args(args):
81
81
  '''
82
82
 
83
83
  # the list of params parsed out of the arg string
84
- # this is going to be the result value when we are donei
84
+ # this is going to be the result value when we are done
85
85
  params = []
86
86
 
87
87
  # here we encode the args, so we have a uniform charset to
@@ -61,7 +61,7 @@ notes:
61
61
  - The alias O(host) of the parameter O(name) is only available on Ansible 2.4 and newer.
62
62
  - Since Ansible 2.4, the C(inventory_dir) variable is now set to V(None) instead of the 'global inventory source',
63
63
  because you can now have multiple sources. An example was added that shows how to partially restore the previous behaviour.
64
- - Though this module does not change the remote host, we do provide 'changed' status as it can be useful for those trying to track inventory changes.
64
+ - Though this module does not change the remote host, we do provide C(changed) status as it can be useful for those trying to track inventory changes.
65
65
  - The hosts added will not bypass the C(--limit) from the command line, so both of those need to be in agreement to make them available as play targets.
66
66
  They are still available from hostvars and for delegation as a normal part of the inventory.
67
67
  seealso: