ansible-core 2.18.5rc1__py3-none-any.whl → 2.19.0b2__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (710) hide show
  1. ansible/_internal/__init__.py +53 -0
  2. ansible/_internal/_ansiballz.py +265 -0
  3. ansible/_internal/_collection_proxy.py +47 -0
  4. ansible/_internal/_datatag/__init__.py +0 -0
  5. ansible/_internal/_datatag/_tags.py +130 -0
  6. ansible/_internal/_datatag/_utils.py +19 -0
  7. ansible/_internal/_datatag/_wrappers.py +33 -0
  8. ansible/_internal/_errors/__init__.py +0 -0
  9. ansible/_internal/_errors/_captured.py +128 -0
  10. ansible/_internal/_errors/_handler.py +91 -0
  11. ansible/_internal/_errors/_utils.py +310 -0
  12. ansible/_internal/_json/__init__.py +203 -0
  13. ansible/_internal/_json/_legacy_encoder.py +34 -0
  14. ansible/_internal/_json/_profiles/__init__.py +0 -0
  15. ansible/_internal/_json/_profiles/_cache_persistence.py +55 -0
  16. ansible/_internal/_json/_profiles/_inventory_legacy.py +40 -0
  17. ansible/_internal/_json/_profiles/_legacy.py +197 -0
  18. ansible/_internal/_locking.py +21 -0
  19. ansible/_internal/_plugins/__init__.py +0 -0
  20. ansible/_internal/_plugins/_cache.py +57 -0
  21. ansible/_internal/_task.py +78 -0
  22. ansible/_internal/_templating/__init__.py +10 -0
  23. ansible/_internal/_templating/_access.py +86 -0
  24. ansible/_internal/_templating/_chain_templar.py +63 -0
  25. ansible/_internal/_templating/_datatag.py +95 -0
  26. ansible/_internal/_templating/_engine.py +588 -0
  27. ansible/_internal/_templating/_errors.py +28 -0
  28. ansible/_internal/_templating/_jinja_bits.py +1066 -0
  29. ansible/_internal/_templating/_jinja_common.py +332 -0
  30. ansible/_internal/_templating/_jinja_patches.py +44 -0
  31. ansible/_internal/_templating/_jinja_plugins.py +345 -0
  32. ansible/_internal/_templating/_lazy_containers.py +633 -0
  33. ansible/_internal/_templating/_marker_behaviors.py +103 -0
  34. ansible/_internal/_templating/_transform.py +63 -0
  35. ansible/_internal/_templating/_utils.py +107 -0
  36. ansible/_internal/_wrapt.py +1052 -0
  37. ansible/_internal/_yaml/__init__.py +0 -0
  38. ansible/_internal/_yaml/_constructor.py +240 -0
  39. ansible/_internal/_yaml/_dumper.py +62 -0
  40. ansible/_internal/_yaml/_errors.py +166 -0
  41. ansible/_internal/_yaml/_loader.py +66 -0
  42. ansible/_internal/ansible_collections/ansible/_protomatter/README.md +11 -0
  43. ansible/_internal/ansible_collections/ansible/_protomatter/plugins/action/debug.py +36 -0
  44. ansible/_internal/ansible_collections/ansible/_protomatter/plugins/filter/apply_trust.py +19 -0
  45. ansible/_internal/ansible_collections/ansible/_protomatter/plugins/filter/dump_object.py +18 -0
  46. ansible/_internal/ansible_collections/ansible/_protomatter/plugins/filter/finalize.py +16 -0
  47. ansible/_internal/ansible_collections/ansible/_protomatter/plugins/filter/origin.py +18 -0
  48. ansible/_internal/ansible_collections/ansible/_protomatter/plugins/filter/python_literal_eval.py +24 -0
  49. ansible/_internal/ansible_collections/ansible/_protomatter/plugins/filter/python_literal_eval.yml +33 -0
  50. ansible/_internal/ansible_collections/ansible/_protomatter/plugins/filter/tag_names.py +16 -0
  51. ansible/_internal/ansible_collections/ansible/_protomatter/plugins/filter/true_type.py +17 -0
  52. ansible/_internal/ansible_collections/ansible/_protomatter/plugins/filter/unmask.py +49 -0
  53. ansible/_internal/ansible_collections/ansible/_protomatter/plugins/lookup/config.py +21 -0
  54. ansible/_internal/ansible_collections/ansible/_protomatter/plugins/lookup/config.yml +2 -0
  55. ansible/_internal/ansible_collections/ansible/_protomatter/plugins/test/tagged.py +15 -0
  56. ansible/_internal/ansible_collections/ansible/_protomatter/plugins/test/tagged.yml +19 -0
  57. ansible/_internal/ansible_collections/ansible/_protomatter/plugins/test/tagged_with.py +18 -0
  58. ansible/_internal/ansible_collections/ansible/_protomatter/plugins/test/tagged_with.yml +19 -0
  59. ansible/cli/__init__.py +159 -89
  60. ansible/cli/_ssh_askpass.py +47 -0
  61. ansible/cli/adhoc.py +14 -7
  62. ansible/cli/arguments/option_helpers.py +154 -7
  63. ansible/cli/config.py +43 -68
  64. ansible/cli/console.py +10 -8
  65. ansible/cli/doc.py +62 -53
  66. ansible/cli/galaxy.py +27 -20
  67. ansible/cli/inventory.py +28 -26
  68. ansible/cli/playbook.py +4 -12
  69. ansible/cli/pull.py +51 -11
  70. ansible/cli/scripts/ansible_connection_cli_stub.py +7 -7
  71. ansible/cli/vault.py +12 -11
  72. ansible/compat/__init__.py +2 -2
  73. ansible/config/base.yml +166 -112
  74. ansible/config/manager.py +52 -49
  75. ansible/constants.py +3 -4
  76. ansible/errors/__init__.py +277 -235
  77. ansible/executor/interpreter_discovery.py +28 -149
  78. ansible/executor/module_common.py +426 -493
  79. ansible/executor/play_iterator.py +22 -27
  80. ansible/executor/playbook_executor.py +11 -11
  81. ansible/executor/powershell/async_watchdog.ps1 +97 -102
  82. ansible/executor/powershell/async_wrapper.ps1 +202 -151
  83. ansible/executor/powershell/become_wrapper.ps1 +89 -144
  84. ansible/executor/powershell/bootstrap_wrapper.ps1 +24 -9
  85. ansible/executor/powershell/coverage_wrapper.ps1 +82 -135
  86. ansible/executor/powershell/exec_wrapper.ps1 +462 -196
  87. ansible/executor/powershell/module_manifest.py +417 -265
  88. ansible/executor/powershell/module_wrapper.ps1 +169 -186
  89. ansible/executor/powershell/psrp_fetch_file.ps1 +41 -0
  90. ansible/executor/powershell/psrp_put_file.ps1 +122 -0
  91. ansible/executor/powershell/winrm_fetch_file.ps1 +46 -0
  92. ansible/executor/powershell/winrm_put_file.ps1 +36 -0
  93. ansible/executor/process/worker.py +161 -96
  94. ansible/executor/stats.py +5 -5
  95. ansible/executor/task_executor.py +268 -258
  96. ansible/executor/task_queue_manager.py +124 -90
  97. ansible/executor/task_result.py +183 -78
  98. ansible/galaxy/__init__.py +2 -2
  99. ansible/galaxy/api.py +22 -18
  100. ansible/galaxy/collection/__init__.py +1 -1
  101. ansible/galaxy/collection/concrete_artifact_manager.py +8 -11
  102. ansible/galaxy/dependency_resolution/dataclasses.py +14 -4
  103. ansible/galaxy/dependency_resolution/providers.py +1 -1
  104. ansible/galaxy/dependency_resolution/reporters.py +81 -0
  105. ansible/galaxy/role.py +4 -8
  106. ansible/galaxy/token.py +28 -21
  107. ansible/inventory/data.py +47 -57
  108. ansible/inventory/group.py +44 -72
  109. ansible/inventory/helpers.py +9 -0
  110. ansible/inventory/host.py +32 -54
  111. ansible/inventory/manager.py +78 -34
  112. ansible/keyword_desc.yml +1 -1
  113. ansible/module_utils/_internal/__init__.py +55 -0
  114. ansible/module_utils/_internal/_ambient_context.py +58 -0
  115. ansible/module_utils/_internal/_ansiballz.py +133 -0
  116. ansible/module_utils/_internal/_concurrent/_daemon_threading.py +1 -0
  117. ansible/module_utils/_internal/_dataclass_annotation_patch.py +64 -0
  118. ansible/module_utils/_internal/_dataclass_validation.py +217 -0
  119. ansible/module_utils/_internal/_datatag/__init__.py +928 -0
  120. ansible/module_utils/_internal/_datatag/_tags.py +38 -0
  121. ansible/module_utils/_internal/_debugging.py +31 -0
  122. ansible/module_utils/_internal/_errors.py +30 -0
  123. ansible/module_utils/_internal/_json/__init__.py +63 -0
  124. ansible/module_utils/_internal/_json/_legacy_encoder.py +26 -0
  125. ansible/module_utils/_internal/_json/_profiles/__init__.py +410 -0
  126. ansible/module_utils/_internal/_json/_profiles/_fallback_to_str.py +73 -0
  127. ansible/module_utils/_internal/_json/_profiles/_module_legacy_c2m.py +31 -0
  128. ansible/module_utils/_internal/_json/_profiles/_module_legacy_m2c.py +35 -0
  129. ansible/module_utils/_internal/_json/_profiles/_module_modern_c2m.py +35 -0
  130. ansible/module_utils/_internal/_json/_profiles/_module_modern_m2c.py +33 -0
  131. ansible/module_utils/_internal/_json/_profiles/_tagless.py +50 -0
  132. ansible/module_utils/_internal/_patches/__init__.py +66 -0
  133. ansible/module_utils/_internal/_patches/_dataclass_annotation_patch.py +55 -0
  134. ansible/module_utils/_internal/_patches/_socket_patch.py +34 -0
  135. ansible/module_utils/_internal/_patches/_sys_intern_patch.py +34 -0
  136. ansible/module_utils/_internal/_plugin_exec_context.py +49 -0
  137. ansible/module_utils/_internal/_testing.py +0 -0
  138. ansible/module_utils/_internal/_traceback.py +89 -0
  139. ansible/module_utils/ansible_release.py +2 -2
  140. ansible/module_utils/api.py +1 -2
  141. ansible/module_utils/basic.py +152 -120
  142. ansible/module_utils/common/_utils.py +24 -28
  143. ansible/module_utils/common/collections.py +1 -2
  144. ansible/module_utils/common/dict_transformations.py +2 -2
  145. ansible/module_utils/common/file.py +2 -2
  146. ansible/module_utils/common/json.py +90 -84
  147. ansible/module_utils/common/locale.py +2 -2
  148. ansible/module_utils/common/messages.py +108 -0
  149. ansible/module_utils/common/parameters.py +27 -24
  150. ansible/module_utils/common/process.py +2 -2
  151. ansible/module_utils/common/respawn.py +41 -19
  152. ansible/module_utils/common/sentinel.py +66 -0
  153. ansible/module_utils/common/sys_info.py +8 -8
  154. ansible/module_utils/common/text/converters.py +16 -37
  155. ansible/module_utils/common/validation.py +35 -24
  156. ansible/module_utils/common/warnings.py +86 -25
  157. ansible/module_utils/common/yaml.py +29 -3
  158. ansible/module_utils/compat/datetime.py +33 -21
  159. ansible/module_utils/compat/paramiko.py +21 -10
  160. ansible/module_utils/compat/typing.py +6 -5
  161. ansible/module_utils/connection.py +2 -2
  162. ansible/module_utils/csharp/Ansible.Basic.cs +14 -11
  163. ansible/module_utils/csharp/Ansible.Become.cs +1 -0
  164. ansible/module_utils/csharp/Ansible._Async.cs +517 -0
  165. ansible/module_utils/datatag.py +46 -0
  166. ansible/module_utils/distro/__init__.py +2 -2
  167. ansible/module_utils/facts/ansible_collector.py +4 -5
  168. ansible/module_utils/facts/collector.py +13 -14
  169. ansible/module_utils/facts/compat.py +4 -4
  170. ansible/module_utils/facts/default_collectors.py +1 -1
  171. ansible/module_utils/facts/hardware/aix.py +34 -0
  172. ansible/module_utils/facts/hardware/base.py +1 -1
  173. ansible/module_utils/facts/hardware/darwin.py +1 -3
  174. ansible/module_utils/facts/hardware/freebsd.py +2 -2
  175. ansible/module_utils/facts/hardware/linux.py +4 -4
  176. ansible/module_utils/facts/namespace.py +1 -1
  177. ansible/module_utils/facts/network/base.py +1 -1
  178. ansible/module_utils/facts/network/fc_wwn.py +1 -2
  179. ansible/module_utils/facts/network/iscsi.py +1 -2
  180. ansible/module_utils/facts/network/nvme.py +1 -2
  181. ansible/module_utils/facts/other/facter.py +1 -2
  182. ansible/module_utils/facts/other/ohai.py +2 -3
  183. ansible/module_utils/facts/system/apparmor.py +1 -2
  184. ansible/module_utils/facts/system/caps.py +1 -1
  185. ansible/module_utils/facts/system/chroot.py +1 -2
  186. ansible/module_utils/facts/system/cmdline.py +1 -2
  187. ansible/module_utils/facts/system/date_time.py +5 -3
  188. ansible/module_utils/facts/system/distribution.py +9 -8
  189. ansible/module_utils/facts/system/dns.py +1 -1
  190. ansible/module_utils/facts/system/env.py +1 -2
  191. ansible/module_utils/facts/system/fips.py +7 -20
  192. ansible/module_utils/facts/system/loadavg.py +1 -2
  193. ansible/module_utils/facts/system/local.py +1 -2
  194. ansible/module_utils/facts/system/lsb.py +1 -2
  195. ansible/module_utils/facts/system/pkg_mgr.py +1 -2
  196. ansible/module_utils/facts/system/platform.py +1 -2
  197. ansible/module_utils/facts/system/python.py +1 -2
  198. ansible/module_utils/facts/system/selinux.py +1 -1
  199. ansible/module_utils/facts/system/service_mgr.py +1 -2
  200. ansible/module_utils/facts/system/ssh_pub_keys.py +1 -1
  201. ansible/module_utils/facts/system/systemd.py +1 -1
  202. ansible/module_utils/facts/system/user.py +1 -2
  203. ansible/module_utils/facts/utils.py +3 -3
  204. ansible/module_utils/facts/virtual/base.py +1 -1
  205. ansible/module_utils/facts/virtual/sunos.py +3 -15
  206. ansible/module_utils/facts/virtual/sysctl.py +3 -16
  207. ansible/module_utils/json_utils.py +2 -2
  208. ansible/module_utils/parsing/convert_bool.py +1 -1
  209. ansible/module_utils/service.py +18 -21
  210. ansible/module_utils/splitter.py +7 -7
  211. ansible/module_utils/testing.py +31 -0
  212. ansible/module_utils/urls.py +60 -31
  213. ansible/modules/add_host.py +4 -4
  214. ansible/modules/apt.py +60 -46
  215. ansible/modules/apt_key.py +19 -12
  216. ansible/modules/apt_repository.py +19 -16
  217. ansible/modules/assemble.py +6 -6
  218. ansible/modules/assert.py +4 -4
  219. ansible/modules/async_status.py +10 -12
  220. ansible/modules/async_wrapper.py +8 -3
  221. ansible/modules/blockinfile.py +6 -7
  222. ansible/modules/command.py +10 -17
  223. ansible/modules/copy.py +57 -144
  224. ansible/modules/cron.py +20 -15
  225. ansible/modules/deb822_repository.py +8 -9
  226. ansible/modules/debconf.py +5 -5
  227. ansible/modules/debug.py +4 -4
  228. ansible/modules/dnf.py +8 -8
  229. ansible/modules/dnf5.py +39 -13
  230. ansible/modules/dpkg_selections.py +4 -4
  231. ansible/modules/expect.py +8 -10
  232. ansible/modules/fail.py +4 -4
  233. ansible/modules/fetch.py +4 -4
  234. ansible/modules/file.py +174 -133
  235. ansible/modules/find.py +19 -17
  236. ansible/modules/gather_facts.py +3 -3
  237. ansible/modules/get_url.py +59 -53
  238. ansible/modules/getent.py +7 -9
  239. ansible/modules/git.py +28 -25
  240. ansible/modules/group.py +6 -6
  241. ansible/modules/group_by.py +4 -4
  242. ansible/modules/hostname.py +13 -29
  243. ansible/modules/import_playbook.py +6 -6
  244. ansible/modules/import_role.py +6 -6
  245. ansible/modules/import_tasks.py +6 -6
  246. ansible/modules/include_role.py +6 -6
  247. ansible/modules/include_tasks.py +6 -6
  248. ansible/modules/include_vars.py +6 -6
  249. ansible/modules/iptables.py +86 -73
  250. ansible/modules/known_hosts.py +10 -10
  251. ansible/modules/lineinfile.py +5 -5
  252. ansible/modules/meta.py +4 -4
  253. ansible/modules/mount_facts.py +2 -2
  254. ansible/modules/package.py +4 -4
  255. ansible/modules/package_facts.py +22 -10
  256. ansible/modules/pause.py +6 -6
  257. ansible/modules/ping.py +6 -6
  258. ansible/modules/pip.py +10 -11
  259. ansible/modules/raw.py +4 -4
  260. ansible/modules/reboot.py +6 -6
  261. ansible/modules/replace.py +9 -13
  262. ansible/modules/rpm_key.py +7 -8
  263. ansible/modules/script.py +4 -4
  264. ansible/modules/service.py +7 -8
  265. ansible/modules/service_facts.py +87 -10
  266. ansible/modules/set_fact.py +5 -5
  267. ansible/modules/set_stats.py +4 -4
  268. ansible/modules/setup.py +2 -2
  269. ansible/modules/shell.py +6 -6
  270. ansible/modules/slurp.py +6 -6
  271. ansible/modules/stat.py +9 -23
  272. ansible/modules/subversion.py +15 -15
  273. ansible/modules/systemd.py +6 -6
  274. ansible/modules/systemd_service.py +6 -6
  275. ansible/modules/sysvinit.py +6 -6
  276. ansible/modules/tempfile.py +5 -6
  277. ansible/modules/template.py +6 -6
  278. ansible/modules/unarchive.py +32 -11
  279. ansible/modules/uri.py +33 -26
  280. ansible/modules/user.py +53 -34
  281. ansible/modules/validate_argument_spec.py +10 -7
  282. ansible/modules/wait_for.py +32 -27
  283. ansible/modules/wait_for_connection.py +6 -6
  284. ansible/modules/yum_repository.py +6 -6
  285. ansible/parsing/ajson.py +14 -32
  286. ansible/parsing/dataloader.py +99 -54
  287. ansible/parsing/mod_args.py +28 -44
  288. ansible/parsing/plugin_docs.py +21 -86
  289. ansible/parsing/quoting.py +1 -1
  290. ansible/parsing/splitter.py +27 -12
  291. ansible/parsing/utils/addresses.py +24 -24
  292. ansible/parsing/utils/jsonify.py +5 -1
  293. ansible/parsing/utils/yaml.py +32 -61
  294. ansible/parsing/vault/__init__.py +319 -87
  295. ansible/parsing/yaml/__init__.py +0 -18
  296. ansible/parsing/yaml/dumper.py +6 -120
  297. ansible/parsing/yaml/loader.py +6 -39
  298. ansible/parsing/yaml/objects.py +43 -335
  299. ansible/playbook/__init__.py +1 -1
  300. ansible/playbook/attribute.py +8 -3
  301. ansible/playbook/base.py +182 -132
  302. ansible/playbook/block.py +26 -24
  303. ansible/playbook/collectionsearch.py +1 -15
  304. ansible/playbook/conditional.py +3 -77
  305. ansible/playbook/handler.py +8 -2
  306. ansible/playbook/helpers.py +41 -53
  307. ansible/playbook/included_file.py +31 -27
  308. ansible/playbook/loop_control.py +2 -2
  309. ansible/playbook/play.py +85 -44
  310. ansible/playbook/play_context.py +12 -17
  311. ansible/playbook/playbook_include.py +14 -15
  312. ansible/playbook/role/__init__.py +24 -26
  313. ansible/playbook/role/definition.py +15 -17
  314. ansible/playbook/role/include.py +2 -4
  315. ansible/playbook/role/metadata.py +10 -11
  316. ansible/playbook/role_include.py +3 -3
  317. ansible/playbook/taggable.py +13 -8
  318. ansible/playbook/task.py +188 -118
  319. ansible/playbook/task_include.py +5 -5
  320. ansible/plugins/__init__.py +68 -21
  321. ansible/plugins/action/__init__.py +209 -176
  322. ansible/plugins/action/add_host.py +1 -1
  323. ansible/plugins/action/assemble.py +1 -1
  324. ansible/plugins/action/assert.py +54 -66
  325. ansible/plugins/action/copy.py +7 -11
  326. ansible/plugins/action/debug.py +37 -31
  327. ansible/plugins/action/dnf.py +3 -4
  328. ansible/plugins/action/fail.py +1 -1
  329. ansible/plugins/action/fetch.py +4 -5
  330. ansible/plugins/action/gather_facts.py +7 -6
  331. ansible/plugins/action/group_by.py +1 -1
  332. ansible/plugins/action/include_vars.py +10 -11
  333. ansible/plugins/action/package.py +3 -6
  334. ansible/plugins/action/pause.py +2 -2
  335. ansible/plugins/action/script.py +15 -8
  336. ansible/plugins/action/service.py +6 -11
  337. ansible/plugins/action/set_fact.py +3 -12
  338. ansible/plugins/action/set_stats.py +3 -8
  339. ansible/plugins/action/template.py +35 -59
  340. ansible/plugins/action/unarchive.py +1 -1
  341. ansible/plugins/action/validate_argument_spec.py +5 -5
  342. ansible/plugins/action/wait_for_connection.py +1 -1
  343. ansible/plugins/become/__init__.py +31 -8
  344. ansible/plugins/become/runas.py +71 -0
  345. ansible/plugins/become/su.py +13 -8
  346. ansible/plugins/become/sudo.py +19 -0
  347. ansible/plugins/cache/__init__.py +35 -44
  348. ansible/plugins/cache/base.py +8 -0
  349. ansible/plugins/cache/jsonfile.py +10 -16
  350. ansible/plugins/cache/memory.py +6 -12
  351. ansible/plugins/callback/__init__.py +284 -179
  352. ansible/plugins/callback/default.py +99 -92
  353. ansible/plugins/callback/junit.py +44 -39
  354. ansible/plugins/callback/minimal.py +28 -25
  355. ansible/plugins/callback/oneline.py +28 -21
  356. ansible/plugins/callback/tree.py +16 -11
  357. ansible/plugins/connection/__init__.py +47 -34
  358. ansible/plugins/connection/local.py +150 -54
  359. ansible/plugins/connection/paramiko_ssh.py +21 -18
  360. ansible/plugins/connection/psrp.py +76 -165
  361. ansible/plugins/connection/ssh.py +301 -78
  362. ansible/plugins/connection/winrm.py +58 -140
  363. ansible/plugins/doc_fragments/action_common_attributes.py +14 -14
  364. ansible/plugins/doc_fragments/action_core.py +6 -6
  365. ansible/plugins/doc_fragments/backup.py +2 -2
  366. ansible/plugins/doc_fragments/checksum_common.py +27 -0
  367. ansible/plugins/doc_fragments/constructed.py +6 -2
  368. ansible/plugins/doc_fragments/decrypt.py +2 -2
  369. ansible/plugins/doc_fragments/default_callback.py +2 -2
  370. ansible/plugins/doc_fragments/files.py +2 -2
  371. ansible/plugins/doc_fragments/inventory_cache.py +2 -2
  372. ansible/plugins/doc_fragments/result_format_callback.py +2 -2
  373. ansible/plugins/doc_fragments/return_common.py +2 -2
  374. ansible/plugins/doc_fragments/template_common.py +4 -4
  375. ansible/plugins/doc_fragments/url.py +17 -1
  376. ansible/plugins/doc_fragments/url_windows.py +2 -2
  377. ansible/plugins/doc_fragments/validate.py +2 -2
  378. ansible/plugins/doc_fragments/vars_plugin_staging.py +2 -2
  379. ansible/plugins/filter/__init__.py +6 -2
  380. ansible/plugins/filter/b64decode.yml +22 -0
  381. ansible/plugins/filter/b64encode.yml +22 -0
  382. ansible/plugins/filter/bool.yml +11 -4
  383. ansible/plugins/filter/core.py +225 -108
  384. ansible/plugins/filter/encryption.py +32 -32
  385. ansible/plugins/filter/flatten.yml +3 -2
  386. ansible/plugins/filter/human_to_bytes.yml +1 -1
  387. ansible/plugins/filter/mathstuff.py +30 -37
  388. ansible/plugins/filter/password_hash.yml +8 -0
  389. ansible/plugins/filter/regex_search.yml +1 -4
  390. ansible/plugins/filter/split.yml +1 -1
  391. ansible/plugins/filter/to_nice_yaml.yml +0 -4
  392. ansible/plugins/filter/to_yaml.yml +0 -4
  393. ansible/plugins/filter/unvault.yml +1 -1
  394. ansible/plugins/filter/urls.py +1 -1
  395. ansible/plugins/filter/urlsplit.py +8 -9
  396. ansible/plugins/filter/vault.yml +14 -9
  397. ansible/plugins/filter/win_basename.yml +6 -1
  398. ansible/plugins/filter/win_dirname.yml +5 -0
  399. ansible/plugins/inventory/__init__.py +97 -77
  400. ansible/plugins/inventory/advanced_host_list.py +7 -5
  401. ansible/plugins/inventory/auto.py +11 -4
  402. ansible/plugins/inventory/constructed.py +21 -24
  403. ansible/plugins/inventory/generator.py +16 -11
  404. ansible/plugins/inventory/host_list.py +7 -5
  405. ansible/plugins/inventory/ini.py +78 -44
  406. ansible/plugins/inventory/script.py +189 -119
  407. ansible/plugins/inventory/toml.py +16 -126
  408. ansible/plugins/inventory/yaml.py +10 -8
  409. ansible/plugins/list.py +3 -3
  410. ansible/plugins/loader.py +197 -82
  411. ansible/plugins/lookup/__init__.py +21 -4
  412. ansible/plugins/lookup/config.py +21 -35
  413. ansible/plugins/lookup/csvfile.py +3 -2
  414. ansible/plugins/lookup/dict.py +1 -6
  415. ansible/plugins/lookup/env.py +12 -9
  416. ansible/plugins/lookup/file.py +5 -8
  417. ansible/plugins/lookup/first_found.py +86 -55
  418. ansible/plugins/lookup/indexed_items.py +1 -10
  419. ansible/plugins/lookup/ini.py +14 -13
  420. ansible/plugins/lookup/items.py +1 -1
  421. ansible/plugins/lookup/lines.py +8 -1
  422. ansible/plugins/lookup/list.py +1 -1
  423. ansible/plugins/lookup/nested.py +2 -18
  424. ansible/plugins/lookup/password.py +5 -5
  425. ansible/plugins/lookup/pipe.py +5 -7
  426. ansible/plugins/lookup/sequence.py +18 -8
  427. ansible/plugins/lookup/subelements.py +1 -4
  428. ansible/plugins/lookup/template.py +42 -36
  429. ansible/plugins/lookup/together.py +0 -12
  430. ansible/plugins/lookup/unvault.py +1 -5
  431. ansible/plugins/lookup/url.py +2 -8
  432. ansible/plugins/lookup/vars.py +16 -24
  433. ansible/plugins/shell/__init__.py +2 -2
  434. ansible/plugins/shell/cmd.py +2 -2
  435. ansible/plugins/shell/powershell.py +39 -22
  436. ansible/plugins/shell/sh.py +3 -2
  437. ansible/plugins/strategy/__init__.py +159 -184
  438. ansible/plugins/strategy/debug.py +2 -2
  439. ansible/plugins/strategy/free.py +16 -31
  440. ansible/plugins/strategy/host_pinned.py +2 -2
  441. ansible/plugins/strategy/linear.py +41 -41
  442. ansible/plugins/terminal/__init__.py +4 -4
  443. ansible/plugins/test/__init__.py +7 -2
  444. ansible/plugins/test/core.py +55 -21
  445. ansible/plugins/test/files.py +1 -1
  446. ansible/plugins/test/mathstuff.py +3 -3
  447. ansible/plugins/test/uri.py +3 -3
  448. ansible/plugins/vars/host_group_vars.py +7 -14
  449. ansible/release.py +2 -2
  450. ansible/template/__init__.py +370 -944
  451. ansible/utils/__init__.py +0 -18
  452. ansible/utils/_ssh_agent.py +657 -0
  453. ansible/utils/collection_loader/__init__.py +52 -5
  454. ansible/utils/collection_loader/_collection_config.py +5 -6
  455. ansible/utils/collection_loader/_collection_finder.py +79 -93
  456. ansible/utils/collection_loader/_collection_meta.py +13 -8
  457. ansible/utils/display.py +433 -63
  458. ansible/utils/encrypt.py +27 -19
  459. ansible/utils/fqcn.py +2 -2
  460. ansible/utils/hashing.py +2 -2
  461. ansible/utils/helpers.py +2 -2
  462. ansible/utils/listify.py +8 -8
  463. ansible/utils/lock.py +2 -2
  464. ansible/utils/path.py +4 -4
  465. ansible/utils/plugin_docs.py +14 -13
  466. ansible/utils/sentinel.py +4 -62
  467. ansible/utils/singleton.py +2 -0
  468. ansible/utils/ssh_functions.py +1 -1
  469. ansible/utils/unsafe_proxy.py +23 -332
  470. ansible/utils/vars.py +51 -8
  471. ansible/utils/version.py +2 -2
  472. ansible/vars/clean.py +5 -5
  473. ansible/vars/hostvars.py +60 -90
  474. ansible/vars/manager.py +206 -282
  475. ansible/vars/reserved.py +8 -9
  476. ansible_core-2.19.0b2.dist-info/BSD-3-Clause.txt +28 -0
  477. {ansible_core-2.18.5rc1.dist-info → ansible_core-2.19.0b2.dist-info}/METADATA +5 -4
  478. ansible_core-2.19.0b2.dist-info/RECORD +1072 -0
  479. {ansible_core-2.18.5rc1.dist-info → ansible_core-2.19.0b2.dist-info}/WHEEL +1 -1
  480. ansible_test/_data/completion/docker.txt +7 -7
  481. ansible_test/_data/completion/remote.txt +6 -6
  482. ansible_test/_data/completion/windows.txt +1 -0
  483. ansible_test/_data/requirements/ansible.txt +2 -2
  484. ansible_test/_data/requirements/sanity.ansible-doc.txt +3 -3
  485. ansible_test/_data/requirements/sanity.changelog.txt +1 -1
  486. ansible_test/_data/requirements/sanity.import.plugin.txt +2 -2
  487. ansible_test/_data/requirements/sanity.pylint.txt +4 -4
  488. ansible_test/_data/requirements/sanity.validate-modules.txt +2 -2
  489. ansible_test/_data/requirements/sanity.yamllint.txt +1 -1
  490. ansible_test/_data/requirements/units.txt +1 -0
  491. ansible_test/_internal/__init__.py +1 -0
  492. ansible_test/_internal/ansible_util.py +2 -0
  493. ansible_test/_internal/become.py +1 -0
  494. ansible_test/_internal/bootstrap.py +1 -0
  495. ansible_test/_internal/cache.py +1 -0
  496. ansible_test/_internal/cgroup.py +1 -0
  497. ansible_test/_internal/ci/__init__.py +1 -0
  498. ansible_test/_internal/ci/azp.py +1 -0
  499. ansible_test/_internal/ci/local.py +1 -0
  500. ansible_test/_internal/classification/__init__.py +1 -0
  501. ansible_test/_internal/classification/common.py +1 -0
  502. ansible_test/_internal/classification/csharp.py +1 -0
  503. ansible_test/_internal/classification/powershell.py +1 -0
  504. ansible_test/_internal/classification/python.py +1 -0
  505. ansible_test/_internal/cli/__init__.py +1 -0
  506. ansible_test/_internal/cli/actions.py +1 -0
  507. ansible_test/_internal/cli/argparsing/__init__.py +1 -0
  508. ansible_test/_internal/cli/argparsing/actions.py +1 -0
  509. ansible_test/_internal/cli/argparsing/argcompletion.py +1 -0
  510. ansible_test/_internal/cli/argparsing/parsers.py +1 -0
  511. ansible_test/_internal/cli/commands/__init__.py +11 -0
  512. ansible_test/_internal/cli/commands/coverage/__init__.py +1 -0
  513. ansible_test/_internal/cli/commands/coverage/analyze/__init__.py +1 -0
  514. ansible_test/_internal/cli/commands/coverage/analyze/targets/__init__.py +1 -0
  515. ansible_test/_internal/cli/commands/coverage/analyze/targets/combine.py +1 -0
  516. ansible_test/_internal/cli/commands/coverage/analyze/targets/expand.py +1 -0
  517. ansible_test/_internal/cli/commands/coverage/analyze/targets/filter.py +1 -0
  518. ansible_test/_internal/cli/commands/coverage/analyze/targets/generate.py +1 -0
  519. ansible_test/_internal/cli/commands/coverage/analyze/targets/missing.py +1 -0
  520. ansible_test/_internal/cli/commands/coverage/combine.py +1 -0
  521. ansible_test/_internal/cli/commands/coverage/erase.py +1 -0
  522. ansible_test/_internal/cli/commands/coverage/html.py +1 -0
  523. ansible_test/_internal/cli/commands/coverage/report.py +1 -0
  524. ansible_test/_internal/cli/commands/coverage/xml.py +1 -0
  525. ansible_test/_internal/cli/commands/env.py +1 -0
  526. ansible_test/_internal/cli/commands/integration/__init__.py +1 -0
  527. ansible_test/_internal/cli/commands/integration/network.py +1 -0
  528. ansible_test/_internal/cli/commands/integration/posix.py +1 -0
  529. ansible_test/_internal/cli/commands/integration/windows.py +1 -0
  530. ansible_test/_internal/cli/commands/sanity.py +9 -0
  531. ansible_test/_internal/cli/commands/shell.py +1 -0
  532. ansible_test/_internal/cli/commands/units.py +1 -0
  533. ansible_test/_internal/cli/compat.py +1 -0
  534. ansible_test/_internal/cli/completers.py +1 -0
  535. ansible_test/_internal/cli/converters.py +1 -0
  536. ansible_test/_internal/cli/environments.py +1 -0
  537. ansible_test/_internal/cli/epilog.py +1 -0
  538. ansible_test/_internal/cli/parsers/__init__.py +1 -0
  539. ansible_test/_internal/cli/parsers/base_argument_parsers.py +1 -0
  540. ansible_test/_internal/cli/parsers/helpers.py +1 -0
  541. ansible_test/_internal/cli/parsers/host_config_parsers.py +1 -0
  542. ansible_test/_internal/cli/parsers/key_value_parsers.py +1 -0
  543. ansible_test/_internal/cli/parsers/value_parsers.py +1 -0
  544. ansible_test/_internal/commands/__init__.py +1 -0
  545. ansible_test/_internal/commands/coverage/__init__.py +2 -1
  546. ansible_test/_internal/commands/coverage/analyze/__init__.py +1 -0
  547. ansible_test/_internal/commands/coverage/analyze/targets/__init__.py +1 -0
  548. ansible_test/_internal/commands/coverage/analyze/targets/combine.py +1 -0
  549. ansible_test/_internal/commands/coverage/analyze/targets/expand.py +1 -0
  550. ansible_test/_internal/commands/coverage/analyze/targets/filter.py +1 -0
  551. ansible_test/_internal/commands/coverage/analyze/targets/generate.py +1 -0
  552. ansible_test/_internal/commands/coverage/analyze/targets/missing.py +1 -0
  553. ansible_test/_internal/commands/coverage/combine.py +2 -1
  554. ansible_test/_internal/commands/coverage/erase.py +1 -0
  555. ansible_test/_internal/commands/coverage/html.py +1 -0
  556. ansible_test/_internal/commands/coverage/report.py +1 -0
  557. ansible_test/_internal/commands/coverage/xml.py +1 -0
  558. ansible_test/_internal/commands/env/__init__.py +2 -0
  559. ansible_test/_internal/commands/integration/__init__.py +4 -0
  560. ansible_test/_internal/commands/integration/cloud/__init__.py +1 -0
  561. ansible_test/_internal/commands/integration/cloud/acme.py +2 -1
  562. ansible_test/_internal/commands/integration/cloud/aws.py +1 -0
  563. ansible_test/_internal/commands/integration/cloud/azure.py +1 -0
  564. ansible_test/_internal/commands/integration/cloud/cs.py +1 -0
  565. ansible_test/_internal/commands/integration/cloud/digitalocean.py +1 -0
  566. ansible_test/_internal/commands/integration/cloud/galaxy.py +3 -2
  567. ansible_test/_internal/commands/integration/cloud/hcloud.py +1 -0
  568. ansible_test/_internal/commands/integration/cloud/httptester.py +2 -1
  569. ansible_test/_internal/commands/integration/cloud/nios.py +2 -1
  570. ansible_test/_internal/commands/integration/cloud/opennebula.py +1 -0
  571. ansible_test/_internal/commands/integration/cloud/openshift.py +1 -0
  572. ansible_test/_internal/commands/integration/cloud/scaleway.py +1 -0
  573. ansible_test/_internal/commands/integration/cloud/vcenter.py +1 -0
  574. ansible_test/_internal/commands/integration/cloud/vultr.py +1 -0
  575. ansible_test/_internal/commands/integration/coverage.py +1 -0
  576. ansible_test/_internal/commands/integration/filters.py +1 -0
  577. ansible_test/_internal/commands/integration/network.py +1 -0
  578. ansible_test/_internal/commands/integration/posix.py +1 -0
  579. ansible_test/_internal/commands/integration/windows.py +1 -0
  580. ansible_test/_internal/commands/sanity/__init__.py +16 -1
  581. ansible_test/_internal/commands/sanity/ansible_doc.py +1 -0
  582. ansible_test/_internal/commands/sanity/bin_symlinks.py +1 -0
  583. ansible_test/_internal/commands/sanity/compile.py +1 -0
  584. ansible_test/_internal/commands/sanity/ignores.py +1 -0
  585. ansible_test/_internal/commands/sanity/import.py +1 -0
  586. ansible_test/_internal/commands/sanity/integration_aliases.py +1 -0
  587. ansible_test/_internal/commands/sanity/pep8.py +1 -0
  588. ansible_test/_internal/commands/sanity/pslint.py +1 -0
  589. ansible_test/_internal/commands/sanity/pylint.py +24 -26
  590. ansible_test/_internal/commands/sanity/shellcheck.py +1 -0
  591. ansible_test/_internal/commands/sanity/validate_modules.py +1 -0
  592. ansible_test/_internal/commands/sanity/yamllint.py +1 -0
  593. ansible_test/_internal/commands/shell/__init__.py +1 -0
  594. ansible_test/_internal/commands/units/__init__.py +1 -0
  595. ansible_test/_internal/compat/__init__.py +1 -0
  596. ansible_test/_internal/compat/packaging.py +1 -0
  597. ansible_test/_internal/compat/yaml.py +1 -0
  598. ansible_test/_internal/completion.py +1 -0
  599. ansible_test/_internal/config.py +2 -0
  600. ansible_test/_internal/connections.py +1 -0
  601. ansible_test/_internal/constants.py +1 -0
  602. ansible_test/_internal/containers.py +1 -0
  603. ansible_test/_internal/content_config.py +1 -0
  604. ansible_test/_internal/core_ci.py +1 -0
  605. ansible_test/_internal/coverage_util.py +11 -10
  606. ansible_test/_internal/data.py +1 -0
  607. ansible_test/_internal/delegation.py +1 -0
  608. ansible_test/_internal/dev/__init__.py +1 -0
  609. ansible_test/_internal/dev/container_probe.py +1 -0
  610. ansible_test/_internal/diff.py +3 -2
  611. ansible_test/_internal/docker_util.py +2 -1
  612. ansible_test/_internal/encoding.py +1 -0
  613. ansible_test/_internal/executor.py +1 -0
  614. ansible_test/_internal/git.py +1 -0
  615. ansible_test/_internal/host_configs.py +1 -0
  616. ansible_test/_internal/host_profiles.py +1 -0
  617. ansible_test/_internal/http.py +1 -0
  618. ansible_test/_internal/init.py +1 -0
  619. ansible_test/_internal/inventory.py +35 -3
  620. ansible_test/_internal/io.py +1 -0
  621. ansible_test/_internal/metadata.py +1 -0
  622. ansible_test/_internal/payload.py +1 -0
  623. ansible_test/_internal/provider/__init__.py +1 -0
  624. ansible_test/_internal/provider/layout/__init__.py +1 -0
  625. ansible_test/_internal/provider/layout/ansible.py +1 -0
  626. ansible_test/_internal/provider/layout/collection.py +1 -0
  627. ansible_test/_internal/provider/layout/unsupported.py +1 -0
  628. ansible_test/_internal/provider/source/__init__.py +1 -0
  629. ansible_test/_internal/provider/source/git.py +1 -0
  630. ansible_test/_internal/provider/source/installed.py +1 -0
  631. ansible_test/_internal/provider/source/unsupported.py +1 -0
  632. ansible_test/_internal/provider/source/unversioned.py +1 -0
  633. ansible_test/_internal/provisioning.py +1 -0
  634. ansible_test/_internal/pypi_proxy.py +6 -5
  635. ansible_test/_internal/python_requirements.py +1 -0
  636. ansible_test/_internal/ssh.py +1 -0
  637. ansible_test/_internal/target.py +1 -0
  638. ansible_test/_internal/test.py +3 -2
  639. ansible_test/_internal/thread.py +1 -0
  640. ansible_test/_internal/timeout.py +1 -0
  641. ansible_test/_internal/util.py +1 -0
  642. ansible_test/_internal/util_common.py +5 -2
  643. ansible_test/_internal/venv.py +1 -0
  644. ansible_test/_util/controller/sanity/code-smell/action-plugin-docs.py +1 -0
  645. ansible_test/_util/controller/sanity/code-smell/changelog/sphinx.py +1 -0
  646. ansible_test/_util/controller/sanity/code-smell/changelog.py +1 -0
  647. ansible_test/_util/controller/sanity/code-smell/empty-init.py +1 -0
  648. ansible_test/_util/controller/sanity/code-smell/line-endings.py +1 -0
  649. ansible_test/_util/controller/sanity/code-smell/no-assert.py +1 -0
  650. ansible_test/_util/controller/sanity/code-smell/no-get-exception.py +1 -0
  651. ansible_test/_util/controller/sanity/code-smell/no-illegal-filenames.py +1 -0
  652. ansible_test/_util/controller/sanity/code-smell/no-smart-quotes.py +1 -0
  653. ansible_test/_util/controller/sanity/code-smell/replace-urlopen.py +1 -0
  654. ansible_test/_util/controller/sanity/code-smell/runtime-metadata.py +28 -1
  655. ansible_test/_util/controller/sanity/code-smell/shebang.py +1 -0
  656. ansible_test/_util/controller/sanity/code-smell/symlinks.py +1 -0
  657. ansible_test/_util/controller/sanity/code-smell/use-argspec-type-path.py +1 -0
  658. ansible_test/_util/controller/sanity/code-smell/use-compat-six.py +1 -0
  659. ansible_test/_util/controller/sanity/integration-aliases/yaml_to_json.py +2 -1
  660. ansible_test/_util/controller/sanity/pep8/current-ignore.txt +4 -0
  661. ansible_test/_util/controller/sanity/pylint/config/ansible-test-target.cfg +7 -5
  662. ansible_test/_util/controller/sanity/pylint/config/ansible-test.cfg +7 -5
  663. ansible_test/_util/controller/sanity/pylint/config/code-smell.cfg +7 -5
  664. ansible_test/_util/controller/sanity/pylint/config/collection.cfg +3 -5
  665. ansible_test/_util/controller/sanity/pylint/config/default.cfg +7 -7
  666. ansible_test/_util/controller/sanity/pylint/plugins/deprecated.py +1 -13
  667. ansible_test/_util/controller/sanity/pylint/plugins/hide_unraisable.py +1 -0
  668. ansible_test/_util/controller/sanity/pylint/plugins/string_format.py +1 -8
  669. ansible_test/_util/controller/sanity/pylint/plugins/unwanted.py +1 -8
  670. ansible_test/_util/controller/sanity/validate-modules/validate_modules/main.py +55 -28
  671. ansible_test/_util/controller/sanity/validate-modules/validate_modules/module_args.py +12 -5
  672. ansible_test/_util/controller/sanity/validate-modules/validate_modules/schema.py +13 -2
  673. ansible_test/_util/controller/sanity/validate-modules/validate_modules/utils.py +1 -0
  674. ansible_test/_util/controller/sanity/yamllint/yamllinter.py +35 -17
  675. ansible_test/_util/controller/tools/collection_detail.py +1 -0
  676. ansible_test/_util/controller/tools/yaml_to_json.py +2 -1
  677. ansible_test/_util/target/pytest/plugins/ansible_forked.py +6 -1
  678. ansible_test/_util/target/pytest/plugins/ansible_pytest_collections.py +2 -1
  679. ansible_test/_util/target/pytest/plugins/ansible_pytest_coverage.py +1 -0
  680. ansible_test/_util/target/sanity/compile/compile.py +1 -0
  681. ansible_test/_util/target/sanity/import/importer.py +15 -16
  682. ansible_test/_util/target/setup/bootstrap.sh +9 -20
  683. ansible_test/_util/target/setup/probe_cgroups.py +1 -0
  684. ansible_test/_util/target/setup/quiet_pip.py +1 -0
  685. ansible_test/_util/target/setup/requirements.py +35 -27
  686. ansible_test/_util/target/tools/virtualenvcheck.py +2 -1
  687. ansible_test/_util/target/tools/yamlcheck.py +2 -1
  688. ansible/compat/selectors.py +0 -32
  689. ansible/errors/yaml_strings.py +0 -138
  690. ansible/executor/action_write_locks.py +0 -44
  691. ansible/executor/discovery/python_target.py +0 -47
  692. ansible/executor/powershell/module_powershell_wrapper.ps1 +0 -86
  693. ansible/executor/powershell/module_script_wrapper.ps1 +0 -22
  694. ansible/module_utils/compat/importlib.py +0 -26
  695. ansible/module_utils/compat/selectors.py +0 -32
  696. ansible/module_utils/pycompat24.py +0 -73
  697. ansible/parsing/yaml/constructor.py +0 -178
  698. ansible/template/native_helpers.py +0 -251
  699. ansible/template/template.py +0 -43
  700. ansible/template/vars.py +0 -77
  701. ansible/utils/native_jinja.py +0 -11
  702. ansible/vars/fact_cache.py +0 -71
  703. ansible_core-2.18.5rc1.dist-info/RECORD +0 -992
  704. {ansible_core-2.18.5rc1.dist-info → ansible_core-2.19.0b2.dist-info}/Apache-License.txt +0 -0
  705. {ansible_core-2.18.5rc1.dist-info → ansible_core-2.19.0b2.dist-info}/COPYING +0 -0
  706. {ansible_core-2.18.5rc1.dist-info → ansible_core-2.19.0b2.dist-info}/MIT-license.txt +0 -0
  707. {ansible_core-2.18.5rc1.dist-info → ansible_core-2.19.0b2.dist-info}/PSF-license.txt +0 -0
  708. {ansible_core-2.18.5rc1.dist-info → ansible_core-2.19.0b2.dist-info}/entry_points.txt +0 -0
  709. {ansible_core-2.18.5rc1.dist-info → ansible_core-2.19.0b2.dist-info}/simplified_bsd.txt +0 -0
  710. {ansible_core-2.18.5rc1.dist-info → ansible_core-2.19.0b2.dist-info}/top_level.txt +0 -0
@@ -160,7 +160,7 @@ def _read_password_file(b_path):
160
160
 
161
161
 
162
162
  def _gen_candidate_chars(characters):
163
- '''Generate a string containing all valid chars as defined by ``characters``
163
+ """Generate a string containing all valid chars as defined by ``characters``
164
164
 
165
165
  :arg characters: A list of character specs. The character specs are
166
166
  shorthand names for sets of characters like 'digits', 'ascii_letters',
@@ -181,7 +181,7 @@ def _gen_candidate_chars(characters):
181
181
  the question mark and pipe characters directly. Return will be the string::
182
182
 
183
183
  u'0123456789?|'
184
- '''
184
+ """
185
185
  chars = []
186
186
  for chars_spec in characters:
187
187
  # getattr from string expands things like "ascii_letters" and "digits"
@@ -192,11 +192,11 @@ def _gen_candidate_chars(characters):
192
192
 
193
193
 
194
194
  def _parse_content(content):
195
- '''parse our password data format into password and salt
195
+ """parse our password data format into password and salt
196
196
 
197
197
  :arg content: The data read from the file
198
198
  :returns: password and salt
199
- '''
199
+ """
200
200
  password = content
201
201
  salt = None
202
202
  ident = None
@@ -350,7 +350,7 @@ class LookupModule(LookupBase):
350
350
 
351
351
  return relpath, params
352
352
 
353
- def run(self, terms, variables, **kwargs):
353
+ def run(self, terms, variables=None, **kwargs):
354
354
  ret = []
355
355
 
356
356
  for term in terms:
@@ -15,14 +15,12 @@ DOCUMENTATION = r"""
15
15
  description: command(s) to run.
16
16
  required: True
17
17
  notes:
18
+ - The given command is passed to a shell for execution, therefore all variables that are part of the command and
19
+ come from a remote/untrusted source MUST be sanitized using the P(ansible.builtin.quote#filter) filter to avoid
20
+ shell injection vulnerabilities. See the example section.
18
21
  - Like all lookups this runs on the Ansible controller and is unaffected by other keywords, such as become,
19
22
  so if you need to different permissions you must change the command or run Ansible as another user.
20
23
  - Alternatively you can use a shell/command task that runs against localhost and registers the result.
21
- - Pipe lookup internally invokes Popen with shell=True (this is required and intentional).
22
- This type of invocation is considered a security issue if appropriate care is not taken to sanitize any user provided or variable input.
23
- It is strongly recommended to pass user input or variable input via quote filter before using with pipe lookup.
24
- See example section for this.
25
- Read more about this L(Bandit B602 docs,https://bandit.readthedocs.io/en/latest/plugins/b602_subprocess_popen_with_shell_equals_true.html)
26
24
  - The directory of the play is used as the current working directory.
27
25
  """
28
26
 
@@ -52,7 +50,7 @@ from ansible.plugins.lookup import LookupBase
52
50
 
53
51
  class LookupModule(LookupBase):
54
52
 
55
- def run(self, terms, variables, **kwargs):
53
+ def run(self, terms, variables=None, **kwargs):
56
54
 
57
55
  ret = []
58
56
  for term in terms:
@@ -65,7 +63,7 @@ class LookupModule(LookupBase):
65
63
  # https://github.com/ansible/ansible/issues/6550
66
64
  term = str(term)
67
65
 
68
- p = subprocess.Popen(term, cwd=self._loader.get_basedir(), shell=True, stdin=subprocess.PIPE, stdout=subprocess.PIPE)
66
+ p = subprocess.Popen(term, cwd=self._templar.basedir, shell=True, stdin=subprocess.PIPE, stdout=subprocess.PIPE)
69
67
  (stdout, stderr) = p.communicate()
70
68
  if p.returncode == 0:
71
69
  ret.append(stdout.decode("utf-8").rstrip())
@@ -171,6 +171,12 @@ class LookupModule(LookupBase):
171
171
  setattr(self, f, self.get_option(f))
172
172
 
173
173
  def sanity_check(self):
174
+ """
175
+ Returns True if options comprise a valid sequence expression
176
+ Raises AnsibleError if options are an invalid expression
177
+ Returns false if options are valid but result in an empty sequence - these cases do not raise exceptions
178
+ in order to maintain historic behavior
179
+ """
174
180
  if self.count is None and self.end is None:
175
181
  raise AnsibleError("must specify count or end in with_sequence")
176
182
  elif self.count is not None and self.end is not None:
@@ -180,17 +186,18 @@ class LookupModule(LookupBase):
180
186
  if self.count != 0:
181
187
  self.end = self.start + self.count * self.stride - 1
182
188
  else:
183
- self.start = 0
184
- self.end = 0
185
- self.stride = 0
186
- del self.count
189
+ return False
187
190
  if self.stride > 0 and self.end < self.start:
188
191
  raise AnsibleError("to count backwards make stride negative")
189
192
  if self.stride < 0 and self.end > self.start:
190
193
  raise AnsibleError("to count forward don't make stride negative")
194
+ if self.stride == 0:
195
+ return False
191
196
  if self.format.count('%') != 1:
192
197
  raise AnsibleError("bad formatting string: %s" % self.format)
193
198
 
199
+ return True
200
+
194
201
  def generate_sequence(self):
195
202
  if self.stride >= 0:
196
203
  adjust = 1
@@ -207,9 +214,13 @@ class LookupModule(LookupBase):
207
214
  "problem formatting %r with %r" % (i, self.format)
208
215
  )
209
216
 
210
- def run(self, terms, variables, **kwargs):
217
+ def run(self, terms, variables=None, **kwargs):
211
218
  results = []
212
219
 
220
+ if kwargs and not terms:
221
+ # All of the necessary arguments can be provided as keywords, but we still need something to loop over
222
+ terms = ['']
223
+
213
224
  for term in terms:
214
225
  try:
215
226
  # set defaults/global
@@ -223,10 +234,9 @@ class LookupModule(LookupBase):
223
234
  raise AnsibleError("unknown error parsing with_sequence arguments: %r. Error was: %s" % (term, e))
224
235
 
225
236
  self.set_fields()
226
- self.sanity_check()
227
-
228
- if self.stride != 0:
237
+ if self.sanity_check():
229
238
  results.extend(self.generate_sequence())
239
+
230
240
  except AnsibleError:
231
241
  raise
232
242
  except Exception as e:
@@ -86,7 +86,6 @@ from ansible.errors import AnsibleError
86
86
  from ansible.module_utils.six import string_types
87
87
  from ansible.module_utils.parsing.convert_bool import boolean
88
88
  from ansible.plugins.lookup import LookupBase
89
- from ansible.utils.listify import listify_lookup_plugin_terms
90
89
 
91
90
 
92
91
  FLAGS = ('skip_missing',)
@@ -94,14 +93,12 @@ FLAGS = ('skip_missing',)
94
93
 
95
94
  class LookupModule(LookupBase):
96
95
 
97
- def run(self, terms, variables, **kwargs):
96
+ def run(self, terms, variables=None, **kwargs):
98
97
 
99
98
  def _raise_terms_error(msg=""):
100
99
  raise AnsibleError(
101
100
  "subelements lookup expects a list of two or three items, " + msg)
102
101
 
103
- terms[0] = listify_lookup_plugin_terms(terms[0], templar=self._templar)
104
-
105
102
  # check lookup terms - check number of terms
106
103
  if not isinstance(terms, list) or not 2 <= len(terms) <= 3:
107
104
  _raise_terms_error()
@@ -17,9 +17,13 @@ DOCUMENTATION = """
17
17
  convert_data:
18
18
  type: bool
19
19
  description:
20
- - Whether to convert YAML into data. If False, strings that are YAML will be left untouched.
21
- - Mutually exclusive with the jinja2_native option.
20
+ - Whether to convert YAML into data. If V(False), strings that are YAML will be left untouched.
21
+ - Mutually exclusive with the O(jinja2_native) option.
22
22
  default: true
23
+ deprecated:
24
+ why: This option is no longer used in the Ansible Core code base.
25
+ version: "2.21"
26
+ alternatives: Jinja2 native mode is now the default and only option, which is mutually exclusive with this option.
23
27
  variable_start_string:
24
28
  description: The string marking the beginning of a print statement.
25
29
  default: '{{'
@@ -33,13 +37,16 @@ DOCUMENTATION = """
33
37
  jinja2_native:
34
38
  description:
35
39
  - Controls whether to use Jinja2 native types.
36
- - It is off by default even if global jinja2_native is True.
37
- - Has no effect if global jinja2_native is False.
40
+ - It is off by default even if global O(jinja2_native) is V(True).
41
+ - Has no effect if global O(jinja2_native) is V(False).
38
42
  - This offers more flexibility than the template module which does not use Jinja2 native types at all.
39
- - Mutually exclusive with the convert_data option.
40
- default: False
43
+ default: True
41
44
  version_added: '2.11'
42
45
  type: bool
46
+ deprecated:
47
+ why: This option is no longer used in the Ansible Core code base.
48
+ version: "2.21"
49
+ alternatives: Jinja2 native mode is now the default and only option.
43
50
  template_vars:
44
51
  description: A dictionary, the keys become additional variables available for templating.
45
52
  default: {}
@@ -55,6 +62,13 @@ DOCUMENTATION = """
55
62
  version_added: '2.12'
56
63
  type: str
57
64
  default: '#}'
65
+ trim_blocks:
66
+ description:
67
+ - Determine when newlines should be removed from blocks.
68
+ - When set to V(yes) the first newline after a block is removed (block, not variable tag!).
69
+ type: bool
70
+ default: yes
71
+ version_added: '2.19'
58
72
  seealso:
59
73
  - ref: playbook_task_paths
60
74
  description: Search paths used for relative templates.
@@ -72,6 +86,11 @@ EXAMPLES = """
72
86
  - name: show templating results with different comment start and end string
73
87
  ansible.builtin.debug:
74
88
  msg: "{{ lookup('ansible.builtin.template', './some_template.j2', comment_start_string='[#', comment_end_string='#]') }}"
89
+
90
+ - name: show templating results with trim_blocks
91
+ ansible.builtin.debug:
92
+ msg: "{{ lookup('ansible.builtin.template', './some_template.j2', trim_blocks=True) }}"
93
+
75
94
  """
76
95
 
77
96
  RETURN = """
@@ -84,14 +103,10 @@ _raw:
84
103
  from copy import deepcopy
85
104
  import os
86
105
 
87
- import ansible.constants as C
88
-
89
106
  from ansible.errors import AnsibleError
90
107
  from ansible.plugins.lookup import LookupBase
91
- from ansible.module_utils.common.text.converters import to_text
92
- from ansible.template import generate_ansible_template_vars, AnsibleEnvironment
108
+ from ansible.template import generate_ansible_template_vars, trust_as_template
93
109
  from ansible.utils.display import Display
94
- from ansible.utils.native_jinja import NativeJinjaText
95
110
 
96
111
 
97
112
  display = Display()
@@ -99,25 +114,21 @@ display = Display()
99
114
 
100
115
  class LookupModule(LookupBase):
101
116
 
102
- def run(self, terms, variables, **kwargs):
117
+ def run(self, terms, variables=None, **kwargs):
103
118
 
104
119
  ret = []
105
120
 
106
121
  self.set_options(var_options=variables, direct=kwargs)
107
122
 
108
123
  # capture options
109
- convert_data_p = self.get_option('convert_data')
110
124
  lookup_template_vars = self.get_option('template_vars')
111
- jinja2_native = self.get_option('jinja2_native') and C.DEFAULT_JINJA2_NATIVE
112
125
  variable_start_string = self.get_option('variable_start_string')
113
126
  variable_end_string = self.get_option('variable_end_string')
114
127
  comment_start_string = self.get_option('comment_start_string')
115
128
  comment_end_string = self.get_option('comment_end_string')
129
+ trim_blocks = self.get_option('trim_blocks')
116
130
 
117
- if jinja2_native:
118
- templar = self._templar
119
- else:
120
- templar = self._templar.copy_with_new_env(environment_class=AnsibleEnvironment)
131
+ templar = self._templar
121
132
 
122
133
  for term in terms:
123
134
  display.debug("File lookup term: %s" % term)
@@ -125,8 +136,7 @@ class LookupModule(LookupBase):
125
136
  lookupfile = self.find_file_in_search_path(variables, 'templates', term)
126
137
  display.vvvv("File lookup using %s as file" % lookupfile)
127
138
  if lookupfile:
128
- b_template_data, show_data = self._loader._get_file_contents(lookupfile)
129
- template_data = to_text(b_template_data, errors='surrogate_or_strict')
139
+ template_data = trust_as_template(self._loader.get_text_file_contents(lookupfile))
130
140
 
131
141
  # set jinja2 internal search path for includes
132
142
  searchpath = variables.get('ansible_search_path', [])
@@ -145,25 +155,21 @@ class LookupModule(LookupBase):
145
155
  # plus some added by ansible (e.g., template_{path,mtime}),
146
156
  # plus anything passed to the lookup with the template_vars=
147
157
  # argument.
158
+ # FIXME: why isn't this a chainmap with a sacrificial bottom layer?
148
159
  vars = deepcopy(variables)
149
- vars.update(generate_ansible_template_vars(term, lookupfile))
160
+ vars.update(generate_ansible_template_vars(term, fullpath=lookupfile))
150
161
  vars.update(lookup_template_vars)
151
162
 
152
- with templar.set_temporary_context(available_variables=vars, searchpath=searchpath):
153
- overrides = dict(
154
- variable_start_string=variable_start_string,
155
- variable_end_string=variable_end_string,
156
- comment_start_string=comment_start_string,
157
- comment_end_string=comment_end_string
158
- )
159
- res = templar.template(template_data, preserve_trailing_newlines=True,
160
- convert_data=convert_data_p, escape_backslashes=False,
161
- overrides=overrides)
162
-
163
- if (C.DEFAULT_JINJA2_NATIVE and not jinja2_native) or not convert_data_p:
164
- # jinja2_native is true globally but off for the lookup, we need this text
165
- # not to be processed by literal_eval anywhere in Ansible
166
- res = NativeJinjaText(res)
163
+ overrides = dict(
164
+ variable_start_string=variable_start_string,
165
+ variable_end_string=variable_end_string,
166
+ comment_start_string=comment_start_string,
167
+ comment_end_string=comment_end_string,
168
+ trim_blocks=trim_blocks,
169
+ )
170
+
171
+ data_templar = templar.copy_with_new_env(available_variables=vars, searchpath=searchpath)
172
+ res = data_templar.template(template_data, escape_backslashes=False, overrides=overrides)
167
173
 
168
174
  ret.append(res)
169
175
  else:
@@ -38,7 +38,6 @@ import itertools
38
38
 
39
39
  from ansible.errors import AnsibleError
40
40
  from ansible.plugins.lookup import LookupBase
41
- from ansible.utils.listify import listify_lookup_plugin_terms
42
41
 
43
42
 
44
43
  class LookupModule(LookupBase):
@@ -48,18 +47,7 @@ class LookupModule(LookupBase):
48
47
  Replace any empty spots in 2nd array with None:
49
48
  [1, 2], [3] -> [1, 3], [2, None]
50
49
  """
51
-
52
- def _lookup_variables(self, terms):
53
- results = []
54
- for x in terms:
55
- intermediate = listify_lookup_plugin_terms(x, templar=self._templar)
56
- results.append(intermediate)
57
- return results
58
-
59
50
  def run(self, terms, variables=None, **kwargs):
60
-
61
- terms = self._lookup_variables(terms)
62
-
63
51
  my_list = terms[:]
64
52
  if len(my_list) == 0:
65
53
  raise AnsibleError("with_together requires at least one element in each list")
@@ -34,7 +34,6 @@ RETURN = """
34
34
 
35
35
  from ansible.errors import AnsibleParserError
36
36
  from ansible.plugins.lookup import LookupBase
37
- from ansible.module_utils.common.text.converters import to_text
38
37
  from ansible.utils.display import Display
39
38
 
40
39
  display = Display()
@@ -55,10 +54,7 @@ class LookupModule(LookupBase):
55
54
  lookupfile = self.find_file_in_search_path(variables, 'files', term)
56
55
  display.vvvv(u"Unvault lookup found %s" % lookupfile)
57
56
  if lookupfile:
58
- actual_file = self._loader.get_real_file(lookupfile, decrypt=True)
59
- with open(actual_file, 'rb') as f:
60
- b_contents = f.read()
61
- ret.append(to_text(b_contents))
57
+ ret.append(self._loader.get_text_file_contents(lookupfile))
62
58
  else:
63
59
  raise AnsibleParserError('Unable to find file matching "%s" ' % term)
64
60
 
@@ -87,7 +87,6 @@ options:
87
87
  - section: url_lookup
88
88
  key: force_basic_auth
89
89
  follow_redirects:
90
- description: String of urllib2, all/yes, safe, none to determine how redirects are followed
91
90
  type: string
92
91
  version_added: "2.10"
93
92
  default: 'urllib2'
@@ -98,13 +97,6 @@ options:
98
97
  ini:
99
98
  - section: url_lookup
100
99
  key: follow_redirects
101
- choices:
102
- all: Will follow all redirects.
103
- none: Will not follow any redirects.
104
- safe: Only redirects doing GET or HEAD requests will be followed.
105
- urllib2: Defer to urllib2 behavior (As of writing this follows HTTP redirects).
106
- 'no': (DEPRECATED, removed in 2.22) alias of V(none).
107
- 'yes': (DEPRECATED, removed in 2.22) alias of V(all).
108
100
  use_gssapi:
109
101
  description:
110
102
  - Use GSSAPI handler of requests
@@ -185,6 +177,8 @@ options:
185
177
  ini:
186
178
  - section: url_lookup
187
179
  key: ciphers
180
+ extends_documentation_fragment:
181
+ - url.url_redirect
188
182
  """
189
183
 
190
184
  EXAMPLES = """
@@ -73,40 +73,32 @@ _value:
73
73
  elements: raw
74
74
  """
75
75
 
76
- from ansible.errors import AnsibleError, AnsibleUndefinedVariable
77
- from ansible.module_utils.six import string_types
76
+ from ansible.errors import AnsibleTypeError
78
77
  from ansible.plugins.lookup import LookupBase
78
+ from ansible.module_utils.datatag import native_type_name
79
+ from ansible._internal._templating import _jinja_bits
79
80
 
80
81
 
81
82
  class LookupModule(LookupBase):
82
-
83
- def run(self, terms, variables=None, **kwargs):
84
- if variables is not None:
85
- self._templar.available_variables = variables
86
- myvars = getattr(self._templar, '_available_variables', {})
87
-
83
+ def run(self, terms, variables, **kwargs):
88
84
  self.set_options(var_options=variables, direct=kwargs)
85
+
89
86
  default = self.get_option('default')
90
87
 
91
88
  ret = []
89
+
92
90
  for term in terms:
93
- if not isinstance(term, string_types):
94
- raise AnsibleError('Invalid setting identifier, "%s" is not a string, its a %s' % (term, type(term)))
91
+ if not isinstance(term, str):
92
+ raise AnsibleTypeError(f'Variable name must be {native_type_name(str)!r} not {native_type_name(term)!r}.', obj=term)
95
93
 
96
94
  try:
97
- try:
98
- value = myvars[term]
99
- except KeyError:
100
- try:
101
- value = myvars['hostvars'][myvars['inventory_hostname']][term]
102
- except KeyError:
103
- raise AnsibleUndefinedVariable('No variable found with this name: %s' % term)
104
-
105
- ret.append(self._templar.template(value, fail_on_undefined=True))
106
- except AnsibleUndefinedVariable:
107
- if default is not None:
108
- ret.append(default)
95
+ value = variables[term]
96
+ except KeyError:
97
+ if default is None:
98
+ value = _jinja_bits._undef(f'No variable named {term!r} was found.')
109
99
  else:
110
- raise
100
+ value = default
101
+
102
+ ret.append(value)
111
103
 
112
- return ret
104
+ return self._templar._engine.template(ret)
@@ -164,7 +164,7 @@ class ShellBase(AnsiblePlugin):
164
164
  return cmd
165
165
 
166
166
  def expand_user(self, user_home_path, username=''):
167
- ''' Return a command to expand tildes in a path
167
+ """ Return a command to expand tildes in a path
168
168
 
169
169
  It can be either "~" or "~username". We just ignore $HOME
170
170
  We use the POSIX definition of a username:
@@ -172,7 +172,7 @@ class ShellBase(AnsiblePlugin):
172
172
  http://pubs.opengroup.org/onlinepubs/000095399/basedefs/xbd_chap03.html#tag_03_276
173
173
 
174
174
  Falls back to 'current working directory' as we assume 'home is where the remote user ends up'
175
- '''
175
+ """
176
176
 
177
177
  # Check that the user_path to expand is safe
178
178
  if user_home_path != '~':
@@ -2,7 +2,7 @@
2
2
  # GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
3
3
  from __future__ import annotations
4
4
 
5
- DOCUMENTATION = '''
5
+ DOCUMENTATION = """
6
6
  name: cmd
7
7
  version_added: '2.8'
8
8
  short_description: Windows Command Prompt
@@ -10,7 +10,7 @@ description:
10
10
  - Used with the 'ssh' connection plugin and no C(DefaultShell) has been set on the Windows host.
11
11
  extends_documentation_fragment:
12
12
  - shell_windows
13
- '''
13
+ """
14
14
 
15
15
  import re
16
16
 
@@ -3,7 +3,7 @@
3
3
  # GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
4
4
  from __future__ import annotations
5
5
 
6
- DOCUMENTATION = '''
6
+ DOCUMENTATION = """
7
7
  name: powershell
8
8
  version_added: historical
9
9
  short_description: Windows PowerShell
@@ -12,16 +12,16 @@ description:
12
12
  - Can also be used when using 'ssh' as a connection plugin and the C(DefaultShell) has been configured to PowerShell.
13
13
  extends_documentation_fragment:
14
14
  - shell_windows
15
- '''
15
+ """
16
16
 
17
17
  import base64
18
18
  import os
19
19
  import re
20
20
  import shlex
21
- import pkgutil
22
21
  import xml.etree.ElementTree as ET
23
22
  import ntpath
24
23
 
24
+ from ansible.executor.powershell.module_manifest import _get_powershell_script
25
25
  from ansible.module_utils.common.text.converters import to_bytes, to_text
26
26
  from ansible.plugins.shell import ShellBase
27
27
 
@@ -221,9 +221,9 @@ class ShellModule(ShellBase):
221
221
  def remove(self, path, recurse=False):
222
222
  path = self._escape(self._unquote(path))
223
223
  if recurse:
224
- return self._encode_script('''Remove-Item '%s' -Force -Recurse;''' % path)
224
+ return self._encode_script("""Remove-Item '%s' -Force -Recurse;""" % path)
225
225
  else:
226
- return self._encode_script('''Remove-Item '%s' -Force;''' % path)
226
+ return self._encode_script("""Remove-Item '%s' -Force;""" % path)
227
227
 
228
228
  def mkdtemp(self, basefile=None, system=False, mode=None, tmpdir=None):
229
229
  # Windows does not have an equivalent for the system temp files, so
@@ -233,12 +233,12 @@ class ShellModule(ShellBase):
233
233
  basefile = self._escape(self._unquote(basefile))
234
234
  basetmpdir = self._escape(tmpdir if tmpdir else self.get_option('remote_tmp'))
235
235
 
236
- script = f'''
236
+ script = f"""
237
237
  {self._CONSOLE_ENCODING}
238
238
  $tmp_path = [System.Environment]::ExpandEnvironmentVariables('{basetmpdir}')
239
239
  $tmp = New-Item -Type Directory -Path $tmp_path -Name '{basefile}'
240
240
  Write-Output -InputObject $tmp.FullName
241
- '''
241
+ """
242
242
  return self._encode_script(script.strip())
243
243
 
244
244
  def expand_user(self, user_home_path, username=''):
@@ -256,7 +256,7 @@ class ShellModule(ShellBase):
256
256
 
257
257
  def exists(self, path):
258
258
  path = self._escape(self._unquote(path))
259
- script = '''
259
+ script = """
260
260
  If (Test-Path '%s')
261
261
  {
262
262
  $res = 0;
@@ -267,12 +267,12 @@ class ShellModule(ShellBase):
267
267
  }
268
268
  Write-Output '$res';
269
269
  Exit $res;
270
- ''' % path
270
+ """ % path
271
271
  return self._encode_script(script)
272
272
 
273
273
  def checksum(self, path, *args, **kwargs):
274
274
  path = self._escape(self._unquote(path))
275
- script = '''
275
+ script = """
276
276
  If (Test-Path -PathType Leaf '%(path)s')
277
277
  {
278
278
  $sp = new-object -TypeName System.Security.Cryptography.SHA1CryptoServiceProvider;
@@ -288,11 +288,11 @@ class ShellModule(ShellBase):
288
288
  {
289
289
  Write-Output "1";
290
290
  }
291
- ''' % dict(path=path)
291
+ """ % dict(path=path)
292
292
  return self._encode_script(script)
293
293
 
294
294
  def build_module_command(self, env_string, shebang, cmd, arg_path=None):
295
- bootstrap_wrapper = pkgutil.get_data("ansible.executor.powershell", "bootstrap_wrapper.ps1")
295
+ bootstrap_wrapper = _get_powershell_script("bootstrap_wrapper.ps1")
296
296
 
297
297
  # pipelining bypass
298
298
  if cmd == '':
@@ -303,18 +303,35 @@ class ShellModule(ShellBase):
303
303
  cmd_parts = shlex.split(cmd, posix=False)
304
304
  cmd_parts = list(map(to_text, cmd_parts))
305
305
  if shebang and shebang.lower() == '#!powershell':
306
- if not self._unquote(cmd_parts[0]).lower().endswith('.ps1'):
307
- # we're running a module via the bootstrap wrapper
308
- cmd_parts[0] = '"%s.ps1"' % self._unquote(cmd_parts[0])
309
- wrapper_cmd = "type " + cmd_parts[0] + " | " + self._encode_script(script=bootstrap_wrapper, strict_mode=False, preserve_rc=False)
310
- return wrapper_cmd
306
+ if arg_path:
307
+ # Running a module without the exec_wrapper and with an argument
308
+ # file.
309
+ script_path = self._unquote(cmd_parts[0])
310
+ if not script_path.lower().endswith('.ps1'):
311
+ script_path += '.ps1'
312
+
313
+ cmd_parts.insert(0, '-File')
314
+ cmd_parts[1] = f'"{script_path}"'
315
+ if arg_path:
316
+ cmd_parts.append(f'"{arg_path}"')
317
+
318
+ wrapper_cmd = " ".join(_common_args + cmd_parts)
319
+ return wrapper_cmd
320
+
321
+ else:
322
+ # Running a module with ANSIBLE_KEEP_REMOTE_FILES=true, the script
323
+ # arg is actually the input manifest JSON to provide to the bootstrap
324
+ # wrapper.
325
+ wrapper_cmd = "type " + cmd_parts[0] + " | " + self._encode_script(script=bootstrap_wrapper, strict_mode=False, preserve_rc=False)
326
+ return wrapper_cmd
327
+
311
328
  elif shebang and shebang.startswith('#!'):
312
329
  cmd_parts.insert(0, shebang[2:])
313
330
  elif not shebang:
314
331
  # The module is assumed to be a binary
315
332
  cmd_parts[0] = self._unquote(cmd_parts[0])
316
333
  cmd_parts.append(arg_path)
317
- script = '''
334
+ script = """
318
335
  Try
319
336
  {
320
337
  %s
@@ -349,14 +366,14 @@ class ShellModule(ShellBase):
349
366
  Echo $_obj | ConvertTo-Json -Compress -Depth 99
350
367
  Exit 1
351
368
  }
352
- ''' % (env_string, ' '.join(cmd_parts))
369
+ """ % (env_string, ' '.join(cmd_parts))
353
370
  return self._encode_script(script, preserve_rc=False)
354
371
 
355
372
  def wrap_for_exec(self, cmd):
356
373
  return '& %s; exit $LASTEXITCODE' % cmd
357
374
 
358
375
  def _unquote(self, value):
359
- '''Remove any matching quotes that wrap the given value.'''
376
+ """Remove any matching quotes that wrap the given value."""
360
377
  value = to_text(value or '')
361
378
  m = re.match(r'^\s*?\'(.*?)\'\s*?$', value)
362
379
  if m:
@@ -367,13 +384,13 @@ class ShellModule(ShellBase):
367
384
  return value
368
385
 
369
386
  def _escape(self, value):
370
- '''Return value escaped for use in PowerShell single quotes.'''
387
+ """Return value escaped for use in PowerShell single quotes."""
371
388
  # There are 5 chars that need to be escaped in a single quote.
372
389
  # https://github.com/PowerShell/PowerShell/blob/b7cb335f03fe2992d0cbd61699de9d9aafa1d7c1/src/System.Management.Automation/engine/parser/CharTraits.cs#L265-L272
373
390
  return re.compile(u"(['\u2018\u2019\u201a\u201b])").sub(u'\\1\\1', value)
374
391
 
375
392
  def _encode_script(self, script, as_list=False, strict_mode=True, preserve_rc=True):
376
- '''Convert a PowerShell script to a single base64-encoded command.'''
393
+ """Convert a PowerShell script to a single base64-encoded command."""
377
394
  script = to_text(script)
378
395
 
379
396
  if script == u'-':