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
@@ -1,238 +1,504 @@
1
- # (c) 2018 Ansible Project
1
+ # (c) 2025 Ansible Project
2
2
  # GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
3
3
 
4
+ using namespace System.Collections
5
+ using namespace System.Collections.Generic
6
+ using namespace System.Diagnostics.CodeAnalysis
7
+ using namespace System.IO
8
+ using namespace System.Linq
9
+ using namespace System.Management.Automation
10
+ using namespace System.Management.Automation.Language
11
+ using namespace System.Management.Automation.Security
12
+ using namespace System.Security.Cryptography
13
+ using namespace System.Text
14
+
15
+ [SuppressMessageAttribute(
16
+ "PSUseCmdletCorrectly",
17
+ "",
18
+ Justification = "ConvertFrom-Json is being used in a steppable pipeline and works this way."
19
+ )]
20
+ [CmdletBinding()]
21
+ param (
22
+ [Parameter(ValueFromPipeline)]
23
+ [string]
24
+ $InputObject,
25
+
26
+ [Parameter()]
27
+ [IDictionary]
28
+ $Manifest,
29
+
30
+ [Parameter()]
31
+ [switch]
32
+ $EncodeInputOutput,
33
+
34
+ [Parameter()]
35
+ [Version]
36
+ $MinOSVersion,
37
+
38
+ [Parameter()]
39
+ [Version]
40
+ $MinPSVersion,
41
+
42
+ [Parameter()]
43
+ [string]
44
+ $TempPath,
45
+
46
+ [Parameter()]
47
+ [PSObject]
48
+ $ActionParameters
49
+ )
50
+
4
51
  begin {
5
- $DebugPreference = "Continue"
6
- $ProgressPreference = "SilentlyContinue"
52
+ $DebugPreference = "SilentlyContinue"
7
53
  $ErrorActionPreference = "Stop"
8
- Set-StrictMode -Version 2
9
-
10
- # common functions that are loaded in exec and module context, this is set
11
- # as a script scoped variable so async_watchdog and module_wrapper can
12
- # access the functions when creating their Runspaces
13
- $script:common_functions = {
14
- Function ConvertFrom-AnsibleJson {
15
- <#
16
- .SYNOPSIS
17
- Converts a JSON string to a Hashtable/Array in the fastest way
18
- possible. Unfortunately ConvertFrom-Json is still faster but outputs
19
- a PSCustomObject which is cumbersome for module consumption.
20
-
21
- .PARAMETER InputObject
22
- [String] The JSON string to deserialize.
23
- #>
24
- param(
25
- [Parameter(Mandatory = $true, Position = 0)][String]$InputObject
26
- )
27
-
28
- # we can use -AsHashtable to get PowerShell to convert the JSON to
29
- # a Hashtable and not a PSCustomObject. This was added in PowerShell
30
- # 6.0, fall back to a manual conversion for older versions
31
- $cmdlet = Get-Command -Name ConvertFrom-Json -CommandType Cmdlet
32
- if ("AsHashtable" -in $cmdlet.Parameters.Keys) {
33
- return , (ConvertFrom-Json -InputObject $InputObject -AsHashtable)
54
+ $ProgressPreference = "SilentlyContinue"
55
+
56
+ # Try and set the console encoding to UTF-8 allowing Ansible to read the
57
+ # output of the wrapper as UTF-8 bytes.
58
+ try {
59
+ [Console]::InputEncoding = [Console]::OutputEncoding = [UTF8Encoding]::new()
60
+ }
61
+ catch {
62
+ # PSRP will not have a console host so this will fail. The line here is
63
+ # to ignore sanity checks.
64
+ $null = $_
65
+ }
66
+
67
+ if ($MinOSVersion) {
68
+ [version]$actualOSVersion = (Get-Item -LiteralPath $env:SystemRoot\System32\kernel32.dll).VersionInfo.ProductVersion
69
+
70
+ if ($actualOSVersion -lt $MinOSVersion) {
71
+ @{
72
+ failed = $true
73
+ msg = "This module cannot run on this OS as it requires a minimum version of $MinOSVersion, actual was $actualOSVersion"
74
+ } | ConvertTo-Json -Compress
75
+ $Host.SetShouldExit(1)
76
+ return
77
+ }
78
+ }
79
+
80
+ if ($MinPSVersion) {
81
+ if ($PSVersionTable.PSVersion -lt $MinPSVersion) {
82
+ @{
83
+ failed = $true
84
+ msg = "This module cannot run as it requires a minimum PowerShell version of $MinPSVersion, actual was ""$($PSVersionTable.PSVersion)"""
85
+ } | ConvertTo-Json -Compress
86
+ $Host.SetShouldExit(1)
87
+ return
88
+ }
89
+ }
90
+
91
+ # $Script:AnsibleManifest = @{} # Defined in process/end.
92
+ $Script:AnsibleWrapperWarnings = [List[string]]::new()
93
+ $Script:AnsibleTempPath = @(
94
+ # Wrapper defined tmpdir
95
+ [Environment]::ExpandEnvironmentVariables($TempPath)
96
+ # Fallback to user's tmpdir
97
+ [Path]::GetTempPath()
98
+ # Should not happen but just in case use the current dir.
99
+ $pwd.Path
100
+ ) | Where-Object {
101
+ if (-not $_) {
102
+ return $false
103
+ }
104
+
105
+ try {
106
+ Test-Path -LiteralPath $_ -ErrorAction Ignore
107
+ }
108
+ catch {
109
+ # Access denied could cause Test-Path to throw an exception.
110
+ $false
111
+ }
112
+ } | Select-Object -First 1
113
+
114
+ Function Convert-JsonObject {
115
+ param(
116
+ [Parameter(Mandatory, ValueFromPipeline)]
117
+ [AllowNull()]
118
+ [object]
119
+ $InputObject
120
+ )
121
+
122
+ process {
123
+ # Using the full type name is important as PSCustomObject is an
124
+ # alias for PSObject which all piped objects are.
125
+ if ($InputObject -is [System.Management.Automation.PSCustomObject]) {
126
+ $value = @{}
127
+ foreach ($prop in $InputObject.PSObject.Properties) {
128
+ $value[$prop.Name] = Convert-JsonObject -InputObject $prop.Value
129
+ }
130
+ $value
131
+ }
132
+ elseif ($InputObject -is [Array]) {
133
+ , @($InputObject | Convert-JsonObject)
34
134
  }
35
135
  else {
36
- # get the PSCustomObject and then manually convert from there
37
- $raw_obj = ConvertFrom-Json -InputObject $InputObject
136
+ $InputObject
137
+ }
138
+ }
139
+ }
38
140
 
39
- Function ConvertTo-Hashtable {
40
- param($InputObject)
141
+ Function Get-AnsibleScript {
142
+ [CmdletBinding()]
143
+ param (
144
+ [Parameter(Mandatory)]
145
+ [string]
146
+ $Name,
41
147
 
42
- if ($null -eq $InputObject) {
43
- return $null
44
- }
148
+ [Parameter()]
149
+ [switch]
150
+ $IncludeScriptBlock
151
+ )
45
152
 
46
- if ($InputObject -is [PSCustomObject]) {
47
- $new_value = @{}
48
- foreach ($prop in $InputObject.PSObject.Properties.GetEnumerator()) {
49
- $new_value.($prop.Name) = (ConvertTo-Hashtable -InputObject $prop.Value)
50
- }
51
- return , $new_value
52
- }
53
- elseif ($InputObject -is [Array]) {
54
- $new_value = [System.Collections.ArrayList]@()
55
- foreach ($val in $InputObject) {
56
- $new_value.Add((ConvertTo-Hashtable -InputObject $val)) > $null
57
- }
58
- return , $new_value.ToArray()
59
- }
60
- else {
61
- return , $InputObject
62
- }
63
- }
64
- return , (ConvertTo-Hashtable -InputObject $raw_obj)
153
+ if (-not $Script:AnsibleManifest.scripts.Contains($Name)) {
154
+ $err = [ErrorRecord]::new(
155
+ [Exception]::new("Could not find the script '$Name'."),
156
+ "ScriptNotFound",
157
+ [ErrorCategory]::ObjectNotFound,
158
+ $Name)
159
+ $PSCmdlet.ThrowTerminatingError($err)
160
+ }
161
+
162
+ $scriptInfo = $Script:AnsibleManifest.scripts[$Name]
163
+ $scriptBytes = [Convert]::FromBase64String($scriptInfo.script)
164
+ $scriptContents = [Encoding]::UTF8.GetString($scriptBytes)
165
+
166
+ $sbk = $null
167
+ if ($IncludeScriptBlock) {
168
+ $sbk = [Parser]::ParseInput(
169
+ $scriptContents,
170
+ $Name,
171
+ [ref]$null,
172
+ [ref]$null).GetScriptBlock()
173
+ }
174
+
175
+ [PSCustomObject]@{
176
+ Name = $Name
177
+ Script = $scriptContents
178
+ Path = $scriptInfo.path
179
+ ScriptBlock = $sbk
180
+ }
181
+ }
182
+
183
+ Function Get-NextAnsibleAction {
184
+ [CmdletBinding()]
185
+ param ()
186
+
187
+ $action, $newActions = $Script:AnsibleManifest.actions
188
+ $Script:AnsibleManifest.actions = @($newActions | Select-Object)
189
+
190
+ $actionName = $action.name
191
+ $actionParams = $action.params
192
+ $actionScript = Get-AnsibleScript -Name $actionName -IncludeScriptBlock
193
+
194
+ foreach ($kvp in $action.secure_params.GetEnumerator()) {
195
+ if (-not $kvp.Value) {
196
+ continue
65
197
  }
198
+
199
+ $name = $kvp.Key
200
+ $actionParams.$name = $kvp.Value | ConvertTo-SecureString -AsPlainText -Force
201
+ }
202
+
203
+ [PSCustomObject]@{
204
+ Name = $actionName
205
+ ScriptBlock = $actionScript.ScriptBlock
206
+ Parameters = $actionParams
66
207
  }
208
+ }
209
+
210
+ Function Get-AnsibleExecWrapper {
211
+ [CmdletBinding()]
212
+ param (
213
+ [Parameter()]
214
+ [switch]
215
+ $ManifestAsParam,
216
+
217
+ [Parameter()]
218
+ [switch]
219
+ $EncodeInputOutput,
220
+
221
+ [Parameter()]
222
+ [switch]
223
+ $IncludeScriptBlock
224
+ )
67
225
 
68
- Function Format-AnsibleException {
69
- <#
70
- .SYNOPSIS
71
- Formats a PowerShell ErrorRecord to a string that's fit for human
72
- consumption.
73
-
74
- .NOTES
75
- Using Out-String can give us the first part of the exception but it
76
- also wraps the messages at 80 chars which is not ideal. We also
77
- append the ScriptStackTrace and the .NET StackTrace if present.
78
- #>
79
- param([System.Management.Automation.ErrorRecord]$ErrorRecord)
80
-
81
- $exception = @"
82
- $($ErrorRecord.ToString())
83
- $($ErrorRecord.InvocationInfo.PositionMessage)
84
- + CategoryInfo : $($ErrorRecord.CategoryInfo.ToString())
85
- + FullyQualifiedErrorId : $($ErrorRecord.FullyQualifiedErrorId.ToString())
86
- "@
87
- # module_common strip comments and empty newlines, need to manually
88
- # add a preceding newline using `r`n
89
- $exception += "`r`n`r`nScriptStackTrace:`r`n$($ErrorRecord.ScriptStackTrace)`r`n"
90
-
91
- # exceptions from C# will also have a StackTrace which we
92
- # append if found
93
- if ($null -ne $ErrorRecord.Exception.StackTrace) {
94
- $exception += "`r`n$($ErrorRecord.Exception.ToString())"
226
+ $sbk = Get-AnsibleScript -Name exec_wrapper.ps1 -IncludeScriptBlock:$IncludeScriptBlock
227
+ $params = @{
228
+ # TempPath may contain env vars that change based on the runtime
229
+ # environment. Ensure we use that and not the $script:AnsibleTempPath
230
+ # when starting the exec wrapper.
231
+ TempPath = $TempPath
232
+ EncodeInputOutput = $EncodeInputOutput.IsPresent
233
+ }
234
+
235
+ $inputData = $null
236
+ if ($ManifestAsParam) {
237
+ $params.Manifest = $Script:AnsibleManifest
238
+ }
239
+ else {
240
+ $inputData = ConvertTo-Json -InputObject $Script:AnsibleManifest -Depth 99 -Compress
241
+ if ($EncodeInputOutput) {
242
+ $inputData = [Convert]::ToBase64String([Encoding]::UTF8.GetBytes($inputData))
95
243
  }
244
+ }
96
245
 
97
- return $exception
98
- }
99
- }
100
- .$common_functions
101
-
102
- # common wrapper functions used in the exec wrappers, this is defined in a
103
- # script scoped variable so async_watchdog can pass them into the async job
104
- $script:wrapper_functions = {
105
- Function Write-AnsibleError {
106
- <#
107
- .SYNOPSIS
108
- Writes an error message to a JSON string in the format that Ansible
109
- understands. Also optionally adds an exception record if the
110
- ErrorRecord is passed through.
111
- #>
112
- param(
113
- [Parameter(Mandatory = $true)][String]$Message,
114
- [System.Management.Automation.ErrorRecord]$ErrorRecord = $null
115
- )
116
- $result = @{
117
- msg = $Message
118
- failed = $true
246
+ [PSCustomObject]@{
247
+ Script = $sbk.Script
248
+ ScriptBlock = $sbk.ScriptBlock
249
+ Parameters = $params
250
+ InputData = $inputData
251
+ }
252
+ }
253
+
254
+ Function Import-PowerShellUtil {
255
+ [CmdletBinding()]
256
+ param (
257
+ [Parameter(Mandatory)]
258
+ [string[]]
259
+ $Name
260
+ )
261
+
262
+ foreach ($moduleName in $Name) {
263
+ $moduleInfo = Get-AnsibleScript -Name $moduleName -IncludeScriptBlock
264
+ $moduleShortName = [Path]::GetFileNameWithoutExtension($moduleName)
265
+ $null = New-Module -Name $moduleShortName -ScriptBlock $moduleInfo.ScriptBlock |
266
+ Import-Module -Scope Global
267
+ }
268
+ }
269
+
270
+ Function Import-CSharpUtil {
271
+ [CmdletBinding()]
272
+ param (
273
+ [Parameter(Mandatory)]
274
+ [string[]]
275
+ $Name
276
+ )
277
+
278
+ Import-PowerShellUtil -Name Ansible.ModuleUtils.AddType.psm1
279
+
280
+ $isBasicUtil = $false
281
+ $csharpModules = foreach ($moduleName in $Name) {
282
+ (Get-AnsibleScript -Name $moduleName).Script
283
+
284
+ if ($moduleName -eq 'Ansible.Basic.cs') {
285
+ $isBasicUtil = $true
119
286
  }
120
- if ($null -ne $ErrorRecord) {
121
- $result.msg += ": $($ErrorRecord.Exception.Message)"
122
- $result.exception = (Format-AnsibleException -ErrorRecord $ErrorRecord)
287
+ }
288
+
289
+ $fakeModule = [PSCustomObject]@{
290
+ Tmpdir = $Script:AnsibleTempPath
291
+ }
292
+ $warningFunc = [PSScriptMethod]::new('Warn', {
293
+ param($message)
294
+ $Script:AnsibleWrapperWarnings.Add($message)
295
+ })
296
+ $fakeModule.PSObject.Members.Add($warningFunc)
297
+ Add-CSharpType -References $csharpModules -AnsibleModule $fakeModule
298
+
299
+ if ($isBasicUtil) {
300
+ # Ansible.Basic.cs is a special case where we need to provide it
301
+ # with the wrapper warnings list so it injects it into the result.
302
+ [Ansible.Basic.AnsibleModule]::_WrapperWarnings = $Script:AnsibleWrapperWarnings
303
+ }
304
+ }
305
+
306
+ Function Write-AnsibleErrorJson {
307
+ [CmdletBinding()]
308
+ param (
309
+ [Parameter(Mandatory)]
310
+ [ErrorRecord]
311
+ $ErrorRecord,
312
+
313
+ [Parameter()]
314
+ [string]
315
+ $Message = "failure during exec_wrapper"
316
+ )
317
+
318
+ $exception = @(
319
+ "$ErrorRecord"
320
+ "$($ErrorRecord.InvocationInfo.PositionMessage)"
321
+ "+ CategoryInfo : $($ErrorRecord.CategoryInfo)"
322
+ "+ FullyQualifiedErrorId : $($ErrorRecord.FullyQualifiedErrorId)"
323
+ ""
324
+ "ScriptStackTrace:"
325
+ "$($ErrorRecord.ScriptStackTrace)"
326
+
327
+ if ($ErrorRecord.Exception.StackTrace) {
328
+ "$($ErrorRecord.Exception.StackTrace)"
123
329
  }
124
- Write-Output -InputObject (ConvertTo-Json -InputObject $result -Depth 99 -Compress)
125
- }
126
-
127
- Function Write-AnsibleLog {
128
- <#
129
- .SYNOPSIS
130
- Used as a debugging tool to log events to a file as they run in the
131
- exec wrappers. By default this is a noop function but the $log_path
132
- can be manually set to enable it. Manually set ANSIBLE_EXEC_DEBUG as
133
- an env value on the Windows host that this is run on to enable.
134
- #>
135
- param(
136
- [Parameter(Mandatory = $true, Position = 0)][String]$Message,
137
- [Parameter(Position = 1)][String]$Wrapper
138
- )
139
-
140
- $log_path = $env:ANSIBLE_EXEC_DEBUG
141
- if ($log_path) {
142
- $log_path = [System.Environment]::ExpandEnvironmentVariables($log_path)
143
- $parent_path = [System.IO.Path]::GetDirectoryName($log_path)
144
- if (Test-Path -LiteralPath $parent_path -PathType Container) {
145
- $msg = "{0:u} - {1} - {2} - " -f (Get-Date), $pid, ([System.Security.Principal.WindowsIdentity]::GetCurrent().Name)
146
- if ($null -ne $Wrapper) {
147
- $msg += "$Wrapper - "
148
- }
149
- $msg += $Message + "`r`n"
150
- $msg_bytes = [System.Text.Encoding]::UTF8.GetBytes($msg)
330
+ ) -join ([Environment]::NewLine)
151
331
 
152
- $fs = [System.IO.File]::Open($log_path, [System.IO.FileMode]::Append,
153
- [System.IO.FileAccess]::Write, [System.IO.FileShare]::ReadWrite)
154
- try {
155
- $fs.Write($msg_bytes, 0, $msg_bytes.Length)
156
- }
157
- finally {
158
- $fs.Close()
332
+ @{
333
+ failed = $true
334
+ msg = "${Message}: $ErrorRecord"
335
+ exception = $exception
336
+ } | ConvertTo-Json -Compress
337
+ $host.SetShouldExit(1)
338
+ }
339
+
340
+ Function Write-PowerShellClixmlStderr {
341
+ [CmdletBinding()]
342
+ param (
343
+ [Parameter(Mandatory)]
344
+ [AllowEmptyString()]
345
+ [string]
346
+ $Output
347
+ )
348
+
349
+ if (-not $Output) {
350
+ return
351
+ }
352
+
353
+ # -EncodedCommand in WinPS will output CLIXML to stderr. This attempts to parse
354
+ # it into a human readable format otherwise it'll just output the raw CLIXML.
355
+ $wroteStderr = $false
356
+ if ($Output.StartsWith('#< CLIXML')) {
357
+ $clixml = $Output -split "\r?\n"
358
+ if ($clixml.Count -eq 2) {
359
+ try {
360
+ # PSSerialize.Deserialize doesn't tell us what streams each record
361
+ # is for so we get the S attribute manually.
362
+ $streams = @(([xml]$clixml[1]).Objs.GetEnumerator() | ForEach-Object { $_.S })
363
+ $objects = @([PSSerializer]::Deserialize($clixml[1]))
364
+
365
+ for ($i = 0; $i -lt $objects.Count; $i++) {
366
+ $msg = $objects[$i]
367
+ if ($msg -isnot [string] -or $streams.Length -le $i) {
368
+ continue
369
+ }
370
+
371
+ # Doesn't use TrimEnd() so it only removes the last newline
372
+ if ($msg.EndsWith([Environment]::NewLine)) {
373
+ $msg = $msg.Substring(0, $msg.Length - [Environment]::NewLine.Length)
374
+ }
375
+ $stream = $streams[$i]
376
+ switch ($stream) {
377
+ 'error' { $host.UI.WriteErrorLine($msg) }
378
+ 'debug' { $host.UI.WriteDebugLine($msg) }
379
+ 'verbose' { $host.UI.WriteVerboseLine($msg) }
380
+ 'warning' { $host.UI.WriteWarningLine($msg) }
381
+ }
159
382
  }
383
+ $wroteStderr = $true
384
+ }
385
+ catch {
386
+ $null = $_
160
387
  }
161
388
  }
162
389
  }
390
+ if (-not $wroteStderr) {
391
+ $host.UI.WriteErrorLine($Output.TrimEnd())
392
+ }
163
393
  }
164
- .$wrapper_functions
165
394
 
166
- # only init and stream in $json_raw if it wasn't set by the enclosing scope
167
- if (-not $(Get-Variable "json_raw" -ErrorAction SilentlyContinue)) {
168
- $json_raw = ''
169
- }
170
- } process {
171
- $json_raw += [String]$input
172
- } end {
173
- Write-AnsibleLog "INFO - starting exec_wrapper" "exec_wrapper"
174
- if (-not $json_raw) {
175
- Write-AnsibleError -Message "internal error: no input given to PowerShell exec wrapper"
176
- exit 1
177
- }
395
+ # To handle optional input for the incoming manifest and optional input to
396
+ # the subsequent action we optionally run this step in the begin or end
397
+ # block.
398
+ $jsonPipeline = $null
399
+ $actionPipeline = $null
400
+ $setupManifest = {
401
+ [CmdletBinding()]
402
+ param (
403
+ [Parameter()]
404
+ [switch]
405
+ $ExpectingInput
406
+ )
178
407
 
179
- Write-AnsibleLog "INFO - converting json raw to a payload" "exec_wrapper"
180
- $payload = ConvertFrom-AnsibleJson -InputObject $json_raw
181
- $payload.module_args._ansible_exec_wrapper_warnings = [System.Collections.Generic.List[string]]@()
408
+ if ($jsonPipeline) {
409
+ $Script:AnsibleManifest = $jsonPipeline.End()[0]
410
+ $jsonPipeline.Dispose()
411
+ $jsonPipeline = $null
412
+ }
413
+ else {
414
+ $Script:AnsibleManifest = $Manifest
415
+ }
182
416
 
183
- # TODO: handle binary modules
184
- # TODO: handle persistence
417
+ $actionInfo = Get-NextAnsibleAction
418
+ $actionParams = $actionInfo.Parameters
185
419
 
186
- if ($payload.min_os_version) {
187
- $min_os_version = [Version]$payload.min_os_version
188
- # Environment.OSVersion.Version is deprecated and may not return the
189
- # right version
190
- $actual_os_version = [Version](Get-Item -Path $env:SystemRoot\System32\kernel32.dll).VersionInfo.ProductVersion
420
+ if ($ActionParameters) {
421
+ foreach ($prop in $ActionParameters.PSObject.Properties) {
422
+ $actionParams[$prop.Name] = $prop.Value
423
+ }
424
+ }
191
425
 
192
- Write-AnsibleLog "INFO - checking if actual os version '$actual_os_version' is less than the min os version '$min_os_version'" "exec_wrapper"
193
- if ($actual_os_version -lt $min_os_version) {
194
- $msg = "internal error: This module cannot run on this OS as it requires a minimum version of $min_os_version, actual was $actual_os_version"
195
- Write-AnsibleError -Message $msg
196
- exit 1
426
+ $actionPipeline = { & $actionInfo.ScriptBlock @actionParams }.GetSteppablePipeline()
427
+ $actionPipeline.Begin($ExpectingInput)
428
+ if (-not $ExpectingInput) {
429
+ $null = $actionPipeline.Process()
197
430
  }
198
431
  }
199
- if ($payload.min_ps_version) {
200
- $min_ps_version = [Version]$payload.min_ps_version
201
- $actual_ps_version = $PSVersionTable.PSVersion
202
432
 
203
- Write-AnsibleLog "INFO - checking if actual PS version '$actual_ps_version' is less than the min PS version '$min_ps_version'" "exec_wrapper"
204
- if ($actual_ps_version -lt $min_ps_version) {
205
- $msg = "internal error: This module cannot run as it requires a minimum PowerShell version of $min_ps_version, actual was $actual_ps_version"
206
- Write-AnsibleError -Message $msg
207
- exit 1
433
+ try {
434
+ if ($Manifest) {
435
+ # If the manifest was provided through the parameter, we can start the
436
+ # action pipeline and all subsequent input (if any) will be sent to the
437
+ # action.
438
+ # It is important that $setupManifest is called by dot sourcing or
439
+ # else the pipelines started in it loose access to all parent scopes.
440
+ # https://github.com/PowerShell/PowerShell/issues/17868
441
+ . $setupManifest -ExpectingInput:$MyInvocation.ExpectingInput
442
+ }
443
+ else {
444
+ # Otherwise the first part of the input is the manifest json with the
445
+ # chance for extra data afterwards.
446
+ $jsonPipeline = { ConvertFrom-Json | Convert-JsonObject }.GetSteppablePipeline()
447
+ $jsonPipeline.Begin($true)
208
448
  }
209
449
  }
450
+ catch {
451
+ Write-AnsibleErrorJson -ErrorRecord $_
452
+ }
453
+ }
210
454
 
211
- # pop 0th action as entrypoint
212
- $action = $payload.actions[0]
213
- Write-AnsibleLog "INFO - running action $action" "exec_wrapper"
214
-
215
- $entrypoint = [System.Text.Encoding]::UTF8.GetString([System.Convert]::FromBase64String($payload.($action)))
216
- $entrypoint = [ScriptBlock]::Create($entrypoint)
217
- # so we preserve the formatting and don't fall prey to locale issues, some
218
- # wrappers want the output to be in base64 form, we store the value here in
219
- # case the wrapper changes the value when they create a payload for their
220
- # own exec_wrapper
221
- $encoded_output = $payload.encoded_output
455
+ process {
456
+ try {
457
+ if ($actionPipeline) {
458
+ # We received our manifest and started the action pipeline, redirect
459
+ # all further input to that pipeline.
460
+ $null = $actionPipeline.Process($InputObject)
461
+ }
462
+ elseif ([string]::Equals($InputObject, "`0`0`0`0")) {
463
+ # Special marker used to indicate all subsequent input is for the
464
+ # action. Setup that pipeline and finalise the manifest.
465
+ . $setupManifest -ExpectingInput
466
+ }
467
+ elseif ($jsonPipeline) {
468
+ # Data is for the JSON manifest, decode if needed.
469
+ if ($EncodeInputOutput) {
470
+ $jsonPipeline.Process([Encoding]::UTF8.GetString([Convert]::FromBase64String($InputObject)))
471
+ }
472
+ else {
473
+ $jsonPipeline.Process($InputObject)
474
+ }
475
+ }
476
+ }
477
+ catch {
478
+ Write-AnsibleErrorJson -ErrorRecord $_
479
+ }
480
+ }
222
481
 
482
+ end {
223
483
  try {
224
- $output = &$entrypoint -Payload $payload
225
- if ($encoded_output -and $null -ne $output) {
226
- $b64_output = [System.Convert]::ToBase64String([System.Text.Encoding]::UTF8.GetBytes($output))
227
- Write-Output -InputObject $b64_output
484
+ if ($jsonPipeline) {
485
+ # Only manifest input was received, process it now and start the
486
+ # action pipeline with no input being provided.
487
+ . $setupManifest
488
+ }
489
+
490
+ $out = $actionPipeline.End()
491
+ if ($EncodeInputOutput) {
492
+ [Convert]::ToBase64String([Encoding]::UTF8.GetBytes($out))
228
493
  }
229
494
  else {
230
- $output
495
+ $out
231
496
  }
232
497
  }
233
498
  catch {
234
- Write-AnsibleError -Message "internal error: failed to run exec_wrapper action $action" -ErrorRecord $_
235
- exit 1
499
+ Write-AnsibleErrorJson -ErrorRecord $_
500
+ }
501
+ finally {
502
+ $actionPipeline.Dispose()
236
503
  }
237
- Write-AnsibleLog "INFO - ending exec_wrapper" "exec_wrapper"
238
504
  }