Compare commits

..

429 Commits

Author SHA1 Message Date
Felix Fontein
862e6d035f Remove CI. 2025-11-02 13:56:24 +01:00
Felix Fontein
12b000ac76 Release 9.5.13. 2025-11-02 13:01:33 +01:00
patchback[bot]
ae6fa9a684 [PR #11005/54af64ad backport][stable-9] keycloak_user: mark credentials[].value as no_log=True (#11010)
keycloak_user: mark credentials[].value as no_log=True (#11005)

Mark credentials[].value as no_log=True.

(cherry picked from commit 54af64ad36)

Co-authored-by: Felix Fontein <felix@fontein.de>
2025-10-29 17:15:24 +00:00
Felix Fontein
a87b62d521 [stable-9] Move stable-2.16 to EOL CI (#10996)
* Move stable-2.16 to EOL CI.

* Skip ODBC tests on Alpine.
2025-10-27 19:57:25 +01:00
Felix Fontein
fce2a7e1be Prepare 9.5.13. 2025-10-27 19:42:00 +01:00
patchback[bot]
f5b6ad1bb7 [PR #10988/f6781f65 backport][stable-9] CI: temporarily disable tests for copr (#10989)
CI: temporarily disable tests for copr (#10988)

Temporarily disable tests for copr.

(cherry picked from commit f6781f654e)

Co-authored-by: Felix Fontein <felix@fontein.de>
2025-10-26 21:57:00 +01:00
Felix Fontein
efaf037775 The next release will be 9.5.13. 2025-10-06 18:49:14 +02:00
Felix Fontein
a3ef32b758 Release 9.5.12. 2025-10-06 18:19:47 +02:00
Felix Fontein
b5c23d5741 Add repository configuration to antsibull-nox.toml.
(cherry picked from commit e9b1788bb9)
2025-09-26 07:04:28 +02:00
Felix Fontein
2ca4a8e472 Prepare 9.5.12. 2025-09-25 21:14:41 +02:00
patchback[bot]
c9819b57b3 [PR #10857/68684a7a backport][stable-9] github_deploy_key: make sure variable exists before use (#10858)
github_deploy_key: make sure variable exists before use (#10857)

Make sure variable exists before use.

(cherry picked from commit 68684a7a4c)

Co-authored-by: Felix Fontein <felix@fontein.de>
2025-09-25 20:46:15 +02:00
patchback[bot]
6230a7a842 [PR #10852/648ff7db backport][stable-9] yaml cache plugin: make compatible with ansible-core 2.19 (#10854)
yaml cache plugin: make compatible with ansible-core 2.19 (#10852)

Make compatible with ansible-core 2.19.

(cherry picked from commit 648ff7db02)

Co-authored-by: Felix Fontein <felix@fontein.de>
2025-09-25 07:37:16 +02:00
patchback[bot]
46c63be23a [PR #10830/2bf8ae88 backport][stable-9] timezone: mention that Debian 13 also needs util-linux-extra (#10835)
timezone: mention that Debian 13 also needs util-linux-extra (#10830)

Mention that Debian 13 also needs util-linux-extra.

(cherry picked from commit 2bf8ae88be)

Co-authored-by: Felix Fontein <felix@fontein.de>
2025-09-18 22:14:51 +02:00
patchback[bot]
e930e3d42a [PR #10770/3cc4f28f backport][stable-9] minor fixes in doc guides (#10778)
minor fixes in doc guides (#10770)

(cherry picked from commit 3cc4f28fd7)

Co-authored-by: Alexei Znamensky <103110+russoz@users.noreply.github.com>
2025-08-31 12:10:47 +02:00
patchback[bot]
72fc0fd22a [PR #10732/5ee02297 backport][stable-9] ssh_config tests: remove paramiko version restriction (#10733)
ssh_config tests: remove paramiko version restriction (#10732)

Remove paramiko version restriction for ssh_config tests.

(cherry picked from commit 5ee02297b0)

Co-authored-by: Felix Fontein <felix@fontein.de>
2025-08-25 07:09:25 +02:00
patchback[bot]
8dc5eeb11b [PR #10728/82b37bdb backport][stable-9] pacman: re-enable yay test (#10729)
pacman: re-enable yay test (#10728)

Re-enable yay test.

(cherry picked from commit 82b37bdb56)

Co-authored-by: Felix Fontein <felix@fontein.de>
2025-08-25 06:57:40 +02:00
dependabot[bot]
e509382dda build(deps): bump actions/checkout from 4 to 5 in the ci group (#10695)
Bumps the ci group with 1 update: [actions/checkout](https://github.com/actions/checkout).

Updates `actions/checkout` from 4 to 5
- [Release notes](https://github.com/actions/checkout/releases)
- [Changelog](https://github.com/actions/checkout/blob/main/CHANGELOG.md)
- [Commits](https://github.com/actions/checkout/compare/v4...v5)

---
updated-dependencies:
- dependency-name: actions/checkout
  dependency-version: '5'
  dependency-type: direct:production
  update-type: version-update:semver-major
  dependency-group: ci
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
(cherry picked from commit 6827680cda)
2025-08-18 20:28:49 +02:00
patchback[bot]
26b7f0e85b [PR #10674/dfc2a54d backport][stable-9] pacman: temporary disable yay test (#10676)
pacman: temporary disable yay test (#10674)

Temporary disable pacman yay test.

(cherry picked from commit dfc2a54d16)

Co-authored-by: Felix Fontein <felix@fontein.de>
2025-08-15 21:03:29 +02:00
patchback[bot]
9ed35900ba [PR #10653/eb5708a1 backport][stable-9] CI: Make sure to install Java in Debian Bullseye (#10654)
CI: Make sure to install Java in Debian Bullseye (#10653)

Make sure to install Java in Debian Bullseye.

(cherry picked from commit eb5708a125)

Co-authored-by: Felix Fontein <felix@fontein.de>
2025-08-12 01:21:29 +02:00
Felix Fontein
1dcbebda20 The next release will be 9.5.12. 2025-08-11 22:20:39 +02:00
Felix Fontein
f9c620a83c Release 9.5.11. 2025-08-11 21:35:24 +02:00
patchback[bot]
ac2704c629 [PR #10566/14f706c5 backport][stable-9] merge_variables lookup: avoid deprecated Templar.set_temporary_context (#10567)
merge_variables lookup: avoid deprecated Templar.set_temporary_context (#10566)

Avoid deprecated Templar.set_temporary_context.

(cherry picked from commit 14f706c5dd)

Co-authored-by: Felix Fontein <felix@fontein.de>
2025-08-03 13:08:45 +02:00
Felix Fontein
018f4c989d [stable-9] diy callback: add test for on_any_msg (#10550) (#10554)
diy callback: add test for on_any_msg (#10550)

Add test for on_any_msg.

(cherry picked from commit ac4aca2004)
2025-08-02 18:02:57 +02:00
patchback[bot]
d480f5792b [PR #10539/3de073fb backport][stable-9] json_query: extend list of type aliases for compatibility with ansible-core 2.19 (#10558)
json_query: extend list of type aliases for compatibility with ansible-core 2.19 (#10539)

* Extend list of type aliases for json_query.

* Improve tests.



---------


(cherry picked from commit 3de073fb6f)

Co-authored-by: Felix Fontein <felix@fontein.de>
Co-authored-by: Abhijeet Kasurde <akasurde@redhat.com>
2025-08-02 18:02:49 +02:00
Felix Fontein
5c00c5b3a5 [stable-9] [stable-10] Backport fixes from community.proxmox (#10553) (#10564)
[stable-10] Backport fixes from community.proxmox (#10553)

* Import paramiko directly.

8f90ab075c

* Remove deprecated disable_lookups parameter.

c0fc31241b
(cherry picked from commit 4c7f64b121)
2025-08-02 18:02:39 +02:00
Felix Fontein
f7f5c7f913 [stable-9] [stable-10] Disable pipelining for doas and machinectl on ansible-core 2.19+ (#10537) (#10561) (#10565)
[stable-10] Disable pipelining for doas and machinectl on ansible-core 2.19+ (#10537) (#10561)

Disable pipelining for doas and machinectl on ansible-core 2.19+ (#10537)

Disable pipelining for doas and machinectl.

(cherry picked from commit 9a29622584)
(cherry picked from commit 69563766ec)
2025-08-02 18:02:31 +02:00
Felix Fontein
93257c32a8 [stable-9] Fix no longer valid constructs in tests (#10543) (#10548)
Fix no longer valid constructs in tests (#10543)

Fix no longer valid constructs in tests.

(cherry picked from commit 7298f25fe0)
2025-08-02 11:08:24 +02:00
Felix Fontein
63ed9a553f Update Azure Pipelines test container. 2025-07-30 06:21:18 +02:00
patchback[bot]
54861a2062 [PR #10491/de0618b8 backport][stable-9] irc: fix wrap_socket() call when validate_certs=true and use_tls=true (#10497)
irc: fix wrap_socket() call when validate_certs=true and use_tls=true (#10491)

Fix wrap_socket() call when validate_certs=true and use_tls=true.

(cherry picked from commit de0618b843)

Co-authored-by: Felix Fontein <felix@fontein.de>
2025-07-28 06:47:00 +02:00
Felix Fontein
b18b9314d3 Normalize changelog configs.
(cherry picked from commit a692888478)
2025-07-27 16:37:10 +02:00
Felix Fontein
7631941cdd Prepare 9.5.11. 2025-07-27 12:15:54 +02:00
patchback[bot]
7daa21210f [PR #10459/ee783066 backport][stable-9] Fix ansible-core 2.19 deprecations (#10469)
Fix ansible-core 2.19 deprecations (#10459)

Do not return warnings.

(cherry picked from commit ee7830667a)

Co-authored-by: Felix Fontein <felix@fontein.de>
2025-07-27 12:13:01 +02:00
patchback[bot]
cfc06284c6 [PR #10446/01f3248a backport][stable-9] CI: Replace FreeBSD 13.3 with 13.5 (#10447)
CI: Replace FreeBSD 13.3 with 13.5 (#10446)

Replace FreeBSD 13.3 with 13.5.

(cherry picked from commit 01f3248a12)

Co-authored-by: Felix Fontein <felix@fontein.de>
2025-07-24 22:10:29 +02:00
patchback[bot]
71a15b5002 [PR #10428/bc4d06ef backport][stable-9] Fix dnf_versionlock examples (#10429)
Fix dnf_versionlock examples (#10428)

Fix dnf_versionlock examples.

(cherry picked from commit bc4d06ef34)

Co-authored-by: Felix Fontein <felix@fontein.de>
2025-07-18 23:23:54 +02:00
Felix Fontein
2184016f5a The next release will be 9.5.11. 2025-07-13 21:44:33 +02:00
Felix Fontein
aa1920bc28 Release 9.5.10. 2025-07-13 21:19:27 +02:00
patchback[bot]
add153098e [PR #10374/a0200d11 backport][stable-9] Disable lmdb_kv integration tests (#10376)
Disable lmdb_kv integration tests (#10374)

Disable lmdb_kv integration tests.

(cherry picked from commit a0200d1130)

Co-authored-by: Felix Fontein <felix@fontein.de>
2025-07-10 22:07:33 +02:00
Felix Fontein
cfcfbc19d7 Prepare 9.5.10. 2025-07-08 21:12:16 +02:00
patchback[bot]
d5f3e6fa7f [PR #10359/16d6e4a8 backport][stable-9] dependent lookup: avoid deprecated ansible-core 2.19 functionality (#10364)
dependent lookup: avoid deprecated ansible-core 2.19 functionality (#10359)

* Avoid deprecated ansible-core 2.19 functionality.

* Adjust unit tests.

(cherry picked from commit 16d6e4a8e5)

Co-authored-by: Felix Fontein <felix@fontein.de>
2025-07-08 06:52:39 +02:00
Jakub Danek
68b233aa96 [keycloak] fix call of non-existent method in backported code (#10298)
* [#KC] fix call of non-existent method in backported code

commit 8b1a193a backported into stable-9 contains calls to _request method which was created as part of api calls refactoring in main/stable-10 but does not exist in stable-9.

This commit replaces the calls with the previous implementation (open_url method).

* [#KC] add changes fragment
2025-06-25 19:55:03 +02:00
patchback[bot]
8ad2bc31a3 [PR #10271/40fb0f0c backport][stable-9] Inventory plugins: remove deprecated disable_lookups parameter (which was set to its default anyway) (#10275)
Inventory plugins: remove deprecated disable_lookups parameter (which was set to its default anyway) (#10271)

* Remove default value for keyword argument that is deprecated since ansible-core 2.19.

* Add changelog fragment.

(cherry picked from commit 40fb0f0c75)

Co-authored-by: Felix Fontein <felix@fontein.de>
2025-06-18 21:52:52 +02:00
patchback[bot]
8b3fb0b6c0 [PR #10272/5b14129c backport][stable-9] sysrc jail tests: FreeBSD 14.1 stopped working (#10273)
sysrc jail tests: FreeBSD 14.1 stopped working (#10272)

FreeBSD 14.1 stopped working.

(cherry picked from commit 5b14129c8f)

Co-authored-by: Felix Fontein <felix@fontein.de>
2025-06-18 21:52:37 +02:00
Felix Fontein
ac3e2bcaa9 Update CI schedule.
(cherry picked from commit 49d84e7b97)
2025-06-16 20:12:23 +02:00
Felix Fontein
bc1d0c4663 The next expected release wil be 9.5.10. 2025-06-15 13:32:17 +02:00
Felix Fontein
34d9809c0d Release 9.5.9. 2025-06-15 12:59:02 +02:00
Felix Fontein
cb26c50d65 [stable-9] docs: add notes that dnf_* modules do not work with dnf5 (#10238) (#10248)
docs: add notes that dnf_* modules do not work with dnf5 (#10238)

* Add notes that dnf_* modules do not work with dnf5.

* Apply suggestions from code review.



---------


(cherry picked from commit 1956815884)

Co-authored-by: Alexei Znamensky <103110+russoz@users.noreply.github.com>
2025-06-15 11:39:26 +02:00
Felix Fontein
67269f302d [stable-9] yaml callback: use new util introduced in ansible-core 2.19.0b2 (#10242) (#10246)
yaml callback: use new util introduced in ansible-core 2.19.0b2 (#10242)

* Avoid repeating some code.

* Use new utility added for ansible-core 2.19.0b2.

* Lint.

* Add changelog fragment.

* transform_to_native_types() does not convert map keys.

To catch all tagged strings, we have to recursively walk the data structure then.

* Add test with vaulted string.

(cherry picked from commit 66cb9aefb5)
2025-06-15 11:12:00 +02:00
patchback[bot]
fd48bc38f1 [PR #10228/a95448ca backport][stable-9] Update auto-generated .gitignore parts (#10229)
Update auto-generated .gitignore parts (#10228)

Update auto-generated .gitignore parts.

(cherry picked from commit a95448ca55)

Co-authored-by: Felix Fontein <felix@fontein.de>
2025-06-11 07:09:14 +02:00
Felix Fontein
f89102ffdc Prepare 9.5.9. 2025-06-07 17:57:11 +02:00
patchback[bot]
3d3328ecaf [PR #10212/996ffc8f backport][stable-9] Fix YAML callback (#10217)
Fix YAML callback (#10212)

Fix YAML callback.

(cherry picked from commit 996ffc8f8c)

Co-authored-by: Felix Fontein <felix@fontein.de>
2025-06-06 22:46:59 +00:00
patchback[bot]
fee8278015 [PR #10214/f7f2db36 backport][stable-9] Fix module_helper tests (#10215)
Fix module_helper tests (#10214)

Fix module_helper tests.

(cherry picked from commit f7f2db365e)

Co-authored-by: Felix Fontein <felix@fontein.de>
2025-06-06 20:28:40 +00:00
patchback[bot]
93c121d4a6 [PR #10209/63add288 backport][stable-9] Tests: adjust to ansible-core devel changes (#10210)
Tests: adjust to ansible-core devel changes (#10209)

Apparently the error message returned by AnsibleModule.run_command() when trying to execute a non-existing executable changed.

Ref: 600c1e67b4
(cherry picked from commit 63add288dc)

Co-authored-by: Felix Fontein <felix@fontein.de>
2025-06-06 21:52:10 +02:00
Felix Fontein
12a21e0517 Fix typo.
(cherry picked from commit 0dc1d9045b)
2025-05-30 14:52:29 +02:00
Felix Fontein
7e49c825f7 [stable-9] Replace devel with stable-2.19 in CI (#10167)
Replace devel with stable-2.19 in CI and docs.
2025-05-22 19:55:14 +02:00
Felix Fontein
4cce99abb5 [stable-9] Add RHEL 10.0 to CI (#10166)
Add RHEL 10.0 to CI (#10164)

Add RHEL 10.0 to CI.

(cherry picked from commit 2a18a07bdc)
2025-05-22 19:55:02 +02:00
Felix Fontein
5a7a3b2f5e The next release will be 9.5.9. 2025-05-19 19:02:44 +02:00
Felix Fontein
d481a6b0d4 Release 9.5.8. 2025-05-19 18:08:30 +02:00
patchback[bot]
7a9253e68b [PR #10145/3daa1dec backport][stable-9] Fix TypeError caused by giving more than 2 positional arguments to CobblerXMLRPCInterface.get_system_handle() (#10157)
Fix TypeError caused by giving more than 2 positional arguments to CobblerXMLRPCInterface.get_system_handle()  (#10145)

* Update cobbler system module to also use new get_system_handle method definition

* Add changelog for bug fix for cobbler system module

(cherry picked from commit 3daa1dec0c)

Co-authored-by: umiruka <211638667+umiruka@users.noreply.github.com>
2025-05-18 22:45:04 +02:00
Felix Fontein
7945d5afbe Fix action group config. 2025-05-18 22:30:27 +02:00
Felix Fontein
c28021b662 Prepare 9.5.8 release. 2025-05-18 22:25:01 +02:00
patchback[bot]
3dd39fedd2 [PR #10128/626ee311 backport][stable-9] kdeconfig: mark end of options before sending value (#10147)
kdeconfig: mark end of options before sending value (#10128)

* mark end of options before sending value

* fix linting issue

* fragment update

(cherry picked from commit 626ee3115d)

Co-authored-by: Bob Mroczka <bob@mroczka.com>
2025-05-17 08:13:31 +02:00
patchback[bot]
6d8549f00a [PR #10097/ff0ed6f9 backport][stable-9] rundeck_acl_policy: fix project acls are put/posted to the wrong endpoint (#10150)
rundeck_acl_policy: fix project acls are put/posted to the wrong endpoint (#10097)

* Fix project acls are put/posted to the wrong endpoint

* Add changelog fragment.

* Fix 2.7 sanity errors in github

* Fix fragment extension and use 2.7 syntax in test

* Update changelogs/fragments/10097-fix-rundeck_acl_policy-project-endpoint.yml



* Fix pep8 formatting

* Add licensing to unit test

---------


(cherry picked from commit ff0ed6f912)

Co-authored-by: kjoyce77 <kevin.joyce@outlook.com>
Co-authored-by: Felix Fontein <felix@fontein.de>
2025-05-17 08:13:19 +02:00
patchback[bot]
805362f337 [PR #10104/6008e6e1 backport][stable-9] Allow running sanity and unit tests with antsibull-nox; impove testing documentation (#10152)
Allow running sanity and unit tests with antsibull-nox; impove testing documentation (#10104)

* Whitespace fixes.

* Allow to run unit and sanity tests with antsibull-nox.

* Document installation of needed collections for tests.

* Also mention other sanity tests.

(cherry picked from commit 6008e6e1a7)

Co-authored-by: Felix Fontein <felix@fontein.de>
2025-05-17 08:13:10 +02:00
patchback[bot]
c0b5119034 [PR #10136/937d92ee backport][stable-9] pickle cache plugin, avoid extra steps in DT (#10143)
pickle cache plugin, avoid extra steps in DT (#10136)

* pickle cache plugin, avoid extra steps in DT

* clog

* Update changelogs/fragments/10136-cache-pickle-json.yml



---------


(cherry picked from commit 937d92ee25)

Co-authored-by: Brian Coca <bcoca@users.noreply.github.com>
Co-authored-by: Felix Fontein <felix@fontein.de>
2025-05-16 22:37:53 +02:00
patchback[bot]
fd8a452f22 [PR #10140/94eb385c backport][stable-9] sysrc - add integration test. value contains equals sign. (#10141)
sysrc - add integration test. value contains equals sign. (#10140)

(cherry picked from commit 94eb385c21)

Co-authored-by: Vladimir Botka <vbotka@gmail.com>
2025-05-16 22:37:41 +02:00
patchback[bot]
6d46e650b7 [PR #10129/e853a6f3 backport][stable-9] redis_info: adjust tests for Arch Linux (#10130)
redis_info: adjust tests for Arch Linux (#10129)

(cherry picked from commit e853a6f39b)

Co-authored-by: Felix Fontein <felix@fontein.de>
2025-05-14 07:34:36 +02:00
patchback[bot]
b4468bd4c7 [PR #10121/de60ea1d backport][stable-9] Fix #10120. Split key=value where value may comprise = (#10124)
Fix #10120. Split key=value where value may comprise = (#10121)

* Fix #10120. Split key=value where value may comprise =

* Added fragment.

* Update plugins/modules/sysrc.py



* Update changelogs/fragments/10121-sysrc-fix-split-first-separator.yml



---------


(cherry picked from commit de60ea1da4)

Co-authored-by: Vladimir Botka <vbotka@gmail.com>
Co-authored-by: Felix Fontein <felix@fontein.de>
2025-05-12 22:10:09 +02:00
patchback[bot]
e2af16b03f [PR #10115/86507e8a backport][stable-9] lxc: fix unit tests (#10117)
lxc: fix unit tests (#10115)

Don't compare strings passed through set_option()/get_option() with 'is'.

(cherry picked from commit 86507e8aca)

Co-authored-by: Felix Fontein <felix@fontein.de>
2025-05-10 15:12:36 +02:00
patchback[bot]
3abf169a2f [PR #10111/fcd2d8b7 backport][stable-9] Fix deprecation test (#10112)
Fix deprecation test (#10111)

Fix deprecation test.

(cherry picked from commit fcd2d8b7b7)

Co-authored-by: Felix Fontein <felix@fontein.de>
2025-05-06 23:13:42 +02:00
patchback[bot]
5039265621 [PR #10106/94acd180 backport][stable-9] antsibull-nox: use community.crypto 2.x.y for ansible-core < 2.17 (#10107)
* antsibull-nox: use community.crypto 2.x.y for ansible-core < 2.17 (#10106)

Use community.crypto 2.x.y for ansible-core < 2.17.

(cherry picked from commit 94acd18052)

* community.general 9.x.y supports ansible-core >= 2.13.

---------

Co-authored-by: Felix Fontein <felix@fontein.de>
2025-05-06 21:54:53 +02:00
patchback[bot]
b52b754a3d [PR #10096/a042721c backport][stable-9] pipx/pipx_info: fix scheduled tests (#10099)
pipx/pipx_info: fix scheduled tests (#10096)

(cherry picked from commit a042721c82)

Co-authored-by: Alexei Znamensky <103110+russoz@users.noreply.github.com>
2025-05-04 14:02:25 +02:00
patchback[bot]
9aef7ad67e [PR #10076/f3ea40db backport][stable-9] keycloak_user_rolemapping: fix diff mode (#10092)
keycloak_user_rolemapping: fix diff mode (#10076)

(cherry picked from commit f3ea40db3d)

Co-authored-by: Felix Fontein <felix@fontein.de>
2025-05-02 06:15:43 +02:00
patchback[bot]
0e15608149 [PR #10086/60f1169d backport][stable-9] CI: Use community.crypto 2.x.y for ansible-core 2.16 and before (#10088)
CI: Use community.crypto 2.x.y for ansible-core 2.16 and before (#10086)

* Use community.crypto 2.x.y for ansible-core 2.16 and before.

* Also use stable-2 for ubuntu2004 tests.

(cherry picked from commit 60f1169d42)

Co-authored-by: Felix Fontein <felix@fontein.de>
2025-05-01 09:17:58 +02:00
Felix Fontein
844e3a581c [stable-9] nmcli: fix misspelled option in example (#10075) (#10085)
nmcli: fix misspelled option in example (#10075)

Fix misspelled option.

(cherry picked from commit d89a0bbc0e)
2025-04-30 22:32:03 +02:00
Felix Fontein
3c86bb9cda Use community.crypto's stable-2 branch in EOL CI.
(cherry picked from commit aeb668a645)
2025-04-30 07:50:44 +02:00
Felix Fontein
8222f1f064 [stable-9] crypttab: removes jijna delimiters from example using when (#10079) (#10081)
crypttab: removes jijna delimiters from example using when (#10079)

The current example includes extra jinja delimiters which
result in double-interpretation of the statement.

Fixes: #10078


(cherry picked from commit 1936fe5181)

Signed-off-by: Abhijeet Kasurde <Akasurde@redhat.com>
Co-authored-by: Abhijeet Kasurde <akasurde@redhat.com>
2025-04-29 23:14:40 +02:00
Felix Fontein
78e552469a Fix info on blanket license statement for changelog fragments.
(cherry picked from commit 8fa357e74b)
2025-04-24 22:49:51 +02:00
patchback[bot]
acdf0cdc2f [PR #10057/a720e994 backport][stable-9] Mark supervisorctl tests as unstable (#10059)
Mark supervisorctl tests as unstable (#10057)

Mark supervisorctl tests as unstable.

(cherry picked from commit a720e99482)

Co-authored-by: Felix Fontein <felix@fontein.de>
2025-04-23 07:07:55 +02:00
patchback[bot]
1246c3357b [PR #10051/4a2920b0 backport][stable-9] Remove FreeBSD 14.0 from CI (#10053)
Remove FreeBSD 14.0 from CI (#10051)

Remove FreeBSD 14.0 from CI.

In ansible-core it has been replaced with 14.1, but we're already testing against that.
Ref: 3546111f2d

(cherry picked from commit 4a2920b0fd)

Co-authored-by: Felix Fontein <felix@fontein.de>
2025-04-22 19:08:00 +02:00
Felix Fontein
c5f939fbc5 The next release will be 9.5.8. 2025-04-21 21:29:44 +02:00
Felix Fontein
666c07acee Release 9.5.7. 2025-04-21 21:08:31 +02:00
patchback[bot]
bcbd04a8fd [PR #10043/2a5abab7 backport][stable-9] Remove blanket skips for Python 3 in CI (#10047)
* Remove blanket skips for Python 3 in CI (#10043)

* Remove blanket skips for Python 3 in CI.

* Try to fix hg tests.

* Disable hg tests.

* Drop restriction of supervisor to <4.0.0.

This was introduced in https://github.com/ansible/ansible/pull/54935.

* Make tests work with supervisorctl 4.0.0.

According to https://supervisord.org/changes.html#id12,
"supervisorctl will now set its exit code to a non-zero value when an error condition occurs."
I'm not sure why a stopped service in 'status' constitutes an error condition,
but whatever 🤷...

* Use correct Python executable.

* Skip RHEL/macOS; diff on config write.

* Skip CentOS 7 and OpenSuSE on ansible-core 2.16.

(cherry picked from commit 2a5abab738)

* Skip OpenSuSE 15/Python 2 on ansible-core 2.13.

---------

Co-authored-by: Felix Fontein <felix@fontein.de>
2025-04-21 16:41:03 +02:00
Felix Fontein
36cb2c22a1 [stable-9] Use antsibull-nox instead of extra sanity test runner and extra workfows (#10041)
* Use antsibull-nox instead of extra sanity test runner and extra workflows (#10022)

* Use antsibull-nox instead of extra sanity test runner and extra workflows.

* Avoid sys.argv[0].

(cherry picked from commit 3ee55c6828)

* Action group keycloak does not exist in 9.x.y.
2025-04-21 14:28:09 +02:00
patchback[bot]
419893eb65 [PR #10005/e0a283bb backport][stable-9] Fix method exists in sysrc (#10033)
Fix method exists in sysrc (#10005)

* Fix method exists.

* Add changelog fragment.

* Update the exists method to pass the present method tests.

* Replace f-string formatting.

* Update changelogs/fragments/10005-fix-method-exists-in-sysrc.yml

Co-authored-by: Alexei Znamensky <103110+russoz@users.noreply.github.com>

* Add comment to the method exists.

* Update plugins/modules/sysrc.py

Co-authored-by: Alexei Znamensky <103110+russoz@users.noreply.github.com>

* Update changelogs/fragments/10005-fix-method-exists-in-sysrc.yml

Co-authored-by: Felix Fontein <felix@fontein.de>

* The improved comment formatting fixed.

---------

Co-authored-by: Alexei Znamensky <103110+russoz@users.noreply.github.com>
Co-authored-by: Felix Fontein <felix@fontein.de>
(cherry picked from commit e0a283bb36)

Co-authored-by: Vladimir Botka <vbotka@gmail.com>
2025-04-21 13:20:48 +02:00
patchback[bot]
2448503e8b [PR #10011/c2480730 backport][stable-9] fix: github_deploy_key check key exists on 422 (#10035)
fix: github_deploy_key check key exists on 422 (#10011)

* fix: github_deploy_key check key exists on 422

If we get a 422 response code as we add a key, check if it's because the key already exists or for another reason.

fixes: #6718

* chore: add changelog 10011-github_deploy_key-check-key-present

* chore: fix changelog fragment

* chore: fix changelog fragment

* Update changelog fragment.

---------

Co-authored-by: Felix Fontein <felix@fontein.de>
(cherry picked from commit c248073079)

Co-authored-by: Alex Garel <alex@garel.org>
2025-04-21 13:20:35 +02:00
patchback[bot]
8b1a193a49 [PR #9987/a8b97732 backport][stable-9] Fix Keycloak authentication flow configuration issues (#10017)
Fix Keycloak authentication flow configuration issues (#9987)

* Add delete_authentication_config method and integrate it into create_or_update_executions

* typo

* Sanity

* Add integration tests for keycloak_authentication module with README, tasks, and variables

* Add copyright and license information to access_token.yml

* Sanity

* Refactor Keycloak integration tests: streamline README, update access token task, and enhance variable management

* Maj changelogs fragments

---------

Co-authored-by: Andre Desrosiers <andre.desrosiers@ssss.gouv.qc.ca>
(cherry picked from commit a8b977320c)

Co-authored-by: desand01 <desrosiers.a@hotmail.com>
2025-04-19 09:33:59 +02:00
patchback[bot]
69bb4420d8 [PR #9952/1243846c backport][stable-9] improve ansible_host in proxmox inventory plugin (#10002)
improve ansible_host in proxmox inventory plugin (#9952)

* improve ansible_host in proxmox inventory plugin

I had this issue myself and found out there was already an issue thread:

https://github.com/ansible-collections/community.general/issues/5906

this fixes the issue for hope we can all benefit after this gets merged

* f string styling

* add log line for the successful address selection

* remove white space

* add changelog: 9952-proxmox-inventory-plugin-improve-ansible_host.yml

* Update changelogs/fragments/9952-proxmox-inventory-plugin-improve-ansible_host.yml

Co-authored-by: Felix Fontein <felix@fontein.de>

---------

Co-authored-by: Felix Fontein <felix@fontein.de>
(cherry picked from commit 1243846c3a)

Co-authored-by: Stein van Broekhoven <stein@aapjeisbaas.nl>
2025-04-16 21:06:02 +02:00
patchback[bot]
69590f55ac [PR #9976/04137746 backport][stable-9] keycloak_client: fix idempotency regression (#9996)
keycloak_client: fix idempotency regression (#9976)

* add function to normalize kc responses

* add changelog fragment

* Update changelogs/fragments/9976-keycloak_client-fix-idempotency-regression.yml

Co-authored-by: Felix Fontein <felix@fontein.de>

* add newline to changelog fragment

---------

Co-authored-by: Felix Fontein <felix@fontein.de>
(cherry picked from commit 0413774641)

Co-authored-by: gruenbauer@b1-systems.de <gruenbauer@b1-systems.de>
2025-04-14 22:51:06 +02:00
Felix Fontein
69cb9b7578 Prepare 9.5.7. 2025-04-14 22:11:16 +02:00
patchback[bot]
72e4deee9b [PR #9992/8525e420 backport][stable-9] Avoid deprecated AnsibleFilterTypeError (#9993)
Avoid deprecated AnsibleFilterTypeError (#9992)

Avoid deprecated AnsibleFilterTypeError.

(cherry picked from commit 8525e420bc)

Co-authored-by: Felix Fontein <felix@fontein.de>
2025-04-14 21:23:23 +02:00
Felix Fontein
f12f69d2a5 [stable-9] Make ready for data tagging (#9991)
Make ready for data tagging (#9833)

* Fix dependent lookup.

* Fix ansible_type plugin utils and adjust documentation of reveal_ansible_type filter and ansible_type test.

* Fix diy callback plugin.

* Adjust to Data Tagging.

* Vendor and use internal code from ansible-core to fix YAML callback.

Ref: https://github.com/ansible/ansible/issues/84781
(cherry picked from commit 04cfce78ea)
2025-04-14 21:23:04 +02:00
patchback[bot]
ff7a8f8018 [PR #9951/02ffb6e7 backport][stable-9] update PHP apache module workaround (#9978)
update PHP apache module workaround (#9951)

* update php apache module workaround

* Update apache2_module.py

* Update apache2_module.py

* Update apache2_module.py

* add changelog fragment

* Update changelogs/fragments/9951-mod-php-identifier.yml

Co-authored-by: Alexei Znamensky <103110+russoz@users.noreply.github.com>

* Update 9951-mod-php-identifier.yml

---------

Co-authored-by: Alexei Znamensky <103110+russoz@users.noreply.github.com>
(cherry picked from commit 02ffb6e7e3)

Co-authored-by: simonLeary42 <71396965+simonLeary42@users.noreply.github.com>
2025-04-10 07:27:01 +02:00
patchback[bot]
08cfbf4f99 [PR #9963/34b6fb74 backport][stable-9] proxmox_disk: fail gracefully if storage hasn't been provided by the user (#9967)
proxmox_disk: fail gracefully if storage hasn't been provided by the user (#9963)

Fail gracefully if storage hasn't been provided by the user.

(cherry picked from commit 34b6fb74eb)

Co-authored-by: Felix Fontein <felix@fontein.de>
2025-04-06 14:24:04 +02:00
Felix Fontein
513ea79c19 Migrate .reuse/dep5 to REUSE.toml.
(cherry picked from commit 70b5e362f9)
2025-03-29 13:46:29 +01:00
patchback[bot]
0409f4048b [PR #9945/e5e33534 backport][stable-9] Simplify YAML callback tests (#9947)
Simplify YAML callback tests (#9945)

Simplify YAML callback tests.

(cherry picked from commit e5e335348a)

Co-authored-by: Felix Fontein <felix@fontein.de>
2025-03-29 11:01:57 +01:00
Felix Fontein
3aa6185f09 Next expected release will be 9.5.7. 2025-03-24 22:10:59 +01:00
Felix Fontein
9a7fb38301 Release 9.5.6. 2025-03-24 21:02:34 +01:00
patchback[bot]
0b33bf4e5a [PR #9910/1fbf5d8e backport][stable-9] proxmox_vm_info: don't expect key 'template' exists in dictionary (#9934)
proxmox_vm_info: don't expect key 'template' exists in dictionary (#9910)

* don't expect key 'template' exists

* add changelog fragment

* Update changelogs/fragments/9875-proxmox-dont-expect-key-template-to-exist.yml

Co-authored-by: Felix Fontein <felix@fontein.de>

---------

Co-authored-by: Felix Fontein <felix@fontein.de>
(cherry picked from commit 1fbf5d8eb4)

Co-authored-by: florianfischer91 <72799603+florianfischer91@users.noreply.github.com>
2025-03-24 05:52:45 +01:00
Felix Fontein
961a7cea8b [stable-9] The yarn module is Yarn Classic only at the moment (#9928)
The yarn module is Yarn Classic only at the moment (#9926)

The yarn module is Yarn Classic only.

(cherry picked from commit cb776e7cd5)
2025-03-23 15:15:41 +01:00
patchback[bot]
7916877179 [PR #9867/ec38a82e backport][stable-9] tests: enable copr tests (#9930)
tests: enable copr tests (#9867)

[WIP] tests: enable copr tests

Signed-off-by: Abhijeet Kasurde <Akasurde@redhat.com>
(cherry picked from commit ec38a82ef1)

Co-authored-by: Abhijeet Kasurde <akasurde@redhat.com>
2025-03-23 15:14:55 +01:00
Felix Fontein
7df07f31a6 [stable-9] Unit tests: replace mock and compat with code from community.internal_test_tools (#9923)
* Unit tests: replace mock and compat with code from community.internal_test_tools (#9921)

* Replace compat with equivalent from community.internal_test_tools.

* Replace mock with equivalent from community.internal_test_tools.

* Remove ignore.txt entries.

* Add test that's no longer present in later versions.
2025-03-22 14:32:01 +01:00
Felix Fontein
928cdaaf87 [stable-9] Use more unit test utils from community.internal_test_tools (#9920)
Use more unit test utils from community.internal_test_tools (#9918)

* Make conftest's patch_ansible_module use the context manager from .utils.

* Fix test dependencies.

* Use module mock utils from community.internal_test_tools.

* Use DataDictLoader from community.internal_test_tools.

* Use trust util from community.internal_test_tools.

(cherry picked from commit 8ab8010b6d)
2025-03-22 14:12:44 +01:00
patchback[bot]
3727bf7cd4 [PR #9880/3922b82a backport][stable-9] nmcli: fix reordering of DNS nameservers and search suffixes (#9911)
nmcli: fix reordering of DNS nameservers and search suffixes (#9880)

* nmcli: fix reordering of DNS nameservers and search suffixes

- Fixes #8724

* Update changelog fragment index in line with PR number

- Now I understand what that number is for

* Use correct changelog format for nmcli PR #9880

(cherry picked from commit 3922b82a57)

Co-authored-by: ashleyghooper <ashleyghooper@gmail.com>
2025-03-21 21:50:35 +01:00
patchback[bot]
845b13d5aa [PR #9904/e3d92491 backport][stable-9] Add caddy example to copr module (#9914)
Add caddy example to copr module (#9904)

Add caddy example to copr.py

(cherry picked from commit e3d92491a3)

Co-authored-by: Elijah Lopez <elijahllopezz@gmail.com>
2025-03-21 21:50:26 +01:00
Felix Fontein
fa3e6673d0 Prepare 9.5.6. 2025-03-21 21:07:32 +01:00
patchback[bot]
84033ec80a [PR #9900/6a2d9ccd backport][stable-9] sysrc: extend the list of FreeBSD releases where the jail test fails (#9902)
sysrc: extend the list of FreeBSD releases where the jail test fails (#9900)

Extend the list of FreeBSD releases where the jail test fails.

(cherry picked from commit 6a2d9ccd99)

Co-authored-by: Felix Fontein <felix@fontein.de>
2025-03-18 22:14:22 +01:00
patchback[bot]
3bceabce93 [PR #9881/e5eac9fe backport][stable-9] homebrew_cask: Handle unusual brew version strings (#9888)
homebrew_cask: Handle unusual brew version strings (#9881)

* Use regex to parse unusual brew version strings

Fixes: #8432

Signed-off-by: Abhijeet Kasurde <Akasurde@redhat.com>
(cherry picked from commit e5eac9fed1)

Co-authored-by: Abhijeet Kasurde <akasurde@redhat.com>
2025-03-15 09:22:42 +01:00
patchback[bot]
0dd960d8ab [PR #9871/dd0a2cbf backport][stable-9] sudoers: display stderr raised while validation (#9884)
sudoers: display stderr raised while validation (#9871)

* sudoers: display stderr raised while validation

* Print stdout and stderr raised from sudoers validation

Fixes: #9674

Signed-off-by: Abhijeet Kasurde <Akasurde@redhat.com>

* Apply suggestions from code review

Co-authored-by: Felix Fontein <felix@fontein.de>

---------

Signed-off-by: Abhijeet Kasurde <Akasurde@redhat.com>
Co-authored-by: Felix Fontein <felix@fontein.de>
(cherry picked from commit dd0a2cbff9)

Co-authored-by: Abhijeet Kasurde <akasurde@redhat.com>
2025-03-15 07:46:11 +01:00
patchback[bot]
e1b338cf41 [PR #9694/d5add1ed backport][stable-9] ipa_host: Maintain the host certificates (#9720)
ipa_host: Maintain the host certificates (#9694)

* ipa_host: Maintain the host certificates

Fix #9693

* Add changelog fragment

* Fix changelog message

* Fix changelog message again

(cherry picked from commit d5add1ed9f)

Co-authored-by: sedrubal <sedrubal@users.noreply.github.com>
2025-03-12 18:09:35 +01:00
patchback[bot]
f2e8354229 [PR #9872/fdbc06c7 backport][stable-9] CI: Add FreeBSD 13.5 (#9873)
CI: Add FreeBSD 13.5 (#9872)

Add FreeBSD 13.5.

(cherry picked from commit fdbc06c714)

Co-authored-by: Felix Fontein <felix@fontein.de>
2025-03-12 18:09:20 +01:00
patchback[bot]
abc435466d [PR #9846/86dea88c backport][stable-9] dnf_versionlock: add support for Fedora 41 and dnf5 (#9864)
dnf_versionlock: add support for Fedora 41 and dnf5 (#9846)

Fixes: #9556

Signed-off-by: Abhijeet Kasurde <Akasurde@redhat.com>
(cherry picked from commit 86dea88cb6)

Co-authored-by: Abhijeet Kasurde <akasurde@redhat.com>
2025-03-10 06:31:05 +01:00
patchback[bot]
3c49c096a9 [PR #9845/7d5357d7 backport][stable-9] Fix roles/policies normalization in consul_token. (#9862)
Fix roles/policies normalization in consul_token. (#9845)

* Fix roles/policies normalization in consul_token.

* Update changelogs/fragments/9845-consul_token_idempotency.yml

Co-authored-by: Felix Fontein <felix@fontein.de>

---------

Co-authored-by: Felix Fontein <felix@fontein.de>
(cherry picked from commit 7d5357d74c)

Co-authored-by: Florian Apolloner <florian@apolloner.eu>
2025-03-10 06:30:50 +01:00
Felix Fontein
de754eacbc [stable-9] Fix/improve tests (#9861)
Fix/improve tests (#9859)

* Fix tests.

* Improve callback tests.

(cherry picked from commit eff25c8a6e)
2025-03-09 17:15:21 +01:00
patchback[bot]
0ccb961ff7 [PR #9853/4727fb77 backport][stable-9] cmd_runner tests: fix reliance on unspecified behavior (#9856)
cmd_runner tests: fix reliance on unspecified behavior (#9853)

Fix reliance on unspecified behavior.

(cherry picked from commit 4727fb77b3)

Co-authored-by: Felix Fontein <felix@fontein.de>
2025-03-09 08:56:49 +01:00
patchback[bot]
c6429e7740 [PR #9850/9df84654 backport][stable-9] Improve/fix unit tests (#9851)
Improve/fix unit tests (#9850)

* Improve/fix tests.

* Fix cargo test.

(cherry picked from commit 9df8465476)

Co-authored-by: Felix Fontein <felix@fontein.de>
2025-03-08 16:42:08 +01:00
patchback[bot]
ba7439e657 [PR #9842/c46575cf backport][stable-9] Simplify module_utils unit tests (#9843)
Simplify module_utils unit tests (#9842)

Simplify module_utils unit tests.

(cherry picked from commit c46575cf06)

Co-authored-by: Felix Fontein <felix@fontein.de>
2025-03-07 18:33:16 +01:00
Felix Fontein
013fb9c006 [stable-9] Unit tests: make set_module_args() a context manager, and remove copies of it in some tests (#9840)
Unit tests: make set_module_args() a context manager, and remove copies of it in some tests (#9838)

Make set_module_args() a context manager, and remove copies of set_module_args().

Prepares for Data Tagging.

(cherry picked from commit a1781d09dd)
2025-03-07 07:31:42 +01:00
patchback[bot]
9a6bd80613 [PR #9819/5f48f2ca backport][stable-9] Example typo in homebrew_services.py (#9826)
Example typo in homebrew_services.py (#9819)

Maybe this was mixed up with the _brew_service_state() function? I get this error as-written:
```
fatal: [eahmm3]: FAILED! => {"changed": false, "msg": "Unsupported parameters for (community.general.homebrew_services) module: service
_state. Supported parameters include: name, path, state (formula)."}
```

(cherry picked from commit 5f48f2ca0d)

Co-authored-by: Ernie Hershey <github@ernie.org>
2025-03-03 21:30:37 +01:00
patchback[bot]
17d11cb587 [PR #9828/77dc0868 backport][stable-9] homebrew_services: skip tests on macOS 13.2 and 14.3 (#9829)
homebrew_services: skip tests on macOS 13.2 and 14.3 (#9828)

Skip tests on macOS 13.2 and 14.3.

(cherry picked from commit 77dc086896)

Co-authored-by: Felix Fontein <felix@fontein.de>
2025-03-03 21:30:25 +01:00
patchback[bot]
933166b984 [PR #9818/3b6efd5c backport][stable-9] cloudflare_dns: handle exhausted response stream in case of http error (#9822)
cloudflare_dns: handle exhausted response stream in case of http error (#9818)

* cloudflare_dns: handle exhausted response stream in case of http error

* Update changelogs/fragments/9818-cloudflare-dns-exhausted-response.yml

Co-authored-by: Felix Fontein <felix@fontein.de>

---------

Co-authored-by: Felix Fontein <felix@fontein.de>
(cherry picked from commit 3b6efd5cbc)

Co-authored-by: Kristian Heljas <11139388+kristianheljas@users.noreply.github.com>
2025-03-03 07:24:08 +01:00
patchback[bot]
162add04b9 [PR #9812/cf147b9f backport][stable-9] misc typo fix (#9815)
misc typo fix (#9812)

Signed-off-by: Abhijeet Kasurde <Akasurde@redhat.com>
(cherry picked from commit cf147b9fca)

Co-authored-by: Abhijeet Kasurde <akasurde@redhat.com>
2025-03-01 11:30:56 +01:00
patchback[bot]
faaeacfaa0 [PR #9805/dd4268e0 backport][stable-9] CI: Add macOS 15.3 (#9807)
CI: Add macOS 15.3 (#9805)

* Add macOS 15.3.

* Install setuptools on macOS 15.

(cherry picked from commit dd4268e0d9)

Co-authored-by: Felix Fontein <felix@fontein.de>
2025-02-26 22:02:35 +01:00
Felix Fontein
bbf3cae316 Next expected release will be 9.5.6. 2025-02-24 07:04:41 +01:00
Felix Fontein
53ebbe4b94 Release 9.5.5. 2025-02-24 06:46:51 +01:00
patchback[bot]
2674e2494d [PR #9796/217a1883 backport][stable-9] locale_gen: enable tests for Arch Linux, make sure they don't even try to run on RHEL and Fedora VMs (#9797)
locale_gen: enable tests for Arch Linux, make sure they don't even try to run on RHEL and Fedora VMs (#9796)

Enable locale_gen tests for Arch Linux, make sure they don't even try to run on RHEL and Fedora VMs.

(cherry picked from commit 217a18839d)

Co-authored-by: Felix Fontein <felix@fontein.de>
2025-02-23 15:27:01 +01:00
patchback[bot]
341f86e2bc [PR #9788/bb2c45b5 backport][stable-9] json_query filter docs: fix typo cluster2 when cluster1 is mentioned (#9792)
json_query filter docs: fix typo cluster2 when cluster1 is mentioned (#9788)

Typo cluster2 but cluster1 is mentioned

(cherry picked from commit bb2c45b5bb)

Co-authored-by: Kloppi313 <36038231+Kloppi313@users.noreply.github.com>
2025-02-21 20:50:41 +01:00
patchback[bot]
dd63fb5347 [PR #9774/ddc1ea6a backport][stable-9] Fix proxy settings for elasticsearch_plugin.py (#9785)
Fix proxy settings for elasticsearch_plugin.py (#9774)

elasticsearch_plugin: fix error when setting proxy settings

Co-authored-by: Tim Hovius <w.hovius@rechtspraak.nl>
(cherry picked from commit ddc1ea6ae4)

Co-authored-by: Tim Hovius <timhovius@gmail.com>
2025-02-20 22:27:19 +01:00
patchback[bot]
b418b2c00d [PR #9778/203c1ecf backport][stable-9] redhat_registration: use 'enable_content' D-Bus option when available (#9783)
redhat_registration: use 'enable_content' D-Bus option when available (#9778)

This makes sure that subscription-manager always enables the content for
the system right after the registration.

This is particular important on EL 10+ and Fedora 41+.

(cherry picked from commit 203c1ecfec)

Co-authored-by: Pino Toscano <ptoscano@redhat.com>
2025-02-20 22:26:59 +01:00
patchback[bot]
382c0a4af6 [PR #9106/105ae056 backport][stable-9] bugfix - Prevent passwordstore lookup to create subkey when create == false (#9779)
bugfix - Prevent passwordstore lookup to create subkey when create == false (#9106)

Fixes #9105

Apply suggestion

Co-authored-by: Felix Fontein <felix@fontein.de>
(cherry picked from commit 105ae0566a)

Co-authored-by: Manuel Luzarreta <mluzarreta.pro@pm.me>
2025-02-19 22:30:22 +01:00
Felix Fontein
1a0a44d179 [stable-9] Make apache2_mod_proxy work with Python 3, half-way modern Apache 2 versions, and add basic tests (#9772)
* Make apache2_mod_proxy work with Python 3, half-way modern Apache 2 versions, and add basic tests (#9762)

* Move Apache 2 installation to setup role.

* Make module work with Python 3.

* Add basic tests.

* Add changelog fragment.

* Simplify change.

* Pass referer.

* apache2_mod_proxy: follow-up for #9762, forgot one place with find_all/findAll (#9775)

Follow-up for #9762, forgot one place.

(cherry picked from commit 8e36fd4847)
2025-02-18 21:53:18 +01:00
patchback[bot]
18e4637042 [PR #9760/d696bb7b backport][stable-9] proxmox inventory: proposal for #9710 (caching) (#9769)
proxmox inventory: proposal for #9710 (caching) (#9760)

* Proposal for #9710

* Fixed comments

* Fixed trailing whitespace

* Fixed changelog fragment

(cherry picked from commit d696bb7b89)

Co-authored-by: Dirk S. <iqt4@users.noreply.github.com>
2025-02-17 19:26:01 +01:00
Felix Fontein
fb68abd6b2 Prepare 9.5.5. 2025-02-16 20:28:09 +01:00
patchback[bot]
2d5999c579 [PR #9739/b2e2d2d3 backport][stable-9] keycloak_client: compare desired and before dicts directly in checkmode (#9758)
keycloak_client: compare desired and before dicts directly in checkmode (#9739)

* compare desired and before dicts directly in checkmode

* fix authorizationServicesEnabled being dropped by kc if unset

* only add authorizationsServicesEnabled=false if before_client exists

* add changelog fragment

* Update changelog.

---------

Co-authored-by: Felix Fontein <felix@fontein.de>
(cherry picked from commit b2e2d2d37b)

Co-authored-by: gruenbauer@b1-systems.de <gruenbauer@b1-systems.de>
2025-02-16 12:38:02 +01:00
patchback[bot]
525ed41a0a [PR #9727/910c57aa backport][stable-9] keycloak: repair integration tests by removing jinja2 templating from conditionals (#9726) (#9747)
keycloak: repair integration tests by removing jinja2 templating from conditionals (#9726) (#9727)

* fix: remove jinja2 templating from conditionals in keycloak_role module integration tests (#9726)

* fix: remove jinja2 templating in conditional in keycloak clientsecret info integration test (#9726)

This test needs a further fix; see #9744. Left for a future PR for now.

* fix: remove jinja2 templating in conditional in keycloak clientsecret regenerate integration test (#9726)

* chore: remove jinja2 templating in conditional in keycloak user federation integration test (#9726)

These instances of templating were not causing failures,
but this removes the warnings.

* chore: remove jinja2 templating in conditional in keycloak user rolemapping integration test (#9726)

These instances of templating were not causing failures,
but this removes the warnings.

* docs: add changelog fragment (#9726)

* docs: repair changelog fragment yaml (#9726)

* docs: actually repair changelog fragment yaml (#9726)

* chore: remove changelog fragment for test only pr (#9726)

(cherry picked from commit 910c57aaa0)

Co-authored-by: Mark Armstrong <markparmstrong@gmail.com>
2025-02-15 12:31:37 +01:00
patchback[bot]
4a4fe8c61f [PR #9722/d756aeb6 backport][stable-9] CI: Cleanup AZP config similarly to ansible-core did some years ago (#9724)
CI: Cleanup AZP config similarly to ansible-core did some years ago (#9722)

Cleanup AZP config similarly to ansible-core did some years ago.

(cherry picked from commit d756aeb6ce)

Co-authored-by: Felix Fontein <felix@fontein.de>
2025-02-10 23:19:52 +01:00
patchback[bot]
f9e4bc85e9 [PR #9695/191a4d8f backport][stable-9] xml: ensure the stream object is closed in main() (#9711)
xml: ensure the stream object is closed in main() (#9695)

* ensure the stream object is closed in main()

* add changelog frag

* Update plugins/modules/xml.py

Co-authored-by: Felix Fontein <felix@fontein.de>

* Update plugins/modules/xml.py

Co-authored-by: Felix Fontein <felix@fontein.de>

---------

Co-authored-by: Felix Fontein <felix@fontein.de>
(cherry picked from commit 191a4d8f63)

Co-authored-by: Alexei Znamensky <103110+russoz@users.noreply.github.com>
2025-02-09 14:26:42 +01:00
patchback[bot]
bde1c721e0 [PR #9705/efe0c464 backport][stable-9] Disable failing copr tests (#9708)
Disable failing copr tests (#9705)

Disable failing copr tests.

(cherry picked from commit efe0c464ff)

Co-authored-by: Felix Fontein <felix@fontein.de>
2025-02-09 12:41:35 +01:00
Felix Fontein
285c97e7ea Fix typo.
(cherry picked from commit d6943c9838)
2025-02-09 08:11:06 +01:00
patchback[bot]
d45a889c3f [PR #9699/10c15d31 backport][stable-9] filesystem tests: reiserfsprogs is no longer available on Arch Linux (#9701)
filesystem tests: reiserfsprogs is no longer available on Arch Linux (#9699)

reiserfsprogs is no longer available on Arch Linux.

(cherry picked from commit 10c15d31f7)

Co-authored-by: Felix Fontein <felix@fontein.de>
2025-02-08 20:25:38 +01:00
patchback[bot]
1e7294716e [PR #9686/0b4337c1 backport][stable-9] Also disable snap_alias tests for RHEL 8.8 (#9688)
Also disable snap_alias tests for RHEL 8.8 (#9686)

Also disable snap_alias tests for RHEL 8.8.

(cherry picked from commit 0b4337c13d)

Co-authored-by: Felix Fontein <felix@fontein.de>
2025-02-04 22:29:23 +01:00
patchback[bot]
88c605a344 [PR #9679/54eec2cb backport][stable-9] Disable snap tests on RHEL 8.8 (#9681)
Disable snap tests on RHEL 8.8 (#9679)

Disable snap tests on RHEL 8.8.

(cherry picked from commit 54eec2cb09)

Co-authored-by: Felix Fontein <felix@fontein.de>
2025-02-03 10:53:45 +01:00
patchback[bot]
4a41ab583a [PR #9644/250dc113 backport][stable-9] Fb keycloak client improvement (#9670)
Fb keycloak client improvement (#9644)

* Fix for failed test

TASK [keycloak_client : Assert changes not detected in last two tasks (desire when same, and check)] ***
task path: /root/ansible_collections/community/general/tests/output/.tmp/integration/keycloak_client-p3ttqf7d-ÅÑŚÌβŁÈ/tests/integration/targets/keycloak_client/tasks/main.yml:79
fatal: [testhost]: FAILED! => {
    "assertion": "check_client_when_present_and_same is not changed",
    "changed": false,
    "evaluated_to": false,
    "msg": "Assertion failed"
}

* Improved test data to test more scenarios, e.g documentation uses True in examples

* Normalize values in config

* add changelog

* Apply suggestions from code review

Co-authored-by: Alexei Znamensky <103110+russoz@users.noreply.github.com>

* Update tests/integration/targets/keycloak_client/vars/main.yml

Co-authored-by: Alexei Znamensky <103110+russoz@users.noreply.github.com>

* Update changelogs/fragments/9644-kc_client-test-improvement-and-fix.yaml

Co-authored-by: Alexei Znamensky <103110+russoz@users.noreply.github.com>

---------

Co-authored-by: Alexei Znamensky <103110+russoz@users.noreply.github.com>
(cherry picked from commit 250dc1139c)

Co-authored-by: amPrimeSign <146177975+amPrimeSign@users.noreply.github.com>
2025-02-01 22:46:10 +01:00
patchback[bot]
5d86045048 [PR #9649/19d00496 backport][stable-9] cloudflare_dns: fix crash when deleting a DNS record or when updating a record with solo=true (#9654)
cloudflare_dns: fix crash when deleting a DNS record or when updating a record with solo=true (#9649)

* cloudflare_dns: fix crash when deleting a DNS record or when updating a record with solo=true

On 2025-01-27, Cloudflare removed the 'zone_id' field from the DNS record API responses. This caused a KeyError in the delete_dns_records method, which previously relied on rr['zone_id'].

This commit ensures the zone ID is retrieved via _get_zone_id() rather than using the no-longer-provided 'zone_id' field in the record response.

Reference: https://developers.cloudflare.com/dns/changelog/#2025-01-27

* Add changelog fragment

* Update changelogs/fragments/9649-cloudflare_dns-fix-crash-when-deleting-record.yml

Co-authored-by: Felix Fontein <felix@fontein.de>

* Update changelogs/fragments/9649-cloudflare_dns-fix-crash-when-deleting-record.yml

Co-authored-by: Felix Fontein <felix@fontein.de>

---------

Co-authored-by: Felix Fontein <felix@fontein.de>
(cherry picked from commit 19d0049698)

Co-authored-by: valievkarim <valievkarim@gmail.com>
2025-01-31 10:57:21 +01:00
Felix Fontein
2eb067e3e0 The next release will be 9.5.5. 2025-01-27 06:56:49 +01:00
Felix Fontein
2ffbfef2ff Release 9.5.4. 2025-01-27 06:27:46 +01:00
patchback[bot]
b23eb4babd [PR #9621/fb4f7248 backport][stable-9] keycloak_client: sanitize saml.encryption.private.key (#9629)
keycloak_client: sanitize `saml.encryption.private.key` (#9621)

* sanitize saml.encryption.private.key in module output

* add changelog fragment

* Re-categorize changelog fragment.

---------

Co-authored-by: Felix Fontein <felix@fontein.de>
(cherry picked from commit fb4f7248c9)

Co-authored-by: fgruenbauer <gruenbauer@b1-systems.de>
2025-01-26 13:22:53 +01:00
patchback[bot]
56a906e42b [PR #9578/bcc92e8a backport][stable-9] redhat_subscription: stop manual unsubscribing on unregistration (#9589)
redhat_subscription: stop manual unsubscribing on unregistration (#9578)

Unregistering a system also drops all the resources for it
automatically, so there is no need to manually unsubscribing (which
actually means removing all the subscriptions).

In addition to that, newer versions of subscription-manager drop all the
support for entitlements, so the "remove" subcommand (used by
unsubscribe()) does not exist anymore, and thus the unregistration fails
with those versions.

This fixes the registration on EL 10 systems, and Fedora 41 and greater.

(cherry picked from commit bcc92e8aac)

Co-authored-by: Pino Toscano <ptoscano@redhat.com>
2025-01-20 19:47:17 +01:00
patchback[bot]
0361154ff3 [PR #9552/bf69dc46 backport][stable-9] CI: Add Fedora 41, Alpine 3.21, RHEL 9.5, FreeBSD 14.2 to CI for devel (#9557)
CI: Add Fedora 41, Alpine 3.21, RHEL 9.5, FreeBSD 14.2 to CI for devel (#9552)

* Add Fedora 41, Alpine 3.21, RHEL 9.5, FreeBSD 14.2 to CI for devel.

* Add some ignores that are likely needed.

* Try to fix/ignore various errors.

* Fix redis setup on Fedora 41.

* Undo disable yum_versionlock since it's already globally disabled.

(cherry picked from commit bf69dc46ff)

Co-authored-by: Felix Fontein <felix@fontein.de>
2025-01-08 19:32:03 +01:00
patchback[bot]
d1f7752b57 [PR #9542/81ea9f69 backport][stable-9] Add hkariti to notifications ignore list (#9549)
Add hkariti to notifications ignore list (#9542)

* Add hkariti to notifications ignore list

* Update .github/BOTMETA.yml

Co-authored-by: Felix Fontein <felix@fontein.de>

---------

Co-authored-by: Felix Fontein <felix@fontein.de>
(cherry picked from commit 81ea9f69bf)

Co-authored-by: Hagai Kariti <hkariti@gmail.com>
2025-01-07 19:08:58 +01:00
Felix Fontein
c6e557b1ec Fix CI badge image URL. Add documentation badge.
(cherry picked from commit 007302d5af)
2025-01-04 11:29:11 +01:00
patchback[bot]
ec183626e5 [PR #9518/d7da0ae7 backport][stable-9] remove stearz as maintainer (#9520)
remove stearz as maintainer (#9518)

* remove stearz as maintainer

As I do not work with Sophos UTMs anymore I am no longer able to test/maintain. - I added team_e_spirit as maintainer as I think they are still using and willing to support the modules.

* added ignore lines to remove stearz as maintainer

(cherry picked from commit d7da0ae7f6)

Co-authored-by: Stephan Schwarz <22387558+stearz@users.noreply.github.com>
2025-01-03 20:07:05 +01:00
Felix Fontein
af762a4c4e The next release will be 9.5.4. 2024-12-31 13:36:27 +01:00
Felix Fontein
124246b763 Release 9.5.3. 2024-12-31 11:50:52 +01:00
patchback[bot]
cb4b8bc3cc [PR #9498/7f3fef30 backport][stable-9] fix typo (#9501)
fix typo (#9498)

(cherry picked from commit 7f3fef3038)

Co-authored-by: Alexei Znamensky <103110+russoz@users.noreply.github.com>
2024-12-31 10:41:16 +01:00
patchback[bot]
c7773afebf [PR #9490/1e28302a backport][stable-9] htpasswd: let changed reflect updated permissions (#9492)
htpasswd: let changed reflect updated permissions (#9490)

* Let changed reflect updated permissions.

* Make pylint happy.

(cherry picked from commit 1e28302a66)

Co-authored-by: Felix Fontein <felix@fontein.de>
2024-12-31 10:28:53 +01:00
patchback[bot]
ae8015667c [PR #9470/f55899d6 backport][stable-9] svc: adjustments to docs (#9478)
svc: adjustments to docs (#9470)

* svc: adjustments to docs

* Update plugins/modules/svc.py

Co-authored-by: Felix Fontein <felix@fontein.de>

---------

Co-authored-by: Felix Fontein <felix@fontein.de>
(cherry picked from commit f55899d6ef)

Co-authored-by: Alexei Znamensky <103110+russoz@users.noreply.github.com>
2024-12-30 20:00:20 +01:00
patchback[bot]
e98daa9f39 [PR #9277/403418f7 backport][stable-9] proxmox_template: fix the wrong path called on proxmox_template.task_status (#9475)
proxmox_template: fix the wrong path called on proxmox_template.task_status (#9277)

fix: add missing 's' on proxmox_template.task_status

Missing the 's' means using the wrong API, making log reading
impossible. Should fix !9276

Signed-off-by: Alexandre Nicolaie <xunleii@users.noreply.github.com>
Co-authored-by: Felix Fontein <felix@fontein.de>
(cherry picked from commit 403418f75d)

Co-authored-by: Alexandre Nicolaie <xunleii@users.noreply.github.com>
2024-12-30 12:55:18 +01:00
patchback[bot]
6f3cfd3385 [PR #9455/d887930e backport][stable-9] normalize docs in callback plugins (#9466)
normalize docs in callback plugins (#9455)

* normalize docs in callback plugins

Normalize doc blocks for plugins

* Apply suggestions from code review

Co-authored-by: Felix Fontein <felix@fontein.de>

---------

Co-authored-by: Felix Fontein <felix@fontein.de>
(cherry picked from commit d887930e49)

Co-authored-by: Alexei Znamensky <103110+russoz@users.noreply.github.com>
2024-12-29 21:24:13 +01:00
patchback[bot]
015496fa9e [PR #9453/040cd0ca backport][stable-9] normalize docs in cache/connection plugins (#9461)
normalize docs in cache/connection plugins (#9453)

Normalize doc blocks for plugins

(cherry picked from commit 040cd0ca50)

Co-authored-by: Alexei Znamensky <103110+russoz@users.noreply.github.com>
2024-12-29 14:12:48 +01:00
patchback[bot]
f44697016f [PR #9256/d8b38073 backport][stable-9] proxmox_disk: fix async method of resize_disk (#9438)
proxmox_disk: fix async method of resize_disk (#9256)

* proxmox_disk: fix async method of resize_disk

Rewritten resizing of disk into separated function and used async method to retrieve task result. Additionally, rewritten function to detect failed tasks early, without waiting for timeout.

* proxmox_disk: add changelog fragment

* proxmox_disk: fix sanity errors

* Apply suggestions from code review

Co-authored-by: Alexei Znamensky <103110+russoz@users.noreply.github.com>

* proxmox_disk: workaround for legacy Proxmox

* Apply suggestions from code review

Co-authored-by: Felix Fontein <felix@fontein.de>

* Apply suggestions from the review

---------

Co-authored-by: Alexei Znamensky <103110+russoz@users.noreply.github.com>
Co-authored-by: Felix Fontein <felix@fontein.de>
(cherry picked from commit d8b38073c1)

Co-authored-by: castorsky <csky57@gmail.com>
2024-12-28 14:43:25 +01:00
patchback[bot]
0bc4970953 [PR #9423/0afd3386 backport][stable-9] [m-z]*.py: normalize doc_fragments (#9429)
[m-z]*.py: normalize doc_fragments (#9423)

(cherry picked from commit 0afd3386d1)

Co-authored-by: Alexei Znamensky <103110+russoz@users.noreply.github.com>
2024-12-27 14:52:32 +01:00
patchback[bot]
4dd76284e9 [PR #9393/84655b0d backport][stable-9] i[b-n]*.py: normalize docs (#9411)
i[b-n]*.py: normalize docs (#9393)

* i[b-n]*.py: normalize docs

* Update plugins/modules/ilo_redfish_command.py

Co-authored-by: Felix Fontein <felix@fontein.de>

---------

Co-authored-by: Felix Fontein <felix@fontein.de>
(cherry picked from commit 84655b0d0f)

Co-authored-by: Alexei Znamensky <103110+russoz@users.noreply.github.com>
2024-12-26 22:44:38 +01:00
patchback[bot]
a66b9fc5c9 [PR #9395/3048d530 backport][stable-9] g*.py: normalize docs (#9414)
g*.py: normalize docs (#9395)

* g*.py: normalize docs

* Update plugins/modules/gandi_livedns.py

Co-authored-by: Felix Fontein <felix@fontein.de>

---------

Co-authored-by: Felix Fontein <felix@fontein.de>
(cherry picked from commit 3048d5305d)

Co-authored-by: Alexei Znamensky <103110+russoz@users.noreply.github.com>
2024-12-26 22:44:22 +01:00
patchback[bot]
87d63c5bed [PR #9394/912065ad backport][stable-9] h*.py: normalize docs (#9416)
h*.py: normalize docs (#9394)

* h*.py: normalize docs

* Apply suggestions from code review

Co-authored-by: Felix Fontein <felix@fontein.de>

---------

Co-authored-by: Felix Fontein <felix@fontein.de>
(cherry picked from commit 912065ad0e)

Co-authored-by: Alexei Znamensky <103110+russoz@users.noreply.github.com>
2024-12-26 22:44:12 +01:00
Felix Fontein
e1d229f2c5 [stable-9] dig: handle NoNameservers exception (#9363) (#9410)
dig: handle NoNameservers exception (#9363)

Handle NoNameservers.

(cherry picked from commit 61b2304f4d)
2024-12-26 17:13:08 +01:00
patchback[bot]
7506742c38 [PR #9352/9fc3092b backport][stable-9] s[e-n]*: normalize docs (#9398)
s[e-n]*: normalize docs (#9352)

* s[e-n]*: normalize docs

* Apply suggestions from code review

Co-authored-by: Felix Fontein <felix@fontein.de>

* quote line with : and remove extraneous notes

* Update plugins/modules/slack.py

Co-authored-by: Felix Fontein <felix@fontein.de>

* Update plugins/modules/seport.py

Co-authored-by: Felix Fontein <felix@fontein.de>

---------

Co-authored-by: Felix Fontein <felix@fontein.de>
(cherry picked from commit 9fc3092bb3)

Co-authored-by: Alexei Znamensky <103110+russoz@users.noreply.github.com>
2024-12-26 08:39:24 +01:00
patchback[bot]
c64705474d [PR #9372/bef82e28 backport][stable-9] p[a-e]*: normalize docs (#9396)
p[a-e]*: normalize docs (#9372)

* p[a-e]*: normalize docs

* Update plugins/modules/packet_volume.py

Co-authored-by: Felix Fontein <felix@fontein.de>

---------

Co-authored-by: Felix Fontein <felix@fontein.de>
(cherry picked from commit bef82e28a2)

Co-authored-by: Alexei Znamensky <103110+russoz@users.noreply.github.com>
2024-12-26 08:39:12 +01:00
Felix Fontein
b8968c5c1c Prepare 9.5.3 release. 2024-12-25 23:00:34 +01:00
patchback[bot]
1ccfc3b821 [PR #9353/70b62ed7 backport][stable-9] s[a-c]*: normalize docs (#9375)
s[a-c]*: normalize docs (#9353)

* s[a-c]*: normalize docs

* Apply suggestions from code review

Co-authored-by: Felix Fontein <felix@fontein.de>

---------

Co-authored-by: Felix Fontein <felix@fontein.de>
(cherry picked from commit 70b62ed745)

Co-authored-by: Alexei Znamensky <103110+russoz@users.noreply.github.com>
2024-12-25 21:41:01 +01:00
patchback[bot]
595c105a29 [PR #9351/4b23e5ec backport][stable-9] s[o-y]*: normalize docs (#9368)
s[o-y]*: normalize docs (#9351)

* s[o-y]*: normalize docs

* Apply suggestions from code review

Co-authored-by: Felix Fontein <felix@fontein.de>

* Update plugins/modules/spectrum_model_attrs.py

---------

Co-authored-by: Felix Fontein <felix@fontein.de>
(cherry picked from commit 4b23e5ecff)

Co-authored-by: Alexei Znamensky <103110+russoz@users.noreply.github.com>
2024-12-25 16:46:29 +01:00
patchback[bot]
e120c64a21 [PR #9339/6e84c137 backport][stable-9] t*: normalize docs (#9355)
t*: normalize docs (#9339)

* t*: normalize docs

* Apply suggestions from code review

Co-authored-by: Felix Fontein <felix@fontein.de>

* break long line to regain sanity

---------

Co-authored-by: Felix Fontein <felix@fontein.de>
(cherry picked from commit 6e84c1375e)

Co-authored-by: Alexei Znamensky <103110+russoz@users.noreply.github.com>
2024-12-24 14:05:39 +01:00
patchback[bot]
8031011497 [PR #9338/2005125a backport][stable-9] u[a-s]*: normalize docs (#9360)
u[a-s]*: normalize docs (#9338)

* u[a-s]*: normalize docs

* Update plugins/modules/udm_dns_record.py

Co-authored-by: Felix Fontein <felix@fontein.de>

* Update plugins/modules/udm_dns_record.py

Co-authored-by: Felix Fontein <felix@fontein.de>

* Update plugins/modules/udm_dns_record.py

Co-authored-by: Felix Fontein <felix@fontein.de>

* Update plugins/modules/udm_dns_zone.py

Co-authored-by: Felix Fontein <felix@fontein.de>

* Update plugins/modules/ufw.py

Co-authored-by: Felix Fontein <felix@fontein.de>

* Apply suggestions from code review

Co-authored-by: Felix Fontein <felix@fontein.de>

---------

Co-authored-by: Felix Fontein <felix@fontein.de>
(cherry picked from commit 2005125af4)

Co-authored-by: Alexei Znamensky <103110+russoz@users.noreply.github.com>
2024-12-24 13:04:48 +00:00
patchback[bot]
961ba0ddcc [PR #9335/c141f868 backport][stable-9] utm*: normalize docs (#9345)
utm*: normalize docs (#9335)

* utm*: normalize docs

* Update plugins/modules/utm_aaa_group.py

Co-authored-by: Felix Fontein <felix@fontein.de>

---------

Co-authored-by: Felix Fontein <felix@fontein.de>
(cherry picked from commit c141f86883)

Co-authored-by: Alexei Znamensky <103110+russoz@users.noreply.github.com>
2024-12-23 21:40:51 +01:00
patchback[bot]
5d094c3bf3 [PR #9334/da51594f backport][stable-9] qubes connection plugin: fix display stmt (#9336)
qubes connection plugin: fix display stmt (#9334)

* qubes connection plugin: fix display stmt

* add changelog frag

(cherry picked from commit da51594f9d)

Co-authored-by: Alexei Znamensky <103110+russoz@users.noreply.github.com>
2024-12-23 12:28:17 +01:00
patchback[bot]
19b6f9ef3f [PR #9309/b57fef20 backport][stable-9] [vw]*: adjust docs (#9325)
[vw]*: adjust docs (#9309)

[vm]*: adjust docs

(cherry picked from commit b57fef201e)

Co-authored-by: Alexei Znamensky <103110+russoz@users.noreply.github.com>
2024-12-23 12:22:42 +01:00
patchback[bot]
3dd1c9d64a [PR #9306/d05d067f backport][stable-9] z mods adjust docs (#9328)
z mods adjust docs (#9306)

z* modules: adjust docs (re-commiting with adjustment from PR)

(cherry picked from commit d05d067f3b)

Co-authored-by: Alexei Znamensky <103110+russoz@users.noreply.github.com>
2024-12-23 12:22:35 +01:00
patchback[bot]
f9086b4680 [PR #9310/2adcc34d backport][stable-9] CI: Arch Linux updated to Python 3.13 (#9313)
CI: Arch Linux updated to Python 3.13 (#9310)

* Arch Linux updated to Python 3.13.

* Skip lmdb_kv lookup on Arch Linux.

Ref: https://github.com/jnwatson/py-lmdb/issues/362
(cherry picked from commit 2adcc34dd5)

Co-authored-by: Felix Fontein <felix@fontein.de>
2024-12-22 22:23:31 +01:00
patchback[bot]
861cbc29be [PR #9281/1b6c0517 backport][stable-9] zfs modules: adjust docs (#9304)
zfs modules: adjust docs (#9281)

* zfs modules: adjust docs

* Apply suggestions from code review

* fix examples indentation

* Update plugins/modules/zfs.py

Co-authored-by: Felix Fontein <felix@fontein.de>

---------

Co-authored-by: Felix Fontein <felix@fontein.de>
(cherry picked from commit 1b6c05176b)

Co-authored-by: Alexei Znamensky <103110+russoz@users.noreply.github.com>
2024-12-21 23:52:01 +01:00
patchback[bot]
3f5445274c [PR #9280/afa5716e backport][stable-9] yum_versionlock: adjust docs (#9302)
yum_versionlock: adjust docs (#9280)

* yum_versionlock: adjust docs

* fix examples indentation

(cherry picked from commit afa5716e0b)

Co-authored-by: Alexei Znamensky <103110+russoz@users.noreply.github.com>
2024-12-21 19:26:30 +01:00
patchback[bot]
f9ee387f68 [PR #9297/d2088ccf backport][stable-9] Polish botmeta extra sanity test and make it work without warnings on Python 3.13 (#9299)
Polish botmeta extra sanity test and make it work without warnings on Python 3.13 (#9297)

Polish botmeta and make it work without warnings on Python 3.13.

(cherry picked from commit d2088ccfcc)

Co-authored-by: Felix Fontein <felix@fontein.de>
2024-12-21 17:02:28 +01:00
patchback[bot]
aa3a43cfa8 [PR #9263/2682ec47 backport][stable-9] keycloak_authentication: Fix priority attribute during execution updates (#9291)
keycloak_authentication: Fix priority attribute during execution updates (#9263)

keycloak_authentication: Fix priority attribute during execution updates.

(cherry picked from commit 2682ec47d9)

Co-authored-by: Florian Apolloner <florian@apolloner.eu>
2024-12-20 23:06:25 +01:00
patchback[bot]
988d760372 [PR #9271/50b25f8c backport][stable-9] random_words integration tests: avoid test failure due to valid result (#9273)
random_words integration tests: avoid test failure due to valid result (#9271)

Avoid test failure due to valid result.

(cherry picked from commit 50b25f8c01)

Co-authored-by: Felix Fontein <felix@fontein.de>
2024-12-17 21:33:30 +01:00
patchback[bot]
f78c1b304c [PR #9259/65827bdc backport][stable-9] Drop myself from team_suse (#9265)
Drop myself from team_suse (#9259)

I no longer work with ansible and/or SUSE so drop me from the team.

(cherry picked from commit 65827bdc96)

Co-authored-by: Thomas Bechtold <thomasbechtold@jpberlin.de>
2024-12-16 20:58:41 +01:00
patchback[bot]
1e3a825e16 [PR #9250/f6dae1fc backport][stable-9] CI: Fix some issues pointed out by zizmor (#9252)
CI: Fix some issues pointed out by zizmor (#9250)

Fix some issues pointed out by zizmor.

(cherry picked from commit f6dae1fc4d)

Co-authored-by: Felix Fontein <felix@fontein.de>
2024-12-14 15:17:08 +01:00
patchback[bot]
34fe33163b [PR #9234/34e8e8e5 backport][stable-9] Fix VerifyBiosAttributes command on Systems with multiple entries (#9248)
Fix VerifyBiosAttributes command on Systems with multiple entries (#9234)

* Fix verify_bios_attributes command

* Add changelog fragment

* Update changelogs/fragments/9234-fix-verify-bios-attributes-multi-system.yml

Improve fragment

Co-authored-by: Alexei Znamensky <103110+russoz@users.noreply.github.com>

---------

Co-authored-by: Alexei Znamensky <103110+russoz@users.noreply.github.com>
(cherry picked from commit 34e8e8e5d1)

Co-authored-by: Scott Seekamp <sseekamp@coreweave.com>
2024-12-14 11:13:41 +01:00
patchback[bot]
396eb1d7e4 [PR #9243/9df4ef9a backport][stable-9] sysrc: add another exclusion for ezjail (#9245)
sysrc: add another exclusion for ezjail (#9243)

Add another exclusion.

(cherry picked from commit 9df4ef9a9c)

Co-authored-by: Felix Fontein <felix@fontein.de>
2024-12-13 22:41:05 +01:00
Felix Fontein
baef8580ec The next release will be 9.5.3. 2024-12-02 21:44:42 +01:00
Felix Fontein
d8505bd8d9 Release 9.5.2. 2024-12-02 21:12:30 +01:00
patchback[bot]
aa0df4d81d [PR #9202/55d714da backport][stable-9] keycloak_clientscope_type: sort default and optional clientscope lists before diff (#9221)
keycloak_clientscope_type: sort default and optional clientscope lists before diff (#9202)

* sort default and optional clientscope lists before diff

* add changelog fragment

(cherry picked from commit 55d714da81)

Co-authored-by: fgruenbauer <gruenbauer@b1-systems.de>
2024-12-02 20:34:13 +01:00
patchback[bot]
c349861190 [PR #9198/f2dbe08d backport][stable-9] Fail if Slack API response is not OK with error message (#9211)
Fail if Slack API response is not OK with error message (#9198)

* Fails if slack api return is not ok

* add changelog

* show all error

* add doc

* Update plugins/modules/slack.py

Co-authored-by: Felix Fontein <felix@fontein.de>

* Update changelogs/fragments/9198-fail-if-slack-api-response-is-not-ok-with-error-message.yml

Co-authored-by: Felix Fontein <felix@fontein.de>

---------

Co-authored-by: Felix Fontein <felix@fontein.de>
(cherry picked from commit f2dbe08d0e)

Co-authored-by: Matthieu Bourgain <aohzan@gmail.com>
2024-12-02 20:33:41 +01:00
patchback[bot]
a853e561f1 [PR #9187/f828bdee backport][stable-9] flatpak: force locale language to be C (#9206)
flatpak: force locale language to be C (#9187)

* flatpak: force locale langauge to be C

* add changelog frag

(cherry picked from commit f828bdee22)

Co-authored-by: Alexei Znamensky <103110+russoz@users.noreply.github.com>
2024-11-28 20:06:48 +01:00
patchback[bot]
1d9367ebea [PR #9186/a863b628 backport][stable-9] fixing broken check mode in the github_key (#9204)
fixing broken check mode in the github_key (#9186)

* fixing datetime.strftime()

* added changelog fragment

* Update changelogs/fragments/9186-fix-broken-check-mode-in-github-key.yml

Co-authored-by: Felix Fontein <felix@fontein.de>

---------

Co-authored-by: Felix Fontein <felix@fontein.de>
(cherry picked from commit a863b62859)

Co-authored-by: tomcperry <99128358+tomcperry@users.noreply.github.com>
2024-11-28 20:06:32 +01:00
patchback[bot]
f1cf0c1949 [PR #9191/fa7c2df4 backport][stable-9] ufw: add note to docs about concurrency (#9194)
ufw: add note to docs about concurrency (#9191)

* ufw: add note to docs about concurrency

* wordsmithing

(cherry picked from commit fa7c2df4b8)

Co-authored-by: Alexei Znamensky <103110+russoz@users.noreply.github.com>
2024-11-26 06:40:50 +01:00
Felix Fontein
5b26e09319 Prepare 9.5.2 release. 2024-11-23 15:41:47 +01:00
patchback[bot]
3cc5a5bc8d [PR #9152/5a971587 backport][stable-9] Update docs for github_app_access_token.py (#9163)
Update docs for github_app_access_token.py (#9152)

* Update github_app_access_token.py

updating docs - github_token missing {{ }}

* Update plugins/lookup/github_app_access_token.py

Co-authored-by: Felix Fontein <felix@fontein.de>

---------

Co-authored-by: Felix Fontein <felix@fontein.de>
(cherry picked from commit 5a9715874a)

Co-authored-by: Ian Richardson <126898943+PredatarIan@users.noreply.github.com>
2024-11-20 19:31:34 +01:00
patchback[bot]
cd0818e488 [PR #9157/4b0d5cb8 backport][stable-9] dnf_config_manager: fix parsing for non-english locales (#9165)
dnf_config_manager: fix parsing for non-english locales (#9157)

* dnf_config_manager: forces locale to 'C' when the module starts

* adds changelog fragment

* Apply suggestions from code review

Co-authored-by: Alexei Znamensky <103110+russoz@users.noreply.github.com>

---------

Co-authored-by: Alexei Znamensky <103110+russoz@users.noreply.github.com>
(cherry picked from commit 4b0d5cb8cf)

Co-authored-by: Stanislav Shamilov <shamilovstas@protonmail.com>
2024-11-20 19:30:32 +01:00
patchback[bot]
ad197a303a [PR #9144/54194ccb backport][stable-9] modprobe: document when 'persistent' was added. (#9155)
modprobe: document when 'persistent' was added. (#9144)

This is based on `git tag --contains
29f5033737a7fd86349ff3daab7d7ee7db66ad00`.

(cherry picked from commit 54194ccb24)

Co-authored-by: Max Gautier <mg@max.gautier.name>
2024-11-19 20:17:10 +01:00
patchback[bot]
cdbf70d781 [PR #9145/dc856ab6 backport][stable-9] filters/dict: document the correct return value (#9150)
filters/dict: document the correct return value (#9145)

(cherry picked from commit dc856ab6fe)

Co-authored-by: Max Gautier <mg@max.gautier.name>
2024-11-18 20:58:51 +01:00
patchback[bot]
c77661c184 [PR #9143/2a66ac71 backport][stable-9] build(deps): bump fsfe/reuse-action from 4 to 5 (#9147)
build(deps): bump fsfe/reuse-action from 4 to 5 (#9143)

Bumps [fsfe/reuse-action](https://github.com/fsfe/reuse-action) from 4 to 5.
- [Release notes](https://github.com/fsfe/reuse-action/releases)
- [Commits](https://github.com/fsfe/reuse-action/compare/v4...v5)

---
updated-dependencies:
- dependency-name: fsfe/reuse-action
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
(cherry picked from commit 2a66ac719a)

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-11-18 19:49:21 +01:00
patchback[bot]
d99a7974ad [PR #9124/36c7e560 backport][stable-9] dnf_config_manager: use --assumeyes when changing state (#9141)
dnf_config_manager: use --assumeyes when changing state (#9124)

* dnf_config_manager: use --assumeyesm when changing state

* changelog fragment

* update tests

* format fix

* Update changelogs/fragments/9124-dnf_config_manager.yml

Co-authored-by: Alexei Znamensky <103110+russoz@users.noreply.github.com>

---------

Co-authored-by: Alexei Znamensky <103110+russoz@users.noreply.github.com>
(cherry picked from commit 36c7e56005)

Co-authored-by: Andrew Hyatt <4400272+ahyattdev@users.noreply.github.com>
2024-11-17 20:19:58 +00:00
patchback[bot]
0fcd23a3f1 [PR #9128/9596995f backport][stable-9] homebrew_cask: add + to valid cask chars (#9134)
homebrew_cask: add + to valid cask chars (#9128)

* fix(homebrew_cask): add + to valid cask chars

* docs(homebrew_cask): add changelog fragment

Signed-off-by: Ben Dronen <dronenb@users.noreply.github.com>

* fix(homebrew_cask): add PR link to changelog fragment

Signed-off-by: Ben Dronen <dronenb@users.noreply.github.com>

* fix: add period to end of changelog fragment

Signed-off-by: Ben Dronen <dronenb@users.noreply.github.com>

* fix: remove blank line from changelog fragment

Signed-off-by: Ben Dronen <dronenb@users.noreply.github.com>

* fix: changelog fragment formatting

Co-authored-by: Alexei Znamensky <103110+russoz@users.noreply.github.com>

* Update changelogs/fragments/9128-homebrew_cask-name-regex-fix.yml

Co-authored-by: Felix Fontein <felix@fontein.de>

---------

Signed-off-by: Ben Dronen <dronenb@users.noreply.github.com>
Co-authored-by: Alexei Znamensky <103110+russoz@users.noreply.github.com>
Co-authored-by: Felix Fontein <felix@fontein.de>
(cherry picked from commit 9596995ffc)

Co-authored-by: dronenb <dronenb@users.noreply.github.com>
2024-11-16 19:14:48 +01:00
patchback[bot]
49fc40b275 [PR #9077/62cb6087 backport][stable-9] keycloak_client: remove code that turns attributes dict into list (#9115)
keycloak_client: remove code that turns attributes dict into list (#9077)

* remove code that turns attributes dict into list

* add changelog fragment

* Update changelogs/fragments/9077-keycloak_client-fix-attributes-dict-turned-into-list.yml

Co-authored-by: Felix Fontein <felix@fontein.de>

---------

Co-authored-by: Felix Fontein <felix@fontein.de>
(cherry picked from commit 62cb6087b5)

Co-authored-by: fgruenbauer <gruenbauer@b1-systems.de>
2024-11-11 20:35:42 +01:00
patchback[bot]
c6c65ee554 [PR #9082/d27d86ec backport][stable-9] keycloak_clientscope: remove code turning attributes dict into list (#9117)
keycloak_clientscope: remove code turning attributes dict into list (#9082)

* remove code turning attributes dict into list

* add changelog fragment

(cherry picked from commit d27d86ecb1)

Co-authored-by: fgruenbauer <gruenbauer@b1-systems.de>
2024-11-11 20:35:33 +01:00
patchback[bot]
d385caa73f [PR #9114/bafb8aca backport][stable-9] redfish_utils: remove undocumented default applytime (#9119)
redfish_utils: remove undocumented default applytime (#9114)

* redfish_utils: remove undocumented default applytime

The `@Redfish.OperationApplyTime` parameter is optional as per Redfish
spec version 1.21.0, paragraph 7.11 [1]. Some systems reject the
request rather than ignore it, causing failures that can not be
workarounded.

Removing this default resolves compatibility issues.

[1] https://www.dmtf.org/sites/default/files/standards/documents/DSP0266_1.21.0.html

Signed-off-by: Tan Siewert <tan@siewert.io>

* redfish_utils: fix changelog fragment to bugfix

Signed-off-by: Tan Siewert <tan@siewert.io>

---------

Signed-off-by: Tan Siewert <tan@siewert.io>
(cherry picked from commit bafb8aca29)

Co-authored-by: Tan Siewert <tom@siewert.io>
2024-11-11 20:35:25 +01:00
patchback[bot]
2b52822043 [PR #9109/04c2ad18 backport][stable-9] Add FreeBSD 13.4 to CI (#9110)
Add FreeBSD 13.4 to CI (#9109)

* Add FreeBSD 13.4 to CI.

* iso_extract won't work.

* pkgng: jail won't work either.

(cherry picked from commit 04c2ad18da)

Co-authored-by: Felix Fontein <felix@fontein.de>
2024-11-09 12:49:53 +01:00
Felix Fontein
9ebb5b270a Adjust nightly CI schedules.
(cherry picked from commit e13d6de250)
2024-11-04 19:35:49 +01:00
patchback[bot]
7b9ba8d2e2 [PR #9099/886d4a65 backport][stable-9] proxmox inventory: fix urllib3 InsecureRequestWarnings not suppressing when a token is used (#9100)
proxmox inventory: fix urllib3 InsecureRequestWarnings not suppressing when a token is used (#9099)

* proxmox inventory: fix urllib3 InsecureRequestWarnings not suppressing when a token is used

* proxmox inventory: add changelog fragment

* proxmox inventory: add forgotten pr number

* Update changelog.

---------

Co-authored-by: Felix Fontein <felix@fontein.de>
(cherry picked from commit 886d4a6596)

Co-authored-by: Mikhail Vorontsov <52924343+mephs@users.noreply.github.com>
2024-11-04 19:35:14 +01:00
Felix Fontein
d33467611e The next release will be 9.5.2. 2024-11-03 20:48:39 +01:00
Felix Fontein
9e0eeb0b94 Release 9.5.1. 2024-11-03 20:24:40 +01:00
patchback[bot]
5fd97399b0 [PR #9093/8fc11fe8 backport][stable-9] keycloak_clientscope_type fix checkmode (#9095)
keycloak_clientscope_type fix checkmode (#9093)

* fix check_mode on set keycloak client scope type (#9092)

* add changelog fragment (#9092)

* update changelog fragment (#9092)

* compact code: make one line conditions with list comprehension and any()

Co-authored-by: Alexei Znamensky <103110+russoz@users.noreply.github.com>

* fix syntax error: remove extra ')'

* fix changelog fragment type

Co-authored-by: Felix Fontein <felix@fontein.de>

* add issue's link in changelog fragment

Co-authored-by: Felix Fontein <felix@fontein.de>

---------

Co-authored-by: Alexei Znamensky <103110+russoz@users.noreply.github.com>
Co-authored-by: Felix Fontein <felix@fontein.de>
(cherry picked from commit 8fc11fe88f)

Co-authored-by: witrdotnet <witr.net@gmail.com>
2024-11-03 11:30:16 +01:00
patchback[bot]
eb14bd572d [PR #9085/9553dd9d backport][stable-9] Stop using ansible.module_utils.compat.importlib (#9089)
Stop using ansible.module_utils.compat.importlib (#9085)

Stop using ansible.module_utils.compat.importlib.

(cherry picked from commit 9553dd9ddf)

Co-authored-by: Felix Fontein <felix@fontein.de>
2024-10-31 19:10:08 +01:00
patchback[bot]
beff4063b3 [PR #9057/c71f662d backport][stable-9] Redfish: Added handling for trailing slashes in URIs when extracting member identifiers (#9078)
Redfish: Added handling for trailing slashes in URIs when extracting member identifiers (#9057)

Signed-off-by: Mike Raineri <michael.raineri@dell.com>
(cherry picked from commit c71f662d55)

Co-authored-by: Mike Raineri <mraineri@gmail.com>
2024-10-29 20:28:07 +01:00
patchback[bot]
b6cd89c677 [PR #9056/67d1b6c4 backport][stable-9] one_image/one_image_info: Fix class typo (#9072)
one_image/one_image_info: Fix class typo (#9056)

* Fix one_image class method args

* Add CHANGELOG fragment

* PR fix

* PR fixes

(cherry picked from commit 67d1b6c413)

Co-authored-by: alexander <79072457+abakanovskii@users.noreply.github.com>
2024-10-29 20:27:36 +01:00
Felix Fontein
9c535cb17d Prepare 9.5.1. 2024-10-28 21:29:16 +01:00
patchback[bot]
772b5b1ad3 [PR #9052/d0b4e91c backport][stable-9] modprobe: fix --check mode not being honored for persistent option (#9071)
modprobe: fix --check mode not being honored for persistent option (#9052)

* modprobe: fix --check mode not being honored for persistent option

* Add CHANGELOG

* Update CHANGELOG

* Update changelogs/fragments/9052-modprobe-bugfix.yml

Co-authored-by: Felix Fontein <felix@fontein.de>

---------

Co-authored-by: d-usuba <d-usuba@sakura.ad.jp>
Co-authored-by: Felix Fontein <felix@fontein.de>
(cherry picked from commit d0b4e91cac)

Co-authored-by: salmon111 <campfire@kumachans.net>
2024-10-28 21:25:16 +01:00
patchback[bot]
e5ab4be82d [PR #9045/ccf7f623 backport][stable-9] Update documentation in apk.py (#9053)
Update documentation in apk.py (#9045)

* Update apk.py

Fix for issue #9017

* Update plugins/modules/apk.py

Added a line break to fix the issue of the line being too long.

Co-authored-by: Felix Fontein <felix@fontein.de>

---------

Co-authored-by: Felix Fontein <felix@fontein.de>
(cherry picked from commit ccf7f62325)

Co-authored-by: Navaneeth S <navisk13@gmail.com>
2024-10-22 20:49:03 +02:00
patchback[bot]
65dd204dab [PR #9019/93be499f backport][stable-9] one_vnet: Fix module (#9049)
one_vnet: Fix module (#9019)

* Fix one_vnet module

* Add CHANGELOG

* Fix CHANGELOG

(cherry picked from commit 93be499f26)

Co-authored-by: alexander <79072457+abakanovskii@users.noreply.github.com>
2024-10-21 21:09:08 +02:00
patchback[bot]
5112994fd4 [PR #8979/658637dc backport][stable-9] keycloak_group: fix subgroup creation in Keycloak ≥23 (#9041)
keycloak_group: fix subgroup creation in Keycloak ≥23 (#8979)

* keycloak_group: fix subgroup creation in Keycloak ≥23

* Add changelog fragment

* Include issue and pull request in changelog fragment

Co-authored-by: Felix Fontein <felix@fontein.de>

* Use new way to get subgroups when getting a subgroup chain

* Fix indent

---------

Co-authored-by: Felix Fontein <felix@fontein.de>
(cherry picked from commit 658637dc70)

Co-authored-by: Victor Gaudard <victor.gaudard@gmail.com>
2024-10-19 22:51:06 +02:00
patchback[bot]
0d4d3f6b73 [PR #9040/cc72fa07 backport][stable-9] groupby_as_dict: mention Jinja2's groupby filter (#9043)
groupby_as_dict: mention Jinja2's groupby filter (#9040)

Mention Jinja2's groupby filter.

(cherry picked from commit cc72fa0786)

Co-authored-by: Felix Fontein <felix@fontein.de>
2024-10-19 22:50:57 +02:00
patchback[bot]
4a7b93df64 [PR #9035/b1f46040 backport][stable-9] Skip timezone test on RHEL 7.9 VMs (#9039)
Skip timezone test on RHEL 7.9 VMs (#9035)

Skip timezone test on RHEL 7.9 VMs.

(cherry picked from commit b1f4604067)

Co-authored-by: Felix Fontein <felix@fontein.de>
2024-10-19 14:29:01 +02:00
patchback[bot]
ab20c90929 [PR #9028/1180843e backport][stable-9] bitwarden_secrets_manager lookup plugin: support more current versions of BWS CLI (#9036)
bitwarden_secrets_manager lookup plugin: support more current versions of BWS CLI (#9028)

* add support for getting secrets in the current version of bitwarden secrets manager

* format

* format2

* fragment

* fix formatting errors

* strip out junk before the version in cli output

* mock the --version command in the unit tests

* use LooseVersion comparison - russoz suggestion

* add blank line

(cherry picked from commit 1180843e35)

Co-authored-by: Zac <zgibson@live.com>
2024-10-19 14:05:56 +02:00
Felix Fontein
721ea50420 Fix reuse workflow branches.
(cherry picked from commit 5874711c6e)
2024-10-19 12:36:07 +02:00
patchback[bot]
23b646d5c2 [PR #9010/12fa2452 backport][stable-9] update gitlab label's color (#9034)
update gitlab label's color (#9010)

* update gitlab label's color

fail if both new_name and color are missing, as per Gitlab API docs.

* add changelog

* Update changelog with suggestion

Co-authored-by: Alexei Znamensky <103110+russoz@users.noreply.github.com>

* remove unneeded check

* Update changelog

---------

Co-authored-by: Alexei Znamensky <103110+russoz@users.noreply.github.com>
(cherry picked from commit 12fa2452d8)

Co-authored-by: Gabriele Pongelli <gpongelli@users.noreply.github.com>
2024-10-17 21:49:39 +02:00
patchback[bot]
1e78ff58d5 [PR #8972/a894f8e7 backport][stable-9] snap: improve documentation (#9023)
snap: improve documentation (#8972)

* plugins/modules/snap: improve documentation

Signed-off-by: Lincoln Wallace <lincoln.wallace@canonical.com>

* undo helper setence about finding avaible snaps.

Co-authored-by: Farshid Tavakolizadeh <email@farshid.ws>

* wip: adress reviews

Signed-off-by: Lincoln Wallace <lincoln.wallace@canonical.com>

* fix: revert sentence

Signed-off-by: Lincoln Wallace <lincoln.wallace@canonical.com>

* feat: improve explanation on snap options

Co-authored-by: Farshid Tavakolizadeh <email@farshid.ws>

* clean: remove duplicated and leave reference

Co-authored-by: Alexei Znamensky <103110+russoz@users.noreply.github.com>

* feat: add note about priviledge scalation and switch sentence position

Signed-off-by: Lincoln Wallace <lincoln.wallace@canonical.com>

* fix: remove additional dash.

Co-authored-by: Farshid Tavakolizadeh <email@farshid.ws>

* feat: reword note and use better doc cross-ref syntax

Signed-off-by: Lincoln Wallace <lincoln.wallace@canonical.com>

* refact: add period.

Co-authored-by: Farshid Tavakolizadeh <email@farshid.ws>

* fix: linter errors

Signed-off-by: Lincoln Wallace <lincoln.wallace@canonical.com>

* fix: remove redundant sentence

Co-authored-by: Alexei Znamensky <103110+russoz@users.noreply.github.com>

* fix: remove confuse sentence

Co-authored-by: Farshid Tavakolizadeh <email@farshid.ws>

* fix: remove redudant content

Signed-off-by: Lincoln Wallace <lincoln.wallace@canonical.com>

* feat: add missing word

Co-authored-by: Alexei Znamensky <103110+russoz@users.noreply.github.com>

* refact: remove abreviation

Co-authored-by: Felix Fontein <felix@fontein.de>

* refact: remove abreviation

Co-authored-by: Felix Fontein <felix@fontein.de>

* refact: remove abreviation

Co-authored-by: Felix Fontein <felix@fontein.de>

---------

Signed-off-by: Lincoln Wallace <lincoln.wallace@canonical.com>
Co-authored-by: Farshid Tavakolizadeh <email@farshid.ws>
Co-authored-by: Alexei Znamensky <103110+russoz@users.noreply.github.com>
Co-authored-by: Felix Fontein <felix@fontein.de>
(cherry picked from commit a894f8e7eb)

Co-authored-by: Lincoln Wallace <locnnil@hotmail.com>
2024-10-13 21:46:35 +02:00
patchback[bot]
280a5b0e61 [PR #8907/8df9d0d7 backport][stable-9] one_host: Fix ID logic (#9014)
one_host: Fix ID logic (#8907)

* Fix one_host module

* Add CHANGELOG fragment

* PR Fixes

* Update exceptions

(cherry picked from commit 8df9d0d7de)

Co-authored-by: alexander <79072457+abakanovskii@users.noreply.github.com>
2024-10-10 22:25:03 +02:00
patchback[bot]
21a840eab7 [PR #9012/67ddb567 backport][stable-9] Dell PwrButton requires a job initated at reboot (#9015)
Dell PwrButton requires a job initated at reboot (#9012)

Dell systems do not change the bios setting PwrButton right away. The
command will return changed=true, but it is not applied. Also no job is
scheduled at next reboot for the change to take place. This patch aims
to fix this issue.

(cherry picked from commit 67ddb567c9)

Co-authored-by: Ruben Bosch <8641284+Rubueno@users.noreply.github.com>
2024-10-10 22:24:53 +02:00
Felix Fontein
6f98adf602 Next release will be 9.5.1. 2024-10-07 23:37:32 +02:00
Felix Fontein
8c45cba53c Release 9.5.0. 2024-10-07 23:14:49 +02:00
patchback[bot]
9fe31235d8 [PR #8973/464812a2 backport][stable-9] keycloak_client add option to support client-x509 authentication (#9005)
keycloak_client add option to support client-x509 authentication (#8973)

* keycloak_client: add client-x509 option to client_authenticator_type

Signed-off-by: boolman <boolman@gmail.com>

* keycloak_client: add attributes for client-x509

Signed-off-by: boolman <boolman@gmail.com>

* keycloak_client update description

Signed-off-by: boolman <boolman@gmail.com>

* keycloak_client add fragment

Signed-off-by: boolman <boolman@gmail.com>

* remove trailing whitespace

Signed-off-by: boolman <boolman@gmail.com>

* keycloak_client add example with x509 authentication

Signed-off-by: boolman <boolman@gmail.com>

* Update plugins/modules/keycloak_client.py

Co-authored-by: Felix Fontein <felix@fontein.de>

* Update changelogs/fragments/8973-keycloak_client-add-x509-auth.yml

Co-authored-by: Felix Fontein <felix@fontein.de>

* keycloak_client added type on new suboptions

Signed-off-by: boolman <boolman@gmail.com>

---------

Signed-off-by: boolman <boolman@gmail.com>
Co-authored-by: Felix Fontein <felix@fontein.de>
(cherry picked from commit 464812a2c2)

Co-authored-by: Boolman <boolman@gmail.com>
2024-10-07 23:10:46 +02:00
patchback[bot]
fc7609628e [PR #8532/24b74cc4 backport][stable-9] opennebula inventory: add VM ID and VM host to data (#9003)
opennebula inventory: add VM ID and VM host to data (#8532)

* Add VM id and VM host to opennebula inventory data

##### SUMMARY
<!--- Describe the change below, including rationale and design decisions --> To enable greater use of the inventory, add the ID of the VM, and the hostname of the host the VM is running on to the inventory output

<!--- HINT: Include "Fixes #nnn" if you are fixing an existing issue -->

<!--- Please do not forget to include a changelog fragment:
      https://docs.ansible.com/ansible/devel/community/collection_development_process.html#creating-changelog-fragments
      No need to include one for docs-only or test-only PR, and for new plugin/module PRs.
      Read about more details in CONTRIBUTING.md.
      -->

##### ISSUE TYPE
<!--- Pick one or more below and delete the rest.
      'Test Pull Request' is for PRs that add/extend tests without code changes. -->
- Feature Pull Request

##### COMPONENT NAME
<!--- Write the SHORT NAME of the module, plugin, task or feature below. --> opennebula.py

##### ADDITIONAL INFORMATION
<!--- Include additional information to help people understand the change here --> <!--- A step-by-step reproduction of the problem is helpful if there is no related issue -->

<!--- Paste verbatim command output below, e.g. before and after your change -->
```paste below
                "host": "foo23.host",
                "id": 1234,
```

* Create 8532-expand-opennuebula-inventory-data.yml

* Update opennebula.py

* Update changelogs/fragments/8532-expand-opennuebula-inventory-data.yml

Co-authored-by: Felix Fontein <felix@fontein.de>

* Add check for empty records and add test

* fix attribute test

* fix attribute test

* fix attribute test

* fix attribute test

* Update plugins/inventory/opennebula.py

Co-authored-by: Felix Fontein <felix@fontein.de>

* update as per guidance

* restore attribute checks

* fix attr

* fix indent

* PR Fixes

* add attribute check in case of empty variable

---------

Co-authored-by: Felix Fontein <felix@fontein.de>
Co-authored-by: Александр Бакановский <abakanovskii@astralinux.ru>
(cherry picked from commit 24b74cc4b9)

Co-authored-by: Tom Paine <github@aioue.net>
2024-10-07 23:10:38 +02:00
patchback[bot]
a1d4051a12 [PR #8940/c814fd05 backport][stable-9] keycloak_userprofile: improve diff by deserializing fetched kc.user.profile.config and serializing it before sending (#9002)
keycloak_userprofile: improve diff by deserializing fetched `kc.user.profile.config` and serializing it before sending (#8940)

* deserialize fetched `kc.user.profile.config` and serialize it before sending

* change `kc.user.profile.config` to JSON formatted string in mock `get_component` responses

* add changelog fragment

(cherry picked from commit c814fd0530)

Co-authored-by: fgruenbauer <gruenbauer@b1-systems.de>
2024-10-07 23:10:29 +02:00
patchback[bot]
acdf19c9e6 [PR #8898/3b109abe backport][stable-9] keycloak_user_federation: add module argument that allows excluding bindCredential from update check (#8999)
keycloak_user_federation: add module argument that allows excluding `bindCredential` from update check (#8898)

* add module argument that allows excluding `bindCredential` from update check

* add changelog fragment

* change option name to `bind_credential_update_mode` and change type to str

(cherry picked from commit 3b109abe18)

Co-authored-by: fgruenbauer <gruenbauer@b1-systems.de>
2024-10-07 23:10:19 +02:00
patchback[bot]
e2513b318e [PR #8920/cc800962 backport][stable-9] ipa_host: Fix enabled and disabled states (#8998)
ipa_host: Fix enabled and disabled states (#8920)

* Fix ipa_host

* PR Fixes

* PR Fixes

* PR Doc fixes

* PR Doc fixes 2

* Fix default value

(cherry picked from commit cc8009621f)

Co-authored-by: alexander <79072457+abakanovskii@users.noreply.github.com>
2024-10-07 23:10:13 +02:00
patchback[bot]
cc2794ad05 [PR #8966/5e6b8e53 backport][stable-9] dig lookup: Allow to pass port for DNS lookup (#9004)
dig lookup: Allow to pass port for DNS lookup (#8966)

dnspython accepts a port as part of the nameserver.

Currently, the nameservers are passed as strings which
leads dnspython to create Nameserver objects out of them
using the port that is currently set in the Resolver instance.
That creation of Nameserver objects is done right when the
`nameservers` property is set.
If a port is to be set by us, the `port` attribute of the
Resolver needs to be set before the nameservers are passed
to the Resolver so when the nameservers are passed, that new
port is used to create the Nameserver objects.
Therefore, the assignment of the `nameservers` property of the
Resolver is moved after the argument processing so the `port`
attribute is (if it's given in the lookup-call) definitely set
before the `nameservers` property.

(cherry picked from commit 5e6b8e5327)

Co-authored-by: JaegerMaKn <max.jaeger@knauf.com>
2024-10-07 23:10:04 +02:00
patchback[bot]
154b5f86fd [PR #8990/447d4b02 backport][stable-9] redfish_config new bool parameter to automatically delete 'None' type volumes. (#9008)
redfish_config new bool parameter to automatically delete 'None' type volumes. (#8990)

* Add a new boolean parameter storage_none_volume_deletion to the volume creation command of redfish_config

* Add description for storage_none_volume_deletion redfish_config parameter

* Update plugins/module_utils/redfish_utils.py

Co-authored-by: Mike Raineri <mraineri@gmail.com>

* Update plugins/modules/redfish_config.py

Co-authored-by: Mike Raineri <mraineri@gmail.com>

* Add CHANGELOG fragment

* Add punctuation.

---------

Co-authored-by: Pierre-yves FONTANIERE <pyf@cc.in2p3.fr>
Co-authored-by: Mike Raineri <mraineri@gmail.com>
Co-authored-by: Felix Fontein <felix@fontein.de>
(cherry picked from commit 447d4b0267)

Co-authored-by: Pierre-yves Fontaniere <pyfontan@cc.in2p3.fr>
2024-10-07 23:09:55 +02:00
patchback[bot]
e302058e2d [PR #8948/1bdf8fc0 backport][stable-9] cloudflare_dns: Update SRV record handling for Cloudflare API changes (#9001)
cloudflare_dns: Update SRV record handling for Cloudflare API changes (#8948)

(cherry picked from commit 1bdf8fc025)

Co-authored-by: salty <salty@salty.dk>
2024-10-07 23:09:44 +02:00
patchback[bot]
1affd48260 [PR #8956/b523d1b1 backport][stable-9] Remove 'CapacityBytes' from list of required parameters (#9007)
Remove 'CapacityBytes' from list of required parameters (#8956)

* Remove 'CapacityBytes' from list of required parameters

* Add CHANGELOG fragment

* Fix sanity test failure whitespace before ']'

* Update changelogs/fragments/8956-remove-capacitybytes-from-the-required-parameters_list.yml

Co-authored-by: Alexei Znamensky <103110+russoz@users.noreply.github.com>

* Add  description for the volume_details key CapacityBytes

* Update plugins/modules/redfish_config.py

Co-authored-by: Mike Raineri <mraineri@gmail.com>

* Adjust description.

---------

Co-authored-by: Pierre-yves FONTANIERE <pyf@cc.in2p3.fr>
Co-authored-by: Alexei Znamensky <103110+russoz@users.noreply.github.com>
Co-authored-by: Mike Raineri <mraineri@gmail.com>
Co-authored-by: Felix Fontein <felix@fontein.de>
(cherry picked from commit b523d1b1c9)

Co-authored-by: Pierre-yves Fontaniere <pyfontan@cc.in2p3.fr>
2024-10-07 23:09:25 +02:00
patchback[bot]
dc5a89b040 [PR #8954/c7e2875a backport][stable-9] keycloak_user_federation: add user federation config parameter referral to module args (#8997)
keycloak_user_federation: add user federation config parameter `referral` to module args (#8954)

* add keycloak referral parameter to module args

* add changelog fragment

* Update plugins/modules/keycloak_user_federation.py

Co-authored-by: Felix Fontein <felix@fontein.de>

* Update changelogs/fragments/8954-keycloak-user-federation-add-referral-parameter.yml

Co-authored-by: Felix Fontein <felix@fontein.de>

---------

Co-authored-by: Felix Fontein <felix@fontein.de>
(cherry picked from commit c7e2875a4d)

Co-authored-by: fgruenbauer <gruenbauer@b1-systems.de>
2024-10-07 22:36:58 +02:00
patchback[bot]
71d8109275 [PR #8952/24f2b980 backport][stable-9] passwordstore: Support subkey creation and update (#8996)
passwordstore: Support subkey creation and update (#8952)

(cherry picked from commit 24f2b980b7)

Co-authored-by: Manuel Luzarreta <mluzarreta.pro@pm.me>
2024-10-07 22:31:04 +02:00
patchback[bot]
73362a1e43 [PR #8938/1d86d496 backport][stable-9] ipa_getkeytab: Create module (#8995)
ipa_getkeytab: Create module (#8938)

* Add ipa_getkeytab

* Parameters fix

* PR fixes

* PR fixes 2

* Fix unit tests

* Fix doc and unit tests

* Fix doc

* Fix doc 2

* Fix doc 3

* PR fixes

* PR fixes 2

* Fix name

* Fix description typo

* Fix variable names

* Update tests

* Add man reference

(cherry picked from commit 1d86d49688)

Co-authored-by: alexander <79072457+abakanovskii@users.noreply.github.com>
2024-10-07 22:30:52 +02:00
patchback[bot]
bc4fda8b14 [PR #8983/5b4f4174 backport][stable-9] Update docs with references to man pages (#8994)
Update docs with references to man pages (#8983)

* update docs with references to man pages

* reformat module docs

* gconftool2/_info: docs adjustments

(cherry picked from commit 5b4f41748d)

Co-authored-by: Alexei Znamensky <103110+russoz@users.noreply.github.com>
2024-10-07 22:19:29 +02:00
patchback[bot]
2766898ea8 [PR #8987/29a2df8e backport][stable-9] udm_user, homectl: use legacycrypt on Python 3.13+ (#8993)
udm_user, homectl: use legacycrypt on Python 3.13+ (#8987)

Use legacycrypt on Python 3.13+.

(cherry picked from commit 29a2df8e6b)

Co-authored-by: Felix Fontein <felix@fontein.de>
2024-10-07 22:19:14 +02:00
patchback[bot]
02f123877a [PR #8889/fea0ffa5 backport][stable-9] one_image/one_image_info: refactor (#8984)
one_image/one_image_info: refactor (#8889)

* Refactor one_image

* Refactor one_image_info

* Add examples one_image

* Add CHANGELOG fragment

* Add integration tests for one_image

* Add integration tests for one_image_info

* Update one_image DOC

* Update one_image_info DOC

* Update one_image DOC

* Update one_image_info DOC

* Fix f-strings for one_image

* Update CHANGELOG fragment

* PR fixes

* PR fixes

(cherry picked from commit fea0ffa5aa)

Co-authored-by: alexander <79072457+abakanovskii@users.noreply.github.com>
2024-10-05 15:17:27 +02:00
patchback[bot]
d4c29e19c0 [PR #8970/8610223d backport][stable-9] dig lookup plugin: Fix using only last nameserver specified (#8986)
dig lookup plugin: Fix using only last nameserver specified (#8970)

* dig plugin: Fix using only last nameserver given

Currently, when specifying multiple nameservers
either using multiple `@ns.example.com` arguments
or by specifying multiple nameservers in a single
argument (@ns1.example.com,ns2.example.com), due
to a bug only the very last nameserver that is
specified is actually used.
This is because for every iteration of the
    for ns in nsset
loop, the local list of nameservers is cleared
and after adding the currently processed nameserver
entry, the whole `nameservers` list of the Resolver
instance is overridden with that new list with just
one element. And as far as I can see, when setting
that `nameserver` property, the dnspython library
actually overrides the existing list and doesn't
do some trickery to append the new nameservers or
something like that.

Therefore, the assignment of the `nameservers`
property of the Resolver is moved after the argument
processing so all nameservers are added and then
collectively written to the `nameservers` property
of the Resolver.

* Add CHANGELOG fragment

(cherry picked from commit 8610223d03)

Co-authored-by: JaegerMaKn <max.jaeger@knauf.com>
2024-10-05 15:17:17 +02:00
patchback[bot]
200ab045fa [PR #8908/e7ccbc2f backport][stable-9] Add gitlab group params (#8981)
Add gitlab group params (#8908)

Add new gitlab_group parameters

(cherry picked from commit e7ccbc2f18)

Co-authored-by: Julien Lecomte <julien-lecomte@users.noreply.github.com>
2024-10-04 09:19:24 +02:00
patchback[bot]
9b4decd831 [PR #8897/d4fb6bf8 backport][stable-9] nmcli: conn_reload param and up/down states (#8975)
nmcli: conn_reload param and up/down states (#8897)

* Update nmcli module

* Update nmcli state

* Update test_nmcli

* Add CHANGELOG fragment

* PR Fixes

* Fix DOCUMENTATION block

(cherry picked from commit d4fb6bf8a6)

Co-authored-by: alexander <79072457+abakanovskii@users.noreply.github.com>
2024-10-03 16:13:11 +03:00
patchback[bot]
566ec0a002 [PR #8812/5d9a7ab2 backport][stable-9] keycloak_user_federation: remove lastSync param from kc API responses (#8977)
keycloak_user_federation: remove `lastSync` param from kc API responses (#8812)

* remove `lastSync` param from kc API responses

* add blank line to satisfy sanity check

* add changelog fragment

* fix NoneType error introduced by changed normalize func return value

(cherry picked from commit 5d9a7ab240)

Co-authored-by: fgruenbauer <gruenbauer@b1-systems.de>
2024-10-03 16:13:02 +03:00
patchback[bot]
2e72051b6c [PR #8719/92df5e8f backport][stable-9] open_iscsi: Make targets optional for a portal login (#8978)
open_iscsi: Make targets optional for a portal login (#8719)

* Make targets optional for a portal login

* Add changelog

* Fix check_rc variable

* Fix idempotence

* Fix linting

* PR fixes

* Linter fixes

* PR fixes

* Change variable name

(cherry picked from commit 92df5e8fec)

Co-authored-by: alexander <79072457+abakanovskii@users.noreply.github.com>
2024-10-03 16:12:50 +03:00
patchback[bot]
89d33bbd7b [PR #8971/7fc7af30 backport][stable-9] fix doc for cmd_runner_fmt.as_bool() (#8974)
fix doc for cmd_runner_fmt.as_bool() (#8971)

(cherry picked from commit 7fc7af306c)

Co-authored-by: Alexei Znamensky <103110+russoz@users.noreply.github.com>
2024-10-03 15:30:49 +03:00
patchback[bot]
76b6c8e184 [PR #8963/96dfb89b backport][stable-9] cmd_runner_guide: docs improvements (#8968)
cmd_runner_guide: docs improvements (#8963)

* cmd_runner_guide: docs improvements

* add note about suboptions

(cherry picked from commit 96dfb89b01)

Co-authored-by: Alexei Znamensky <103110+russoz@users.noreply.github.com>
2024-10-02 21:29:40 +03:00
patchback[bot]
fdc279def9 [PR #8965/daaa0087 backport][stable-9] pipx: remove unused param from the runner ctx.run() call (#8967)
pipx: remove unused param from the runner ctx.run() call (#8965)

remove unused param from the runner ctx.run() call

(cherry picked from commit daaa008713)

Co-authored-by: Alexei Znamensky <103110+russoz@users.noreply.github.com>
2024-10-02 21:23:11 +03:00
patchback[bot]
a471fa88b8 [PR #8909/2d660a12 backport][stable-9] flatpak: improve flatpak name parsing in _parse_flatpak_name (#8961)
flatpak: improve flatpak name parsing in `_parse_flatpak_name` (#8909)

* flatpak: improve flatpak name parsing in `_parse_flatpak_name`

* changelog: add changelog fragment

* flatpak: fix condition in `_is_flatpak_id` function

* chore: update changelog fragment

* docs(flatpak): add guidelines for application IDs in comments

(cherry picked from commit 2d660a1252)

Co-authored-by: Járedy Alves <jaredyalves@undefinedname.com>
2024-10-02 10:34:07 +03:00
patchback[bot]
bf4e5dc3c0 [PR #8923/83080cc0 backport][stable-9] keycloak_userprofile: fix empty response by removing parent filter when fetching userprofile component (#8960)
keycloak_userprofile: fix empty response by removing `parent` filter when fetching userprofile component (#8923)

* remove parent filter when fetching userprofile component

* add changelog fragment

* Update changelogs/fragments/8923-keycloak_userprofile-fix-empty-response-when-fetching-userprofile.yml

Co-authored-by: Felix Fontein <felix@fontein.de>

---------

Co-authored-by: Felix Fontein <felix@fontein.de>
(cherry picked from commit 83080cc005)

Co-authored-by: fgruenbauer <gruenbauer@b1-systems.de>
2024-10-02 09:55:34 +03:00
patchback[bot]
185bdaaa39 [PR #8925/7c913b23 backport][stable-9] Pass absolute paths to atomic_move() (#8959)
Pass absolute paths to atomic_move() (#8925)

Pass absolute paths to atmoic_move().

(cherry picked from commit 7c913b239a)

Co-authored-by: Felix Fontein <felix@fontein.de>
2024-10-01 22:52:56 +03:00
patchback[bot]
55d44975dd [PR #8944/a7d1b0fc backport][stable-9] python_runner/django_command: bugfixes (#8946)
python_runner/django_command: bugfixes (#8944)

* python_runner/django_command: bugfixes

* fix indentation

* join path_prefix with : when concatenating with PATH

* add changelog frag

(cherry picked from commit a7d1b0fc52)

Co-authored-by: Alexei Znamensky <103110+russoz@users.noreply.github.com>
2024-09-30 17:41:21 +03:00
patchback[bot]
43772cfbbb [PR #8899/ab84f163 backport][stable-9] Sort parameters in gitlab_group to aid in adding more params (#8945)
Sort parameters in gitlab_group to aid in adding more params (#8899)

(cherry picked from commit ab84f1632f)

Co-authored-by: Julien Lecomte <julien-lecomte@users.noreply.github.com>
2024-09-30 09:37:09 +03:00
Felix Fontein
e93b6231ec Prepare 9.5.0 release. 2024-09-28 08:36:54 +03:00
patchback[bot]
605a557a8d [PR #8894/8ef77d86 backport][stable-9] unit test helper: big revamp (#8943)
unit test helper: big revamp (#8894)

* initial commit

* multiple changes:

- TestCaseContext fixture no longer need to autouse=True
- Helper.from_module() allows extra param to specify yaml file
- test_django_check: adjusted .py and .yaml

* set fixtures per testcase

* set fixtures per testcase

* rollback to original state

* patch_ansible_module fixture

- now it works not only in parametrized functions but also directly with args

* tests/unit/plugins/modules/helper.py

- improved encapsulation, class Helper no longer knows details about test cases
- test functions no longer parametrized, that allows using test case fixtures per test function
- renamed 'context' to 'mock'

* enable Helper.from_list(), better param name 'ansible_module'

* adjusted test fiels to new helper

* remove unnecessary .license file

* fix bracket

* fix reference name

* Update tests/unit/plugins/modules/helper.py

Co-authored-by: Felix Fontein <felix@fontein.de>

* revert to parametrized test func instead of multiple funcs

---------

Co-authored-by: Felix Fontein <felix@fontein.de>
(cherry picked from commit 8ef77d8664)

Co-authored-by: Alexei Znamensky <103110+russoz@users.noreply.github.com>
2024-09-28 08:33:00 +03:00
patchback[bot]
d97f1a31ba [PR #8937/84e0190e backport][stable-9] Disk description now contains a StorageId and a RedfishURI (#8942)
Disk description now contains a StorageId and a RedfishURI (#8937)

* Disks controller is now uniquely identified by the controller ID

* Fix typo `StorageID` to `StorageId`

* Add changelog fragments

---------

Co-authored-by: Pierre-yves FONTANIERE <pyf@cc.in2p3.fr>
(cherry picked from commit 84e0190eee)

Co-authored-by: Pierre-yves Fontaniere <pyfontan@cc.in2p3.fr>
2024-09-28 08:10:49 +03:00
patchback[bot]
5949b29a12 [PR #8933/bc6ae849 backport][stable-9] Move ansible-core 2.15 tests to EOL tests (#8934)
Move ansible-core 2.15 tests to EOL tests (#8933)

Move ansible-core 2.15 tests to EOL tests.

(cherry picked from commit bc6ae849b3)

Co-authored-by: Felix Fontein <felix@fontein.de>
2024-09-26 16:06:03 +03:00
patchback[bot]
993d580adc [PR #8887/0bc5f248 backport][stable-9] one_service: fix recreation (#8932)
one_service: fix recreation (#8887)

* Fix one_service unique creation

* Revert empty space

* Add CHANGELOG fragment

* Update CHANGELOG fragment

(cherry picked from commit 0bc5f24863)

Co-authored-by: alexander <79072457+abakanovskii@users.noreply.github.com>
2024-09-26 11:38:34 +03:00
patchback[bot]
1ac7783c5c [PR #8929/4700accb backport][stable-9] CmdRunner: missing parameter for get_best_parsable_locale() (#8930)
CmdRunner: missing parameter for get_best_parsable_locale() (#8929)

* CmdRunner: missing parameter for get_best_parsable_locale()

* add changelog frag

(cherry picked from commit 4700accbff)

Co-authored-by: Alexei Znamensky <103110+russoz@users.noreply.github.com>
2024-09-26 11:28:16 +03:00
patchback[bot]
f0724c0975 [PR #8922/d356e255 backport][stable-9] Deprecate hipchat module (#8924)
Deprecate hipchat module (#8922)

Deprecate hipchat module.

(cherry picked from commit d356e255e0)

Co-authored-by: Felix Fontein <felix@fontein.de>
2024-09-25 22:33:28 +03:00
patchback[bot]
f3aca8a575 [PR #8917/89ad40db backport][stable-9] proxmox inventory: remove duplicated credentials line (#8919)
proxmox inventory: remove duplicated credentials line (#8917)

* proxmox inventory: remove duplicated credentials line

* fixup! proxmox inventory: remove duplicated credentials line

* fixup! proxmox inventory: remove duplicated credentials line

(cherry picked from commit 89ad40db41)

Co-authored-by: Per Fide <perfide@users.noreply.github.com>
2024-09-25 14:01:03 +03:00
patchback[bot]
ad1cf82a34 [PR #8913/199ba0a1 backport][stable-9] Fix parameter name (#8916)
Fix parameter name (#8913)

(cherry picked from commit 199ba0a170)

Co-authored-by: Niko Ehrenfeuchter <mail@he1ix.org>
2024-09-24 23:10:55 +03:00
patchback[bot]
42d0a55984 [PR #8910/293021c3 backport][stable-9] Add stable-2.18 to CI (#8912)
Add stable-2.18 to CI (#8910)

Add stable-2.18 to CI.

(cherry picked from commit 293021c3dd)

Co-authored-by: Felix Fontein <felix@fontein.de>
2024-09-24 14:00:45 +03:00
patchback[bot]
4f4d962f7c [PR #8877/deaad6e5 backport][stable-9] keycloak_realm: fix change detection in check mode by normalizing realms beforehand (#8903)
keycloak_realm: fix change detection in check mode by normalizing realms beforehand (#8877)

* keycloak_realm: fix change detection in check mode by normalizing realms beforehand

* add changelog fragment

(cherry picked from commit deaad6e547)

Co-authored-by: fgruenbauer <gruenbauer@b1-systems.de>
2024-09-23 21:46:37 +03:00
patchback[bot]
5343880fa5 [PR #8900/a32f1d69 backport][stable-9] ipa_hostgroup: fix state params (#8906)
ipa_hostgroup: fix state params (#8900)

* Fix ipa_hostgroup

* Add CHANGELOG fragment

(cherry picked from commit a32f1d699b)

Co-authored-by: alexander <79072457+abakanovskii@users.noreply.github.com>
2024-09-23 21:46:25 +03:00
patchback[bot]
5ea44edc64 [PR #8895/0bf84ba2 backport][stable-9] fix comprehension (#8896)
fix comprehension (#8895)

* fix comprehension

* add changelog frag

* Update changelogs/fragments/8895-fix-comprehension.yaml

Co-authored-by: Felix Fontein <felix@fontein.de>

---------

Co-authored-by: Felix Fontein <felix@fontein.de>
(cherry picked from commit 0bf84ba2b6)

Co-authored-by: Alexei Znamensky <103110+russoz@users.noreply.github.com>
2024-09-22 13:15:21 +03:00
patchback[bot]
8152cb3e1f [PR #8785/ac302eb7 backport][stable-9] keycloak_user_federation: set krbPrincipalAttribute to '' if unset in kc responses (#8892)
keycloak_user_federation: set `krbPrincipalAttribute` to `''` if unset in kc responses (#8785)

* set `krbPrincipalAttribute` to `''` if unset in kc before and after responses

* add changelog fragment

* Update changelogs/fragments/8785-keycloak_user_federation-set-krbPrincipalAttribute-to-empty-string-if-missing.yaml

Co-authored-by: Felix Fontein <felix@fontein.de>

---------

Co-authored-by: Felix Fontein <felix@fontein.de>
(cherry picked from commit ac302eb77d)

Co-authored-by: fgruenbauer <gruenbauer@b1-systems.de>
2024-09-21 10:42:43 +03:00
patchback[bot]
eae0c4f92b [PR #8885/38479ee9 backport][stable-9] npm: Add force flag (#8893)
npm: Add force flag (#8885)

* Add force flag for nmp module

* Add CHANGELOG fragment

* Add force to cmdrunner

* Update CHANGELOG

* Add comma

(cherry picked from commit 38479ee9ff)

Co-authored-by: alexander <79072457+abakanovskii@users.noreply.github.com>
2024-09-21 10:42:31 +03:00
patchback[bot]
57277e0661 [PR #8886/27cb0c90 backport][stable-9] Update example for community.general.homebrew_services (#8890)
Update example for community.general.homebrew_services (#8886)

(cherry picked from commit 27cb0c9090)

Co-authored-by: Florian Weber <florian@webflo.org>
2024-09-20 20:15:48 +02:00
patchback[bot]
53a941cee7 [PR #8876/6af74d1b backport][stable-9] multiple modules: improve dict.items() loops (#8882)
multiple modules: improve dict.items() loops (#8876)

* multiple modules: improve dict.items() loops

* simplify in memset_* modules

* add changelog frag

(cherry picked from commit 6af74d1ba6)

Co-authored-by: Alexei Znamensky <103110+russoz@users.noreply.github.com>
2024-09-18 17:50:02 +02:00
patchback[bot]
e6edf9cdea [PR #8653/80f48cce backport][stable-9] Redfish: Added steps to allow a user to change their password when their account requires a password change (#8881)
Redfish: Added steps to allow a user to change their password when their account requires a password change (#8653)

* Redfish: Added steps to allow a user to change their password when their account requires a password change

Signed-off-by: Mike Raineri <michael.raineri@dell.com>

* Bug fix

Signed-off-by: Mike Raineri <michael.raineri@dell.com>

* Bug fix

Signed-off-by: Mike Raineri <michael.raineri@dell.com>

* Bug fixes with return data handling

Signed-off-by: Mike Raineri <michael.raineri@dell.com>

* Added changelog fragment

Signed-off-by: Mike Raineri <michael.raineri@dell.com>

* Update changelogs/fragments/8652-Redfish-Password-Change-Required.yml

Co-authored-by: Felix Fontein <felix@fontein.de>

---------

Signed-off-by: Mike Raineri <michael.raineri@dell.com>
Co-authored-by: Felix Fontein <felix@fontein.de>
(cherry picked from commit 80f48cceb4)

Co-authored-by: Mike Raineri <mraineri@gmail.com>
2024-09-18 17:49:15 +02:00
patchback[bot]
5550ba1946 [PR #8860/f93883aa backport][stable-9] gitlab_runner: update requirements in docs (#8880)
gitlab_runner: update requirements in docs (#8860)

* Update gitlab_runner.py

Be specific related requirements for package version. This difference change the whole dependency chain for playbook.

* Update plugins/modules/gitlab_runner.py

Co-authored-by: Felix Fontein <felix@fontein.de>

---------

Co-authored-by: Felix Fontein <felix@fontein.de>
(cherry picked from commit f93883aa20)

Co-authored-by: Péter Mikáczó <petermikaczo@gmail.com>
2024-09-17 15:13:34 +02:00
patchback[bot]
374378beeb [PR #8875/4123934b backport][stable-9] reformat module docs (#8878)
reformat xfconf docs (#8875)

* reformat module docs

* fix sanity

(cherry picked from commit 4123934b46)

Co-authored-by: Alexei Znamensky <103110+russoz@users.noreply.github.com>
2024-09-17 15:13:23 +02:00
patchback[bot]
5222df306b [PR #8870/2f1df973 backport][stable-9] Remove private key and certificates from documentation (#8874)
Remove private key and certificates from documentation (#8870)

* Remove private key and certificate from example.

* Censor certificates in examples.

(cherry picked from commit 2f1df973a6)

Co-authored-by: Felix Fontein <felix@fontein.de>
2024-09-16 21:56:17 +02:00
patchback[bot]
788c722b3e [PR #8859/e4472b32 backport][stable-9] pipx/pipx_info: refactor doc fragment (#8869)
pipx/pipx_info: refactor doc fragment (#8859)

* pipx/pipx_info: refactor doc fragment

* pipx/pipx_info: refactor common options to module_utils

(cherry picked from commit e4472b322b)

Co-authored-by: Alexei Znamensky <103110+russoz@users.noreply.github.com>
2024-09-14 09:38:19 +02:00
patchback[bot]
2ddbda2aa7 [PR #8856/37dd6ec8 backport][stable-9] jira: adjust module for old vardict deprecation (#8864)
jira: adjust module for old vardict deprecation (#8856)

* jira: adjust module for old vardict deprecation

* add changelog frag

(cherry picked from commit 37dd6ec8a3)

Co-authored-by: Alexei Znamensky <103110+russoz@users.noreply.github.com>
2024-09-13 22:59:05 +02:00
patchback[bot]
cb939cbb75 [PR #8858/94472dd7 backport][stable-9] use dict comprehension in plugins, part 4 (#8865)
use dict comprehension in plugins, part 4 (#8858)

* use dict comprehension in plugins, part 4

* add changelog frag

(cherry picked from commit 94472dd7e5)

Co-authored-by: Alexei Znamensky <103110+russoz@users.noreply.github.com>
2024-09-13 22:58:57 +02:00
patchback[bot]
7db1613730 [PR #8861/76ebda7f backport][stable-9] snap tests: re-enable test for --dangerous using smaller snap (#8868)
snap tests: re-enable test for --dangerous using smaller snap (#8861)

(cherry picked from commit 76ebda7faf)

Co-authored-by: Alexei Znamensky <103110+russoz@users.noreply.github.com>
2024-09-13 22:58:47 +02:00
patchback[bot]
38a16b421d [PR #8855/41d87f5c backport][stable-9] gio_mime: adjust module for old vardict deprecation (#8863)
gio_mime: adjust module for old vardict deprecation (#8855)

* gio_mime: adjust module for old vardict deprecation

* add changelog frag

(cherry picked from commit 41d87f5c9d)

Co-authored-by: Alexei Znamensky <103110+russoz@users.noreply.github.com>
2024-09-13 22:58:33 +02:00
Felix Fontein
bd8b7e3737 The next expected release will be 9.5.0. 2024-09-09 19:45:07 +02:00
Felix Fontein
057f7196c7 Release 9.4.0. 2024-09-09 19:14:09 +02:00
patchback[bot]
8d8fc3d3ba [PR #8831/2ae41fa8 backport][stable-9] keycloak_user_federation: get the before mappers from before_comp to fix UnboundLocalError (#8850)
keycloak_user_federation: get the before mappers from `before_comp` to fix `UnboundLocalError` (#8831)

* fix: get the before mappers from `before_comp`

* add changelog fragment

* Adjust changelog fragment.

---------

Co-authored-by: Felix Fontein <felix@fontein.de>
(cherry picked from commit 2ae41fa83f)

Co-authored-by: fgruenbauer <gruenbauer@b1-systems.de>
2024-09-09 12:17:13 +00:00
patchback[bot]
5f7a3ac896 [PR #8651/529af498 backport][stable-9] keycloak_userprofile: new module (#8848)
keycloak_userprofile: new module (#8651)

keycloak_userprofile: new keycloak module to manage user profiles (#8651)

(cherry picked from commit 529af4984c)

Co-authored-by: Eike Waldt <waldt@b1-systems.de>
2024-09-09 14:06:42 +02:00
patchback[bot]
23ac1b62c3 [PR #8843/d73f977b backport][stable-9] Remove link to Google Groups mailing list (#8846)
Remove link to Google Groups mailing list (#8843)

Remove link to Google Groups mailing list.

Ref: https://groups.google.com/g/ansible-project/c/B0oKR0aQqXs
(cherry picked from commit d73f977b7a)

Co-authored-by: Felix Fontein <felix@fontein.de>
2024-09-08 16:52:09 +02:00
patchback[bot]
186d410f63 [PR #8833/26df6c76 backport][stable-9] use dict comprehension in plugins, part 3 (#8835)
use dict comprehension in plugins, part 3 (#8833)

* use dict comprehension in plugins, part 3

* add changelog frag

(cherry picked from commit 26df6c7657)

Co-authored-by: Alexei Znamensky <103110+russoz@users.noreply.github.com>
2024-09-08 14:46:13 +02:00
patchback[bot]
1978100d25 [PR #8827/afd754e3 backport][stable-9] (doc) random_string lookup: fix examples (#8842)
(doc) random_string lookup: fix examples (#8827)

(cherry picked from commit afd754e384)

Co-authored-by: Samuel-BF <36996277+Samuel-BF@users.noreply.github.com>
2024-09-08 14:45:59 +02:00
patchback[bot]
6fec5a7005 [PR #8823/ea389e70 backport][stable-9] bugfix(keycloak): fix parameters for realm key creation (#8840)
bugfix(keycloak): fix parameters for realm key creation (#8823)

* bugfix(keycloak): fix parameters for realm key creation

* supply changelog fragment

* fix formatting

* fix formatting

* Update changelogs/fragments/8823-keycloak-realm-key.yml

Co-authored-by: Felix Fontein <felix@fontein.de>

---------

Co-authored-by: Felix Fontein <felix@fontein.de>
(cherry picked from commit ea389e7045)

Co-authored-by: Björn Bösel <bjoernboesel@gmail.com>
2024-09-08 14:45:47 +02:00
patchback[bot]
aca2afc6f8 [PR #8761/982b8d89 backport][stable-9] keycloak_user_federation: sort desired and after mappers by name (#8837)
keycloak_user_federation: sort desired and after mappers by name (#8761)

* sort desired mappers by name

* sort mappers fetched after update by name

* only sort mapper list if there are desired mappers specified

* add fallback `''` in case `name` is not a key or `None` when sorting mappers

* add changelog fragment

(cherry picked from commit 982b8d89b7)

Co-authored-by: fgruenbauer <gruenbauer@b1-systems.de>
2024-09-08 14:45:31 +02:00
patchback[bot]
adda8d3113 [PR #8769/d9b0c42f backport][stable-9] Add one_vnet module (#8838)
Add one_vnet module (#8769)

* Add one_vnet module

* Add one_vnet integration tests

* Update BOTMETA.yml

* Update aliases

---------

Co-authored-by: Александр Бакановский <abakanovskii@astralinux.ru>
(cherry picked from commit d9b0c42f5f)

Co-authored-by: alexander <79072457+abakanovskii@users.noreply.github.com>
2024-09-08 14:45:18 +02:00
Felix Fontein
21ed66a097 Prepare 9.4.0. 2024-09-07 09:51:04 +02:00
patchback[bot]
73a1ac2f1c [PR #8809/43f8adf1 backport][stable-9] pipx: add new states (#8834)
pipx: add new states (#8809)

* ensure minimum version of pip

* ensure pipx 1.7.0 is installed

* pipx: add new states/params

* add tests

* add license to json file

* Update plugins/modules/pipx.py

Co-authored-by: Felix Fontein <felix@fontein.de>

* fix uninject tests

* add changelog frag

* fix doc per review

* refactor license out of pipx spec file

* Update plugins/modules/pipx.py

Co-authored-by: Felix Fontein <felix@fontein.de>

* Update tests/integration/targets/pipx/files/spec.json.license

Co-authored-by: Felix Fontein <felix@fontein.de>

---------

Co-authored-by: Felix Fontein <felix@fontein.de>
(cherry picked from commit 43f8adf1a5)

Co-authored-by: Alexei Znamensky <103110+russoz@users.noreply.github.com>
2024-09-07 09:37:47 +02:00
patchback[bot]
7c3b441246 [PR #8822/7e978c77 backport][stable-9] use dict comprehension in plugins, part 2 (#8832)
use dict comprehension in plugins, part 2 (#8822)

* use dict comprehension in plugins

* add changelog frag

(cherry picked from commit 7e978c77b4)

Co-authored-by: Alexei Znamensky <103110+russoz@users.noreply.github.com>
2024-09-05 22:01:56 +02:00
patchback[bot]
19613ce111 [PR #8794/249126f4 backport][stable-9] proxmox inventory: fixing possible concatenation error (#8818)
proxmox inventory: fixing possible concatenation error (#8794)

* Fixing possible concatination error

* Create 8794-Fixing-possible-concatination-error.yaml

* Update 8794-Fixing-possible-concatination-error.yaml

Updating changelog

(cherry picked from commit 249126f429)

Co-authored-by: Simon Siebert <Mail@simonsiebert.de>
2024-09-01 20:55:19 +02:00
patchback[bot]
594ca4f983 [PR #8815/593d302f backport][stable-9] Fix and enable test for datadog_downtime (#8821)
Fix and enable test for datadog_downtime (#8815)

The test has been disabled because it started to fail after an update of
the Datadog API client. The issue itself (id cannot be set in
constructor) and other issues (module name, additional attribute in API
responses) are now fixed. The test is now working fine again.

Fixes #3219.

(cherry picked from commit 593d302f0b)

Co-authored-by: Stefan Birkner <github@stefan-birkner.de>
2024-09-01 20:55:10 +02:00
patchback[bot]
af08ea33b1 [PR #8814/ecc048bc backport][stable-9] Use dict comprehension in plugins (#8819)
Use dict comprehension in plugins (#8814)

* use dict comprehension in plugins

* Apply suggestions from code review

* add changelog frag

* fix references in changelog frag

(cherry picked from commit ecc048bc12)

Co-authored-by: Alexei Znamensky <103110+russoz@users.noreply.github.com>
2024-09-01 20:55:02 +02:00
patchback[bot]
7f729d99a2 [PR #8779/96d5e6e5 backport][stable-9] copr: add includepkgs functionality (#8808)
copr: add includepkgs functionality (#8779)

* Limit package for Copr using includepkgs

* Limit package for Copr using includepkgs

* Limit package for Copr using includepkgs

* Limit package for Copr using includepkgs

* Limit package for Copr using includepkgs

* Added changes in copr module

* Excludepkgs parameter add

* Update module and params to handle a list + Docs updated

* Update module and params to handle a list + Docs updated

(cherry picked from commit 96d5e6e50e)

Co-authored-by: Shubham Singh Sugara <37795429+shubhamsugara22@users.noreply.github.com>
2024-08-27 09:02:00 +02:00
patchback[bot]
5b62e0edd6 [PR #8791/45987584 backport][stable-9] MH cause_changes: deprecate params (#8806)
MH cause_changes: deprecate params (#8791)

* MH cause_changes: deprecate params

* add changelog frag

* Update changelogs/fragments/8791-mh-cause-changes-param-depr.yml

Co-authored-by: Felix Fontein <felix@fontein.de>

---------

Co-authored-by: Felix Fontein <felix@fontein.de>
(cherry picked from commit 4598758419)

Co-authored-by: Alexei Znamensky <103110+russoz@users.noreply.github.com>
2024-08-26 20:10:04 +02:00
patchback[bot]
b935dcedd8 [PR #8793/9c9c4cbc backport][stable-9] pipx/pipx_info: add parameter global (#8807)
pipx/pipx_info: add parameter `global` (#8793)

* pipx/pipx_info: add new parameters

* add test for --global, refactor int test main file

* ensure initial state of test

* ensure PATH includes /usr/local/bin

* ensure PATH includes /usr/local/bin for entire block

* ensure minimum version of pip

* ensure pipx 1.6.0 is installed

* push recommendation for pipx 1.7.0 instead of 1.6.0

* add changelog frag

* add deprecatons to changelog frag

* add deprecatons to changelog frag, better

* Update changelogs/fragments/8793-pipx-global.yml

Co-authored-by: Felix Fontein <felix@fontein.de>

* Update changelogs/fragments/8793-pipx-global.yml

Co-authored-by: Felix Fontein <felix@fontein.de>

---------

Co-authored-by: Felix Fontein <felix@fontein.de>
(cherry picked from commit 9c9c4cbc3e)

Co-authored-by: Alexei Znamensky <103110+russoz@users.noreply.github.com>
2024-08-26 11:35:39 +02:00
patchback[bot]
c58181bdc9 [PR #8760/5192ffe5 backport][stable-9] gitlab_project: add param "issues_access_level" (#8805)
gitlab_project: add param "issues_access_level" (#8760)

gitlab_project: add option `issues_access_level` to enable/disable project

(cherry picked from commit 5192ffe5b3)

Co-authored-by: Julien Lecomte <julien-lecomte@users.noreply.github.com>
2024-08-26 11:35:32 +02:00
patchback[bot]
f71af21287 [PR #8764/7dc4429c backport][stable-9] keycloak_user_federation: add module arg to make mapper removal optout (#8804)
keycloak_user_federation: add module arg to make mapper removal optout (#8764)

* add module arg to make mapper removal optout

* change parameter name to snake case: remove_unspecified_mappers

* add period to parameter description

Co-authored-by: Felix Fontein <felix@fontein.de>

* use dict indexing to get parameter instead of `.get()`

* add changelog fragment

* Update changelogs/fragments/8764-keycloak_user_federation-make-mapper-removal-optout.yml

Co-authored-by: Felix Fontein <felix@fontein.de>

* add `version_added` to argument description

Co-authored-by: Felix Fontein <felix@fontein.de>

* Update plugins/modules/keycloak_user_federation.py

Co-authored-by: Felix Fontein <felix@fontein.de>

---------

Co-authored-by: Felix Fontein <felix@fontein.de>
(cherry picked from commit 7dc4429c9c)

Co-authored-by: fgruenbauer <gruenbauer@b1-systems.de>
2024-08-26 11:35:25 +02:00
patchback[bot]
1a48ebd699 [PR #8792/3607e3d0 backport][stable-9] pipx: add doc example (#8799)
pipx: add doc example (#8792)

(cherry picked from commit 3607e3d012)

Co-authored-by: Alexei Znamensky <103110+russoz@users.noreply.github.com>
2024-08-26 11:35:18 +02:00
patchback[bot]
5e1be68b01 [PR #8790/573a7b97 backport][stable-9] Fix gitlab_project container_expiration_policy for project create (#8801)
Fix gitlab_project container_expiration_policy for project create (#8790)

* Fix gitlab_project container_expiration_policy for project create

* Check for container_expiration_policy presence before renaming it

* Add missing links to changelog fragment

* Fix changelog grammar

(cherry picked from commit 573a7b97c6)

Co-authored-by: Veikko Virrankoski <71337077+vvirrank@users.noreply.github.com>
2024-08-26 11:35:05 +02:00
patchback[bot]
812431e7fe [PR #8796/e9071e98 backport][stable-9] Fix gitlab access token crash in check mode for new tokens (#8802)
Fix gitlab access token crash in check mode for new tokens (#8796)

Fix crash in check mode when attempting to create a new gitlab access token

(cherry picked from commit e9071e9871)

Co-authored-by: Veikko Virrankoski <71337077+vvirrank@users.noreply.github.com>
2024-08-26 11:34:53 +02:00
patchback[bot]
04f36f0bac [PR #8771/e3a3c6d5 backport][stable-9] ModuleHelper guide (#8786)
ModuleHelper guide (#8771)

* initial commit

* fix initial version

* add quickstart and high-level outline

* MH guide progress

* MH guide progress (up to params,vars,output)

* adjustments

* MH guide progress (up to handling changes)

* MH guide progress (up to Exceptions)

* typo

* change section from note to important

* MH guide progress (added StateModuleHelper)

* minor improvement

* MH guide progress (added decorators)

* typo

* minor adjustments

* remove line

* complete MH guide

* adjustments

* adjustments

* change paragraph into seealso

* rearrange sections, plus wordsmithing

* adjustments

* wordsmithing

* fix references

(cherry picked from commit e3a3c6d58f)

Co-authored-by: Alexei Znamensky <103110+russoz@users.noreply.github.com>
2024-08-21 16:10:32 +00:00
patchback[bot]
2f3d3aaf76 [PR #8762/b79ac4f0 backport][stable-9] keycloak_user_federation: fix key error when removing mappers in update (#8781)
keycloak_user_federation: fix key error when removing mappers in update (#8762)

* remove new mappers without an id from list comprehension

* add changelog fragment

* Update changelogs/fragments/8762-keycloac_user_federation-fix-key-error-when-updating.yml

Co-authored-by: Felix Fontein <felix@fontein.de>

---------

Co-authored-by: Felix Fontein <felix@fontein.de>
(cherry picked from commit b79ac4f0ac)

Co-authored-by: fgruenbauer <gruenbauer@b1-systems.de>
2024-08-20 09:11:52 +02:00
patchback[bot]
e7024c3f97 [PR #8776/e5bc38d8 backport][stable-9] MH: use mute_vardict_deprecation (#8782)
MH: use mute_vardict_deprecation (#8776)

* use mute_vardict_deprecation

* add changelog frag

(cherry picked from commit e5bc38d856)

Co-authored-by: Alexei Znamensky <103110+russoz@users.noreply.github.com>
2024-08-20 09:11:36 +02:00
patchback[bot]
0c2642aa2e [PR #8766/c84fb557 backport][stable-9] MH deco: minor refactor (#8775)
MH deco: minor refactor (#8766)

* MH deco: minor refactor

* adjustments and improvement in test

* sanity fix

* use func.__self__

* simplify use of self

* add changelog frag

(cherry picked from commit c84fb5577b)

Co-authored-by: Alexei Znamensky <103110+russoz@users.noreply.github.com>
2024-08-17 18:12:16 +02:00
patchback[bot]
2f62b6bbc6 [PR #8770/14e86bde backport][stable-9] one_template: update name in copyright (#8774)
one_template: update name in copyright (#8770)

finally got it changed this year :)

(cherry picked from commit 14e86bde07)

Co-authored-by: Jyrki Gadinger <nilsding@nilsding.org>
2024-08-17 18:12:08 +02:00
Felix Fontein
5c10ed5f5c Improve communication link description.
(cherry picked from commit 9571ec7c72)
2024-08-15 21:42:28 +02:00
patchback[bot]
a4bac47520 [PR #8759/e1b5ddb0 backport][stable-9] gitlab_project: sort parameters in order to avoid futur merge conflicts (#8763)
gitlab_project: sort parameters in order to avoid futur merge conflicts (#8759)

(cherry picked from commit e1b5ddb050)

Co-authored-by: Julien Lecomte <julien-lecomte@users.noreply.github.com>
2024-08-14 19:57:38 +02:00
Felix Fontein
b396ceb6c3 Next expected release is 9.4.0. 2024-08-12 18:30:01 +02:00
Felix Fontein
e4911a0278 Release 9.3.0. 2024-08-12 17:27:14 +02:00
patchback[bot]
1b3e9d8e99 [PR #8756/34519a5e backport][stable-9] Improve communication info (#8758)
Improve communication info (#8756)

Improve communication info.

(cherry picked from commit 34519a5ecb)

Co-authored-by: Felix Fontein <felix@fontein.de>
2024-08-12 17:23:17 +02:00
patchback[bot]
6243112067 [PR #8732/4cb4c608 backport][stable-9] README: Add Communication section with Forum information (#8755)
README: Add Communication section with Forum information (#8732)

* README: Add Communication section with Forum information

* Changelog fragment isn't needed for README change.

* Distinguish between Get Help and the community-general tag.

* Update links.

---------

Co-authored-by: Felix Fontein <felix@fontein.de>
(cherry picked from commit 4cb4c608d0)

Co-authored-by: Andrew Klychkov <aklychko@redhat.com>
2024-08-12 12:44:25 +02:00
patchback[bot]
7d23c90c6e [PR #8713/0f59bb7a backport][stable-9] Get interfaces for Proxmox LXC containers (#8750)
Get interfaces for Proxmox LXC containers (#8713)

* Get interfaces for Proxmox LXC containers

* Add changelog

* Don't use bare except

* Update changelog from suggestion

Co-authored-by: Felix Fontein <felix@fontein.de>

* Only lookup interfaces for running containers

* Ignore not implemented status

* Check that key exists in properties dict

* define ignore errors in mock

* Use not in

---------

Co-authored-by: Felix Fontein <felix@fontein.de>
(cherry picked from commit 0f59bb7a99)

Co-authored-by: Scott Langendyk <scott@langendyk.com>
2024-08-12 08:07:31 +02:00
patchback[bot]
825bd81e44 [PR #8688/e7480ad2 backport][stable-9] gitlab_project: Add some missing params (#8742)
gitlab_project: Add some missing params (#8688)

(cherry picked from commit e7480ad29e)

Co-authored-by: Julien Lecomte <julien-lecomte@users.noreply.github.com>
2024-08-12 08:07:18 +02:00
patchback[bot]
e10f95836e [PR #8735/57e28e5a backport][stable-9] keycloak_identity_provider: get cleartext clientsecret (#8744)
keycloak_identity_provider: get cleartext clientsecret (#8735)

* get cleartext `clientSecret` from full realm info

* add mock get_realm call to existing tests; add new no_change_when_present test

* add changelog fragment

* remove blank lines

* Update changelog.

---------

Co-authored-by: Felix Fontein <felix@fontein.de>
(cherry picked from commit 57e28e5a73)

Co-authored-by: fgruenbauer <gruenbauer@b1-systems.de>
2024-08-12 08:07:10 +02:00
patchback[bot]
176f6a62ae [PR #8689/8989b6c4 backport][stable-9] Namespace the passwordstore lockfile (#8746)
Namespace the passwordstore lockfile (#8689)

* Namespace the lockfile

When passwordstore needs to grab a lock, it creates a statically file (within /tmp, typically). This is unfortunate, when there might be more than one user using the passwordstore functionality on that machine. Prepend the user to the filename, to bypass further issues.

* Update plugins/lookup/passwordstore.py

specifically reference the argument number in the format string.

Co-authored-by: Felix Fontein <felix@fontein.de>

* Add changelog fragment for PR#8689

* Update 8689-passwordstore-lock-naming.yml

I was sure that was a copy/paste.

* Update changelogs/fragments/8689-passwordstore-lock-naming.yml

specify the type of plugin

Co-authored-by: Felix Fontein <felix@fontein.de>

---------

Co-authored-by: Felix Fontein <felix@fontein.de>
(cherry picked from commit 8989b6c4d4)

Co-authored-by: Adam Tygart <adam.tygart@gmail.com>
2024-08-12 08:06:57 +02:00
patchback[bot]
b1b6134f69 [PR #8682/158947f5 backport][stable-9] Add support for multiple locales in locale_gen (#8747)
Add support for multiple locales in locale_gen (#8682)

* Add support for multiple locales in locale_gen

* Add changelog fragment

* Remove extraneous newlines

* Remove typehints

* Add 'before version' to names documentation

* Remove extraneous comment

* Replace fstring with .format

* Refer to issue in changelog fragment

Co-authored-by: Felix Fontein <felix@fontein.de>

* Clarify version

Co-authored-by: Felix Fontein <felix@fontein.de>

* Add newline between examples

Co-authored-by: Felix Fontein <felix@fontein.de>

* Use semantic markup for locale value

Co-authored-by: Felix Fontein <felix@fontein.de>

---------

Co-authored-by: Felix Fontein <felix@fontein.de>
(cherry picked from commit 158947f5e5)

Co-authored-by: Matthias Kunnen <matthias.kunnen@gmail.com>
2024-08-12 08:06:47 +02:00
patchback[bot]
5103c3cea0 [PR #8708/76d0222a backport][stable-9] homebrew_cask: fix upgrade_all changed when nothing upgraded (#8749)
homebrew_cask: fix upgrade_all changed when nothing upgraded (#8708)

* homebrew_cask: fix upgrade_all changed when nothing upgraded

* Add changelog fragment

* Update changelogs/fragments/8708-homebrew_cask-fix-upgrade-all.yml

Co-authored-by: Felix Fontein <felix@fontein.de>

* Add .strip() to upgrade output check

Co-authored-by: Felix Fontein <felix@fontein.de>

---------

Co-authored-by: John Byrne <john@jobytech.net>
Co-authored-by: Felix Fontein <felix@fontein.de>
(cherry picked from commit 76d0222a83)

Co-authored-by: John Byrne <6145795+johnbyrneio@users.noreply.github.com>
2024-08-12 08:06:35 +02:00
patchback[bot]
8444902289 [PR #8741/73b54139 backport][stable-9] fix(opentelemetry): adjust default value for store_spans_in_file causing traces to be produced to a file named None (#8751)
fix(opentelemetry): adjust default value for `store_spans_in_file` causing traces to be produced to a file named `None` (#8741)

* fix(opentelemetry): adjust default value for `store_spans_in_file` causing traces to be produced to a file named `None`

The commit 5f481939d introduced `store_spans_in_file` with the default
value `None` as a string. This causes the value of `store_spans_in_file`
to be a not empty string, value=None as a string and not a null value.
The rest of the code check if the store_spans_in_file is not null which
squeezes the rest of the code. The following commit set the default
value as an empty string.

Signed-off-by: Wilfried Roset <wilfriedroset@users.noreply.github.com>

* fix(opentelemetry): No default value is better, reword changelog

Signed-off-by: Wilfried Roset <wilfriedroset@users.noreply.github.com>

---------

Signed-off-by: Wilfried Roset <wilfriedroset@users.noreply.github.com>
(cherry picked from commit 73b54139d6)

Co-authored-by: Wilfried ROSET <wilfriedroset@users.noreply.github.com>
2024-08-12 08:06:22 +02:00
patchback[bot]
2e1040bfa5 [PR #8695/2942eda8 backport][stable-9] keycloak_user_federation: add mapper removal (#8753)
keycloak_user_federation: add mapper removal (#8695)

* add unwanted mapper removal

* check for mapper updates in already fetched data to remove unnecessary API calls

* added mock answers and updated request count to match the added delete and fetch after_comp calls

* fix sanity issues

* add changelog fragment

* removed automatic field numbering from format

* replace filter expression with list comprehension

Co-authored-by: Felix Fontein <felix@fontein.de>

* add module name, link to issue and link to PR to changelog

Co-authored-by: Felix Fontein <felix@fontein.de>

* Use list comprehension.

---------

Co-authored-by: Felix Fontein <felix@fontein.de>
(cherry picked from commit 2942eda8e0)

Co-authored-by: fgruenbauer <gruenbauer@b1-systems.de>
2024-08-12 08:06:13 +02:00
patchback[bot]
5c5ae113c9 [PR #8674/b9244130 backport][stable-9] Gitlab_project: add options for repository_access_level and container_expiration_policy (#8740)
Gitlab_project: add options for repository_access_level and container_expiration_policy (#8674)

* gitlab_project: add option repository_access_level to disable repository

* gitlab_project: add option container_expiration_policy to schedule registry cleanup

* add chnagelog fragment

* Fix changelog fragment PR id

* Fix formatting

* Add required suboptions for container_expiration_policy

* Handle setting only a subset of policy attributes

* Fix changed indicator when policy attribute has null value

* Add descriptions to field clearing options in gitlab container_expiration_policy

(cherry picked from commit b9244130ef)

Co-authored-by: Veikko Virrankoski <71337077+vvirrank@users.noreply.github.com>
2024-08-11 20:21:49 +02:00
patchback[bot]
1d7843465d [PR #8644/9f340861 backport][stable-9] django_manage: rely on package idempotency to install virtualenv (#8737)
django_manage: rely on package idempotency to install virtualenv (#8644)

* rely on package idempotency to install virtualenv

* improve os package name logic in integration tests

* add os families debian, redhat

* add os families archlinux

* fix pkg name in archlinux

* improvement from PR

* typo

* Update tests/integration/targets/setup_os_pkg_name/tasks/debian.yml

Co-authored-by: Felix Fontein <felix@fontein.de>

* Update tests/integration/targets/setup_os_pkg_name/tasks/redhat.yml

Co-authored-by: Felix Fontein <felix@fontein.de>

---------

Co-authored-by: Felix Fontein <felix@fontein.de>
(cherry picked from commit 9f340861ad)

Co-authored-by: Alexei Znamensky <103110+russoz@users.noreply.github.com>
2024-08-10 13:16:07 +00:00
patchback[bot]
b79f286a66 [PR #8718/b16263eb backport][stable-9] Clarify contribution guide on integration tests (#8734)
Clarify contribution guide on integration tests (#8718)

* Clarify contribution guide on integration tests

* Improve test guide in CONTRIBUTING.md

* Uppercase Docker

Co-authored-by: Felix Fontein <felix@fontein.de>

* Improve test_name documentation

* Use working example in ansible-test integration docs

Co-authored-by: Felix Fontein <felix@fontein.de>

* Fix test_name in ansible-test integration being documented as required

---------

Co-authored-by: Felix Fontein <felix@fontein.de>
(cherry picked from commit b16263ebd7)

Co-authored-by: Matthias Kunnen <matthias.kunnen@gmail.com>
2024-08-08 11:32:48 +02:00
patchback[bot]
45e1d0a01a [PR #8725/5322dd94 backport][stable-9] Remove invalid cloud/gandi entry (#8728)
Remove invalid cloud/gandi entry (#8725)

Remove invalid cloud/gandi entry.

(cherry picked from commit 5322dd942e)

Co-authored-by: Felix Fontein <felix@fontein.de>
2024-08-08 10:16:37 +02:00
patchback[bot]
c7213ec1b5 [PR #8720/9a16eaf9 backport][stable-9] Fix pylint and pep8 issues exposed by latest ansible-core's ansible-test sanity checks (#8722)
Fix pylint and pep8 issues exposed by latest ansible-core's ansible-test sanity checks (#8720)

* Remove bad whitespace.

* 'Fixing' various used-before-assignment issues that pylint flagged.

(cherry picked from commit 9a16eaf9ba)

Co-authored-by: Felix Fontein <felix@fontein.de>
2024-08-07 15:49:06 +02:00
patchback[bot]
7c9dd8d8ad [PR #8675/5b2711bb backport][stable-9] pipx - add suffix parameter (#8721)
pipx - add suffix parameter (#8675)

* initial commit

* add changelog frag

* Add idempotency when using suffix

(cherry picked from commit 5b2711bbd3)

Co-authored-by: Alexei Znamensky <103110+russoz@users.noreply.github.com>
2024-08-07 15:12:40 +02:00
patchback[bot]
9842b057b0 [PR #8710/c517f1c4 backport][stable-9] ensure util-linux-extra is installed in Ubuntu 24.04 (#8715)
ensure util-linux-extra is installed in Ubuntu 24.04 (#8710)

(cherry picked from commit c517f1c483)

Co-authored-by: Alexei Znamensky <103110+russoz@users.noreply.github.com>
2024-08-05 22:16:24 +02:00
patchback[bot]
63eca8e68c [PR #8711/132faeae backport][stable-9] gconftool2: minor refactor (#8717)
gconftool2: minor refactor (#8711)

* gconftool2: minor refactor

* add changelog frag

(cherry picked from commit 132faeae34)

Co-authored-by: Alexei Znamensky <103110+russoz@users.noreply.github.com>
2024-08-05 22:16:15 +02:00
patchback[bot]
569bd30148 [PR #8605/229ed6da backport][stable-9] Add a keycloak module to query keys metadata (#8696)
Add a keycloak module to query keys metadata (#8605)

* feat(keycloak): module to query keys metadata

* chore: add thomasbach-dev as maintainer in team_keycloak

* test: adding a unit test for keycloak_real_keys_metadata_info module

* fixup! feat(keycloak): module to query keys metadata

(cherry picked from commit 229ed6dad9)

Co-authored-by: Thomas Bach <63091663+thomasbach-dev@users.noreply.github.com>
2024-08-01 17:33:43 +02:00
patchback[bot]
70acdf1f6d [PR #8329/29630049 backport][stable-9] homebrew: Add support for services functions (#8697)
homebrew: Add support for services functions (#8329)

* Homebrew: Add support for services functions

Fixes #8286.
Add a homebrew.services module for starting and stopping services
that are attached to homebrew packages.

* Address python version compatibility

* Addressing reviewer comments

* Addressing sanity logs

* Address str format issues

* Fixing Python 2.7 syntax issues

* Test alias, BOTMETA, grammar

* Attempt to fix brew in tests

* Address comments by russoz

* Fixing more dumb typos

* Actually uninstall black

* Update version_added in plugins/modules/homebrew_services.py

Co-authored-by: Felix Fontein <felix@fontein.de>

---------

Co-authored-by: Felix Fontein <felix@fontein.de>
(cherry picked from commit 2963004991)

Co-authored-by: Kit Ham <kitizz.devside@gmail.com>
2024-08-01 17:33:36 +02:00
patchback[bot]
86caa19f78 [PR #8657/7bbf32dc backport][stable-9] Update proxmox.py (#8699)
Update proxmox.py (#8657)

* Update proxmox.py

Added an example to create a new container with more network options (with ipv6 static configuration)

* Update proxmox.py

Made the linter happy.

* cleaned up dictionaries

Changed dictionaries from this format:
netif: '{"net0":"name=eth0,g...
to this:
netif:
  net0: "name=eth0,g...

* Update proxmox.py

false intendation and trailing whitespaces

(cherry picked from commit 7bbf32dc0e)

Co-authored-by: inDane <inDane@users.noreply.github.com>
2024-08-01 17:33:27 +02:00
patchback[bot]
f9acef140f [PR #8648/b6c6253b backport][stable-9] fix(modules/gitlab_runners): pass paused to gitlab (#8701)
fix(modules/gitlab_runners): pass paused to gitlab (#8648)

(cherry picked from commit b6c6253bfc)

Co-authored-by: Andreas Perhab <a.perhab@wtioit.at>
2024-08-01 17:33:11 +02:00
patchback[bot]
31a147f0eb [PR #8692/fd811df4 backport][stable-9] Update timezone.py (#8703)
Update timezone.py (#8692)

in order to set a timezone, root priviliages are needed on most distros, therefore i suggest to change an example to make it plug and play ready.

(cherry picked from commit fd811df414)

Co-authored-by: Mateusz Kiersnowski <82416937+Ganji00@users.noreply.github.com>
2024-08-01 17:33:05 +02:00
patchback[bot]
9b0ebef408 [PR #8624/37c85605 backport][stable-9] Type options of cache plugins (#8686)
Type options of cache plugins (#8624)

* Type options of cache plugins.

* Do not change type of _timeout for now.

(cherry picked from commit 37c8560542)

Co-authored-by: Felix Fontein <felix@fontein.de>
2024-07-28 22:39:07 +02:00
Felix Fontein
4c734ea134 Prepare 9.3.0 release. 2024-07-27 13:57:27 +02:00
patchback[bot]
ccf71fb483 [PR #8606/1a8f1721 backport][stable-9] Introduce bootc functionality (#8685)
Introduce bootc functionality (#8606)

* introduce bootc functionality

Signed-off-by: Ryan Cook <rcook@redhat.com>

Co-authored-by: Alexei Znamensky <103110+russoz@users.noreply.github.com>

* fix of test

Signed-off-by: Ryan Cook <rcook@redhat.com>

* switch stdout var

Signed-off-by: Ryan Cook <rcook@redhat.com>

* Feedback on NOTE format

Co-authored-by: Felix Fontein <felix@fontein.de>

* addition of trailing comma

Co-authored-by: Felix Fontein <felix@fontein.de>

* addition of trailing comma

Co-authored-by: Felix Fontein <felix@fontein.de>

* incorporating feedback from russoz

Signed-off-by: Ryan Cook <rcook@redhat.com>

* error in stdout

Signed-off-by: Ryan Cook <rcook@redhat.com>

* proper rc checking and status

Signed-off-by: Ryan Cook <rcook@redhat.com>

* linting

Signed-off-by: Ryan Cook <rcook@redhat.com>

* Update version

Co-authored-by: Felix Fontein <felix@fontein.de>

---------

Signed-off-by: Ryan Cook <rcook@redhat.com>
Co-authored-by: Alexei Znamensky <103110+russoz@users.noreply.github.com>
Co-authored-by: Felix Fontein <felix@fontein.de>
(cherry picked from commit 1a8f172186)

Co-authored-by: Ryan Cook <rcook@redhat.com>
2024-07-27 09:57:35 +02:00
patchback[bot]
585d4e8784 [PR #8646/e1148e6b backport][stable-9] Fix new Proxmox Volume handling (#8667)
Fix new Proxmox Volume handling (#8646)

* proxmox(fix): volume string builder

Half of the string was incorrectly discarded

* proxmox(fix): remove string conversion of values

 - Also converted `None` values into strings
 - Clashed with non-`str` values in documentation

* proxmox: add changelog fragment

* proxmox(fix): remove old & unused imports

* proxmox(fix): correctly turn maps into lists

* Update changelogs/fragments/8646-fix-bug-in-proxmox-volumes.yml

Co-authored-by: Felix Fontein <felix@fontein.de>

* Update plugins/modules/proxmox.py

Co-authored-by: Felix Fontein <felix@fontein.de>

---------

Co-authored-by: Felix Fontein <felix@fontein.de>
(cherry picked from commit e1148e6bdc)

Co-authored-by: JL Euler <Lithimlin@users.noreply.github.com>
2024-07-23 22:03:51 +02:00
patchback[bot]
47f235dc68 [PR #8633/e3fb817a backport][stable-9] pkgng - add option use_globs (default=true) (#8668)
pkgng - add option use_globs (default=true) (#8633)

* pkgng - add option use_globs (default=true) #8632

* Fix lint.

* Update changelogs/fragments/8632-pkgng-add-option-use_globs.yml

Co-authored-by: Felix Fontein <felix@fontein.de>

* Update plugins/modules/pkgng.py

Co-authored-by: Felix Fontein <felix@fontein.de>

* Update plugins/modules/pkgng.py

Co-authored-by: Felix Fontein <felix@fontein.de>

* Update tests/integration/targets/pkgng/tasks/install_single_package.yml

Co-authored-by: Felix Fontein <felix@fontein.de>

* Update plugins/modules/pkgng.py

Co-authored-by: Felix Fontein <felix@fontein.de>

---------

Co-authored-by: Felix Fontein <felix@fontein.de>
(cherry picked from commit e3fb817a21)

Co-authored-by: Vladimir Botka <vbotka@gmail.com>
2024-07-23 22:03:42 +02:00
patchback[bot]
08200954e9 [PR #8665/58f9860b backport][stable-9] Fix pipx tests (#8670)
Fix pipx tests (#8665)

* fix pipx tests

* enable pipx int tests

* replace ansible-lint with pylint in pipx test

* install jupyter in freebsd

* replace jupyter with mkdocs in pipx test

* adjust installed dependency for mkdocs

* fix pipx_info tests as well

(cherry picked from commit 58f9860ba7)

Co-authored-by: Alexei Znamensky <103110+russoz@users.noreply.github.com>
2024-07-23 22:03:31 +02:00
patchback[bot]
9e66e2c653 [PR #8654/52126b8f backport][stable-9] Add TLS certs params to redis (#8672)
Add TLS certs params to redis (#8654)

* add tls params to redis

* add PR number

* add example

* move doc to redis fragment

* Update changelogs/fragments/8654-add-redis-tls-params.yml

Co-authored-by: Felix Fontein <felix@fontein.de>

* rm aliases and add version_added

---------

Co-authored-by: Felix Fontein <felix@fontein.de>
(cherry picked from commit 52126b8fae)

Co-authored-by: Matthieu Bourgain <matthieu@bourgain.me>
2024-07-23 22:03:13 +02:00
patchback[bot]
510ad54062 [PR #8664/c0fd10e7 backport][stable-9] Various docs improvements (#8666)
Various docs improvements (#8664)

Various docs improvements.

(cherry picked from commit c0fd10e793)

Co-authored-by: Felix Fontein <felix@fontein.de>
2024-07-23 17:41:11 +02:00
patchback[bot]
a89ca23ecc [PR #8628/cac55beb backport][stable-9] Type options of callback plugins (#8663)
Type options of callback plugins (#8628)

Type options of callback plugins.

(cherry picked from commit cac55beb4f)

Co-authored-by: Felix Fontein <felix@fontein.de>
2024-07-21 22:16:23 +02:00
patchback[bot]
2261bd62de [PR #8627/ce65eb87 backport][stable-9] Type options of connection plugins (#8662)
Type options of connection plugins (#8627)

Type options of connection plugins.

(cherry picked from commit ce65eb8736)

Co-authored-by: Felix Fontein <felix@fontein.de>
2024-07-21 22:16:12 +02:00
patchback[bot]
3726b50a92 [PR #8626/daed4dcc backport][stable-9] Type options of lookup plugins (#8660)
Type options of lookup plugins (#8626)

Type options of lookup plugins.

(cherry picked from commit daed4dcc94)

Co-authored-by: Felix Fontein <felix@fontein.de>
2024-07-21 22:16:02 +02:00
patchback[bot]
037948fde9 [PR #8625/f9a56b9a backport][stable-9] Type options of inventory plugins (#8661)
Type options of inventory plugins (#8625)

Type options of inventory plugins.

(cherry picked from commit f9a56b9a9b)

Co-authored-by: Felix Fontein <felix@fontein.de>
2024-07-21 22:15:49 +02:00
patchback[bot]
9597b7c110 [PR #8623/a24ee93f backport][stable-9] Type options of become plugins (#8659)
Type options of become plugins (#8623)

Type options of become plugins.

(cherry picked from commit a24ee93f23)

Co-authored-by: Felix Fontein <felix@fontein.de>
2024-07-21 22:15:40 +02:00
patchback[bot]
780a7c6a38 [PR #8641/3a24aa5b backport][stable-9] Bump next expected version after release (#8642)
Bump next expected version after release (#8641)

(cherry picked from commit 3a24aa5b6d)

Co-authored-by: Andrew Klychkov <aklychko@redhat.com>
2024-07-15 10:50:06 +02:00
Andrew Klychkov
4c24a12462 Release 9.2.0 commit (#8640) 2024-07-15 08:11:49 +02:00
patchback[bot]
990fffb563 [PR #8634/a78f7b1e backport][stable-9] #8572 - Updated docs to include pip >= 20.3b1 requirement (#8637)
#8572 - Updated docs to include pip >= 20.3b1 requirement (#8634)

* #8572 - Updated docs to include pip >= 20.3b1 requirement

* Update plugins/modules/pip_package_info.py

Co-authored-by: Felix Fontein <felix@fontein.de>

---------

Co-authored-by: Felix Fontein <felix@fontein.de>
(cherry picked from commit a78f7b1e6a)

Co-authored-by: Daniel Poggenpohl <danowar2k@googlemail.com>
2024-07-14 22:29:06 +02:00
patchback[bot]
1d9bfc206b [PR #8214/83318c36 backport][stable-9] fix: sudosu not working on some BSD machines (#8631)
fix: sudosu not working on some BSD machines (#8214)

* fix: sudosu not working on some BSD machines

* fix: sudosu: added a flag (`alt_method`) to enhance compatibility with more versions of `su`

* Update changelogs/fragments/8214-sudosu-not-working-on-some-BSD-machines.yml

Co-authored-by: Felix Fontein <felix@fontein.de>

* Update plugins/become/sudosu.py

Co-authored-by: Felix Fontein <felix@fontein.de>

* Update plugins/become/sudosu.py

Co-authored-by: Felix Fontein <felix@fontein.de>

* Update plugins/become/sudosu.py

Co-authored-by: Felix Fontein <felix@fontein.de>

* Update plugins/become/sudosu.py

Co-authored-by: Felix Fontein <felix@fontein.de>

* fix: sudosu: lint

---------

Co-authored-by: Felix Fontein <felix@fontein.de>
(cherry picked from commit 83318c36aa)

Co-authored-by: leko <rexx0520@gmail.com>
2024-07-14 14:22:48 +02:00
patchback[bot]
3b74e9b646 [PR #8614/9dd2b71d backport][stable-9] nsupdate: fix 'index out of range' error when changing NS records (#8630)
nsupdate: fix 'index out of range' error when changing NS records (#8614)

* nsupdate: fix 'index out of range' error when changing NS records

* add clog fragment

* Update changelogs/fragments/8614-nsupdate-index-out-of-range.yml

Co-authored-by: Felix Fontein <felix@fontein.de>

---------

Co-authored-by: Felix Fontein <felix@fontein.de>
(cherry picked from commit 9dd2b71d04)

Co-authored-by: Art Win <art@make.lv>
2024-07-14 14:11:01 +02:00
patchback[bot]
37308c929b [PR #8510/21b16c1c backport][stable-9] Update VirtualBox Group parsing to align with documentation. (#8621)
Update VirtualBox Group parsing to align with documentation. (#8510)

* Update VirtualBox Group parsing to align with documentation.

Previously, we could separate the group string on the `/` char and
consider each element to be distinct, top-level groups. This change
implements the notion of nested groups and the use of the `,` char to
split multiple groups.

* Address code review comments.

Changed the implementation from a breaking change to a minor change by
introducing a new parameter to configure the behaviour. Keep the default
values to maintain the existing behaviour, and allow consumers an option
to opt-in.

* Fix line length.

The long lines were tripping CI. Reduce the length.

* Apply suggestions from code review

Update documentation to match expected conventions and correct the final rendered formatting.
Set the initial parent_group to `None` instead of `all` and rely on the parent class' inventory reconciliation logic to ensure consistent behaviour across different inventory plugins.

Co-authored-by: Felix Fontein <felix@fontein.de>

* Reword module arg description to avoid issues with CI.

One of the lines ended with a colon character which made the CI tests
fail since it would interpret it as a YAML key. Reworded the description
altogether to avoid that issue.

* Apply suggestions from code review

Co-authored-by: Felix Fontein <felix@fontein.de>

---------

Co-authored-by: Felix Fontein <felix@fontein.de>
(cherry picked from commit 21b16c1c77)

Co-authored-by: lyrandy <42095565+lyrandy@users.noreply.github.com>
2024-07-14 12:17:49 +02:00
patchback[bot]
2945509a55 [PR #8542/6cefde62 backport][stable-9] Improve Proxmox volume handling (#8622)
Improve Proxmox volume handling (#8542)

* proxmox: basic linting

using black via trunk.io

* proxmox: refactor mount handling (#8407)

- make mount creation idempotent: Mounts created using the special syntax "<storage>:<size>" no longer create a new volume each time
- add new keys for easier mount creation & management

* proxmox: add changelog fragment

* proxmox(fix): fix occasional syntax error

* Update changelogs/fragments/8542-fix-proxmox-volume-handling.yml

Link to pull request

Co-authored-by: Felix Fontein <felix@fontein.de>

* Update documentation

- Fix options defined as values
- Document mutual exclusivity
- Fix option hierarchy
- Add version_added tag

* Revert "proxmox: basic linting"

This reverts commit ca7214f60e.

* proxmox: Fix documentation

* Fix list identifier in documentation

* pass volume options as dict instead of list

* Update plugins/modules/proxmox.py

Update documentation wording

Co-authored-by: Felix Fontein <felix@fontein.de>

* Update plugins/modules/proxmox.py

Update documentation wording

Co-authored-by: Felix Fontein <felix@fontein.de>

* proxmox: ensure values of `disk_volume` and `mount_volumes.*` dicts are strings

* proxmox(fix): correct indentation

* Apply suggestions from code review: punctuation

Add suggested punctuation to documentation

Co-authored-by: Alexei Znamensky <103110+russoz@users.noreply.github.com>

* Update plugins/modules/proxmox.py: vol_string building

Accept suggested review change

Co-authored-by: Alexei Znamensky <103110+russoz@users.noreply.github.com>

* proxmox: Use better string check and conversion

---------

Co-authored-by: Felix Fontein <felix@fontein.de>
Co-authored-by: Alexei Znamensky <103110+russoz@users.noreply.github.com>
(cherry picked from commit 6cefde622c)

Co-authored-by: JL Euler <Lithimlin@users.noreply.github.com>
2024-07-14 12:17:41 +02:00
patchback[bot]
57be1e8be4 [PR #8556/9f3103e8 backport][stable-9] Add example to rpm_ostree_pkg (#8620)
Add example to rpm_ostree_pkg (#8556)

* Update rpm_ostree_pkg.py

expand examples list with 'until' example

* Apply suggestions from code review.

---------

Co-authored-by: Felix Fontein <felix@fontein.de>
(cherry picked from commit 9f3103e891)

Co-authored-by: Daskan <kevin81991@web.de>
2024-07-14 12:17:31 +02:00
patchback[bot]
086b4e4fb8 [PR #8595/8990f97b backport][stable-9] New Plugins #8594 (#8618)
New Plugins #8594 (#8595)

* Implement #8594

* Fix lint and BOTMETA entries.

* Fix BOTMETA

* Consolidate argument check, code simplification, and formatting. Remove test vars.

* Fix lint.

* retrigger checks

* Update plugins/plugin_utils/ansible_type.py

Co-authored-by: Felix Fontein <felix@fontein.de>

* Update plugins/test/ansible_type.py

Co-authored-by: Felix Fontein <felix@fontein.de>

---------

Co-authored-by: Felix Fontein <felix@fontein.de>
(cherry picked from commit 8990f97b45)

Co-authored-by: Vladimir Botka <vbotka@gmail.com>
2024-07-13 14:19:14 +02:00
patchback[bot]
92dcf1e0b2 [PR #8613/ca8ecb1d backport][stable-9] redfish_utils: fix language check (#8617)
redfish_utils: fix language check (#8613)

* redfish_utils: fix language check

* add fragment file

* typo

* improve words

* improve words based on suggestion

---------

Co-authored-by: Mike Koreneff <mkoreneff@hudson-trading.com>
(cherry picked from commit ca8ecb1df1)

Co-authored-by: Mike Koreneff <mkoreneff@users.noreply.github.com>
2024-07-12 23:23:50 +02:00
Felix Fontein
78a02b84f3 Reformat and re-order changelogs/changelog.yaml.
(cherry picked from commit e794fa74da)
2024-07-11 22:47:16 +02:00
patchback[bot]
7846cddab8 [PR #8607/8451fc36 backport][stable-9] Remove EOL'ed FreeBSD 13.2 from CI (#8610)
Remove EOL'ed FreeBSD 13.2 from CI (#8607)

Remove EOL'ed FreeBSD 13.2 from CI.

Apparently the packages are no longer available.

(cherry picked from commit 8451fc36ca)

Co-authored-by: Felix Fontein <felix@fontein.de>
2024-07-09 11:34:02 +02:00
patchback[bot]
b0af1e9c75 [PR #8444/feb1ecbf backport][stable-9] Fix to handle Redfish Gen2 Firmware upgrade (#8601)
Fix to handle Redfish Gen2 Firmware upgrade (#8444)

* Fix to handle Redfish Gen2 Firmware upgrade

* Fixed sanity checks and unit test cases

* Added change log gragment

* Updated change log fragment

* Updated review comments

---------

Co-authored-by: Adarsh Manjunath <adarsh.manjunath@wdc.com>
(cherry picked from commit feb1ecbfcd)

Co-authored-by: cmadarsh <53748644+cmadarsh@users.noreply.github.com>
2024-07-08 22:25:30 +02:00
patchback[bot]
f6349578c6 [PR #8592/b0797d32 backport][stable-9] CmdRunner guide (#8602)
CmdRunner guide (#8592)

* initial commit

* wip

* WIP

* progressing

* remove copied part

* progressing

* document as_func()

* complete docs about arg formatting

* add PythonRunner documentation

* fix markup

* improve markup

* multiple changes

- revamp the cmd_runner_fmt doc
- add CmdRunner instance and context parameters
- changed formatting of other blocks

* fix typo + reduce tables sizes

* improve text

* fixes and adjustments

* fix sanity

* fix version added

(cherry picked from commit b0797d329c)

Co-authored-by: Alexei Znamensky <103110+russoz@users.noreply.github.com>
2024-07-08 22:25:23 +02:00
patchback[bot]
e4287becb1 [PR #8596/45972c23 backport][stable-9] Bump fsfe/reuse-action from 3 to 4 (#8599)
Bump fsfe/reuse-action from 3 to 4 (#8596)

Bumps [fsfe/reuse-action](https://github.com/fsfe/reuse-action) from 3 to 4.
- [Release notes](https://github.com/fsfe/reuse-action/releases)
- [Commits](https://github.com/fsfe/reuse-action/compare/v3...v4)

---
updated-dependencies:
- dependency-name: fsfe/reuse-action
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
(cherry picked from commit 45972c23d4)

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-07-08 09:27:51 +02:00
Felix Fontein
005e8b151a Prepare 9.2.0 release. 2024-07-07 20:12:41 +02:00
patchback[bot]
cd2e55e2ab [PR #8580/a3989095 backport][stable-9] merge_variables: correct misleading short description (#8591)
merge_variables: correct misleading short description (#8580)

The short description makes it sound like the plugin would only support
matching a given suffix, while the actual description clarifies the
actual matching capabilities (suffix, prefix or regular expression).

Update the short description accordingly.

(cherry picked from commit a3989095af)

Co-authored-by: Elias Probst <mail@eliasprobst.eu>
2024-07-06 21:31:45 +02:00
patchback[bot]
1ff276ec34 [PR #8585/b2c77399 backport][stable-9] Add link to forum (#8588)
Add link to forum (#8585)

Add link to forum.

(cherry picked from commit b2c773996d)

Co-authored-by: Felix Fontein <felix@fontein.de>
2024-07-05 23:01:14 +02:00
patchback[bot]
c16c4a32d1 [PR #8517/5259caac backport][stable-9] cmd_runner - handle special value "auto" in param force_lang (#8581)
cmd_runner - handle special value "auto" in param force_lang (#8517)

* cmd_runner - handle special value "auto" in param force_lang

* add changelog frag

* update doc in puppet

* fix markup

(cherry picked from commit 5259caacae)

Co-authored-by: Alexei Znamensky <103110+russoz@users.noreply.github.com>
2024-07-05 08:54:04 +02:00
patchback[bot]
3a01ceb355 [PR #8482/caecb229 backport][stable-9] Feature. Add chapter 'Lists of dictionaries' to docsite (#8582)
Feature. Add chapter 'Lists of dictionaries' to docsite (#8482)

* Feature. Add chapter 'Lists of dictionaries'

* Fix copyright and licensing.

* Add maintainers for docsite chapter 'Lists of dictionaries'.

* Generate docs keep_keys and remove_keys

* Update integration tests of keep_keys and remove_keys
* Update docs helpers of keep_keys and remove_keys

* Fix copyright and licensing.

* Fix remove license from templates. Cleanup.

* Add docs helper replace_keys

* Update integration test filter_replace_keys
* Generate and update:
  filter_guide-abstract_informations-lists_of_dictionaries-replace_keys.rst

* Formatting improved.

* Fix results Jinja quotation marks.

* Update docs/docsite/helper/keep_keys/filter_guide-abstract_informations-lists_of_dictionaries-keep_keys.rst.j2

Co-authored-by: Felix Fontein <felix@fontein.de>

* Update docs/docsite/helper/keep_keys/filter_guide-abstract_informations-lists_of_dictionaries-keep_keys.rst.j2

Co-authored-by: Felix Fontein <felix@fontein.de>

* Fix references.

* Updated helpers.

* Fix licenses. Simplified templates.

* Fix licenses.

* Fix README.

---------

Co-authored-by: Felix Fontein <felix@fontein.de>
(cherry picked from commit caecb2297f)

Co-authored-by: Vladimir Botka <vbotka@gmail.com>
2024-07-05 08:53:55 +02:00
patchback[bot]
8ca91ab283 [PR #8567/01d8c7b7 backport][stable-9] Fix CI for CentOS 7 (#8570)
Fix CI for CentOS 7 (#8567)

Fix CI for CentOS 7.

(cherry picked from commit 01d8c7b769)

Co-authored-by: Felix Fontein <felix@fontein.de>
2024-07-01 14:13:22 +02:00
patchback[bot]
c88a40d3e3 [PR #8557/6e0142fe backport][stable-9] bitwarden: Fix KeyError in search_field (#8549) (#8563)
bitwarden: Fix KeyError in search_field (#8549) (#8557)

* bitwarden: Fix KeyError in search_field (#8549)

* Update changelogs/fragments/8557-fix-bug-with-bitwarden.yml

Co-authored-by: Felix Fontein <felix@fontein.de>

---------

Co-authored-by: Felix Fontein <felix@fontein.de>
(cherry picked from commit 6e0142fe3a)

Co-authored-by: Kai <github@sistason.de>
2024-06-27 10:19:35 +00:00
patchback[bot]
0dfd02c1ca [PR #8516/70c8042c backport][stable-9] proxmox_template: small refactor in get_template() (#8561)
proxmox_template: small refactor in get_template() (#8516)

* proxmox_template: small refactor in get_template()

* add changelog frag

* Update plugins/modules/proxmox_template.py

Co-authored-by: Felix Fontein <felix@fontein.de>

* rename function as per PR suggestion

---------

Co-authored-by: Felix Fontein <felix@fontein.de>
(cherry picked from commit 70c8042c99)

Co-authored-by: Alexei Znamensky <103110+russoz@users.noreply.github.com>
2024-06-27 12:19:24 +02:00
patchback[bot]
5d9072030e [PR #8545/10535458 backport][stable-9] keycloak_clientscope: ignore ids on diff check (#8554)
keycloak_clientscope: ignore ids on diff check (#8545)

* keycloak_clientscope: ignore ids on diff check

* keycloak_clientscope: add changelog fragment

* keycloak_clientscope: Include changelog fragment change suggestion

Co-authored-by: Felix Fontein <felix@fontein.de>

---------

Co-authored-by: Felix Fontein <felix@fontein.de>
(cherry picked from commit 1053545870)

Co-authored-by: Noah Lehmann <62204532+noahlehmann@users.noreply.github.com>
2024-06-22 11:05:25 +02:00
patchback[bot]
49765f103b [PR #8550/9e381614 backport][stable-9] CI: Replace FreeBSD 14.0 with 14.1; add 14.0 for stable-2.17 (#8552)
CI: Replace FreeBSD 14.0 with 14.1; add 14.0 for stable-2.17 (#8550)

* Replace FreeBSD 14.0 with 14.1; add 14.0 for stable-2.17.

* Skip tests that do not work.

(cherry picked from commit 9e38161400)

Co-authored-by: Felix Fontein <felix@fontein.de>
2024-06-22 10:48:45 +02:00
patchback[bot]
1782efb09e [PR #8541/60ba7cab backport][stable-9] add test case for cmd_runner_fmt.as_list() (#8547)
add test case for cmd_runner_fmt.as_list() (#8541)

(cherry picked from commit 60ba7cab93)

Co-authored-by: Alexei Znamensky <103110+russoz@users.noreply.github.com>
2024-06-20 21:14:01 +02:00
patchback[bot]
d8807e9b51 [PR #8533/0d50131d backport][stable-9] Enable Custom Cipher Selection for Redfish Modules (#8548)
Enable Custom Cipher Selection for Redfish Modules (#8533)

* Enable custom cipher selection for redfish modules

Signed-off-by: David Ehrman <dlehrman@liberty.edu>

* Add changelog fragment

Signed-off-by: David Ehrman <dlehrman@liberty.edu>

* Added version_added to the ciphers option in redfish modules

Signed-off-by: David Ehrman <dlehrman@liberty.edu>

---------

Signed-off-by: David Ehrman <dlehrman@liberty.edu>
(cherry picked from commit 0d50131d5e)

Co-authored-by: dlehrman <dlehrman@users.noreply.github.com>
2024-06-20 21:13:53 +02:00
patchback[bot]
d823d71442 [PR #8534/86f19cb5 backport][stable-9] Update CI for ansible-core devel (#8536)
* Update CI for ansible-core devel (#8534)

* Update CI for ansible-core devel.

* Uncomment platforms that cause problems.

(cherry picked from commit 86f19cb5d3)

* Finish updating CI (#8537)

* Uncomment TODO entries.

* Exclude some tests that fail or are known to fail.

* Also run extra VM tests on Ubuntu 24.04.

* Fix condition.

* More adjustments.

(cherry picked from commit ecb68aa5d2)

---------

Co-authored-by: Felix Fontein <felix@fontein.de>
2024-06-19 07:28:45 +02:00
Felix Fontein
46d2cddbde The next expected release will be 9.2.0. 2024-06-17 20:27:30 +02:00
Felix Fontein
069b785cb2 Release 9.1.0. 2024-06-17 19:37:55 +02:00
patchback[bot]
090d3f3709 [PR #8476/2612ceee backport][stable-9] Fix launchd check-mode to report changed correctly (#8529)
Fix launchd check-mode to report changed correctly (#8476)

* Fix launchd check-mode to report changed correctly

* Update changelog fragment.

---------

Co-authored-by: Strahinja Kustudic <strahinjak@nordeus.com>
Co-authored-by: Felix Fontein <felix@fontein.de>
(cherry picked from commit 2612ceee37)

Co-authored-by: Strahinja Kustudic <kustodian@gmail.com>
2024-06-17 07:55:49 +02:00
patchback[bot]
68a9b66966 [PR #8503/3314d5c8 backport][stable-9] proxmox_kvm: document that force requires archive (#8526)
proxmox_kvm: document that force requires archive (#8503)

* proxmox_kvm: document that force requires archive

As per `qm(1)`, the force option requires `archive`. Add this
information in the `proxmox_kvm` module so one will know they have to
define `archive` when using `force`.

* fix: parameter is an option O(archive)

Co-authored-by: Felix Fontein <felix@fontein.de>

---------

Co-authored-by: Felix Fontein <felix@fontein.de>
(cherry picked from commit 3314d5c8db)

Co-authored-by: Bruno Travouillon <devel@travouillon.fr>
2024-06-17 07:24:25 +02:00
patchback[bot]
f96c6476fe [PR #8428/b11da288 backport][stable-9] Keycloak set client authentification flows by name (#8524)
Keycloak set client authentification flows by name (#8428)

* first commit

* Add change logs

* fix sanity

* Sanity 2

* Test unset flows

* Update plugins/modules/keycloak_client.py

Co-authored-by: Alexei Znamensky <103110+russoz@users.noreply.github.com>

* Update plugins/modules/keycloak_client.py

Co-authored-by: Felix Fontein <felix@fontein.de>

* Update changelogs/fragments/8428-assign-auth-flow-by-name-keycloak-client.yaml

Co-authored-by: Felix Fontein <felix@fontein.de>

* Remove double traitement from "alias"

* Update plugins/modules/keycloak_client.py

Co-authored-by: Felix Fontein <felix@fontein.de>

* Update plugins/modules/keycloak_client.py

Co-authored-by: Felix Fontein <felix@fontein.de>

---------

Co-authored-by: Andre Desrosiers <andre.desrosiers@ssss.gouv.qc.ca>
Co-authored-by: Alexei Znamensky <103110+russoz@users.noreply.github.com>
Co-authored-by: Felix Fontein <felix@fontein.de>
(cherry picked from commit b11da288d2)

Co-authored-by: desand01 <desrosiers.a@hotmail.com>
2024-06-17 07:24:17 +02:00
patchback[bot]
fc0f677535 [PR #8514/df7fe19b backport][stable-9] pacman: do not fail if there is nothing to do (#8523)
pacman: do not fail if there is nothing to do (#8514)

Do not fail if there is nothing to do.

(cherry picked from commit df7fe19bbe)

Co-authored-by: Felix Fontein <felix@fontein.de>
2024-06-17 07:24:08 +02:00
patchback[bot]
9a986473bd [PR #8480/69b72e4a backport][stable-9] cargo module install from source in a given directory (#8527)
`cargo` module install from source in a given directory (#8480)

* Fixes installed version for git/local.

* Support latest determination with local source.

* Adds docs.

* Improves error message.

* Setup for tests.

* Updates copyright.

* Align closer to #7895.

* Adds changelog.

* Check directory exists.

* Stop using format strings.

* Corrects directory arg type in docs.

* Setup test repo dynamically.

* Adds tests.

* Adds version matching tests.

* Update changelog fragment to match PR ID.

* Updates copyright.

* Import new directory tests.

(cherry picked from commit 69b72e4a8e)

Co-authored-by: Colin Nolan <colin-nolan@users.noreply.github.com>
2024-06-17 07:24:00 +02:00
patchback[bot]
e9f0e49283 [PR #8496/fd2cd5f2 backport][stable-9] keycloak_clientscope: add normalizations for attributes and protocol_mappers (#8521)
keycloak_clientscope: add normalizations for attributes and protocol_mappers (#8496)

Signed-off-by: Eike Waldt <waldt@b1-systems.de>
(cherry picked from commit fd2cd5f28c)

Co-authored-by: Eike Waldt <waldt@b1-systems.de>
2024-06-16 22:24:45 +02:00
patchback[bot]
5eff31e760 [PR #8489/3716187f backport][stable-9] Fix OpenNebula inventory crash when NIC does not have IP (#8519)
Fix OpenNebula inventory crash when NIC does not have IP (#8489)

* Fix OpenNebula inventory crash when NIC does not have IP

Match IPv6 behaviour.

When a NIC does not have an IP:
  File "ansible/inventory/manager.py", line 292, in parse_source
    plugin.parse(self._inventory, self._loader, source, cache=cache)
  File "ansible-cm/plugins/inventory/opennebula.py", line 263, in parse
    self._populate()
  File "ansible-cm/plugins/inventory/opennebula.py", line 226, in _populate
    servers = self._retrieve_servers(filter_by_label)
              ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "ansible-cm/plugins/inventory/opennebula.py", line 210, in _retrieve_servers
    server['v4_first_ip'] = self._get_vm_ipv4(vm)
                            ^^^^^^^^^^^^^^^^^^^^^
  File "ansible-cm/plugins/inventory/opennebula.py", line 154, in _get_vm_ipv4
    return net['IP']

* Update to call to match IPv6 and add changelog fragment

* Update changelog fragment.

---------

Co-authored-by: Felix Fontein <felix@fontein.de>
(cherry picked from commit 3716187fc3)

Co-authored-by: Tom Paine <github@aioue.net>
2024-06-16 22:24:35 +02:00
Felix Fontein
39c58d5469 Prepare 9.1.0 release. 2024-06-16 21:12:20 +02:00
patchback[bot]
20d7be4f38 [PR #8512/ec4cf555 backport][stable-9] simplify cmd_runner_fmt.as_bool_not() (#8515)
simplify cmd_runner_fmt.as_bool_not() (#8512)

* simplify cmd_runner_fmt.as_bool_not()

* add changelog frag

(cherry picked from commit ec4cf55566)

Co-authored-by: Alexei Znamensky <103110+russoz@users.noreply.github.com>
2024-06-16 10:10:55 +02:00
patchback[bot]
2d26fba0b9 [PR #7989/03966624 backport][stable-9] Consul implement agent service and check (#8513)
Consul implement agent service and check (#7989)

* Implement agent service and check (#7987)

* implement update of service and check

* update tests
update documentation

* update documentation

* add consul_agent_check/service to action_groups

check if unique_identifier of name is in params to get object

add suggested improvements

* update sanity

* fix sanity issues
update documentation

* fix naming

* fix naming

check if response_data has data

* fix sanity extra-docs

* add as ignore maintainer in BOTMETA.yml
update version_added to 8.4

* fix sanity

* add to maintainers

* Update plugins/modules/consul_agent_check.py

Co-authored-by: Felix Fontein <felix@fontein.de>

* Update plugins/modules/consul_agent_check.py

Co-authored-by: Felix Fontein <felix@fontein.de>

* Update plugins/modules/consul_agent_check.py

Co-authored-by: Felix Fontein <felix@fontein.de>

* update version_added

* if create and update return no object as result we read the object again

* get_first_appearing_identifier check the params for the given identifier and return it to simplify id vs name

* add unique_identifiers as a new property and a method to decide which identifier should be used

* fix sanity

* add self to team consul
remove params with no values
add operational_attributes that inherited classes can set them
get identifier value from object

* fix sanity
fix test

* remove the possibility to add checks with consul_agent_check.
check if service has changed

* remove tests for idempotency check because for checks it is not possible

* remove unique_identifier from consul.py
change unique_identifier to unique_identifiers

* get id from params

* Revert "remove unique_identifier from consul.py"

This reverts commit a4f0d0220dd23e95871914b152c25ff352097a2c.

* update version to 8.5

* Revert "Revert "remove unique_identifier from consul.py""

This reverts commit d2c35cf04c8aaf5f0175d772f862a796e22e35d4.

* update description
update test

* fix sanity tests

* fix sanity tests

* update documentation for agent_check

* fix line length

* add documentation

* fix sanity

* simplified check for Tcp

Co-authored-by: Alexei Znamensky <103110+russoz@users.noreply.github.com>

* check duration with regex

* fix

* update documentation

---------

Co-authored-by: Felix Fontein <felix@fontein.de>
Co-authored-by: Alexei Znamensky <103110+russoz@users.noreply.github.com>
(cherry picked from commit 03966624ba)

Co-authored-by: Ilgmi <michael.ilg@mailbox.org>
2024-06-16 10:10:45 +02:00
patchback[bot]
d6168a196b [PR #8446/1d615419 backport][stable-9] Feature filter replace_keys (#8507)
Feature filter replace_keys (#8446)

* Add filter replace_keys.

* Update examples and integration tests.

* Fix examples and copyright.

* Update documentation, examples and integration tests.

* Implement #8445. Add filter replace_keys

* Fix documentation formatting.

* Fix documentation.

* Fix type(target). Formatting improved.

* Instead of a dictionary, _keys_filter_target_dict returns a list

* No target testing in _keys_filter_params
* Interface changed _keys_filter_params(data, matching_parameter)
* If there are items with equal C(before) the B(first) one will be used.

* Update remove_keys. Interface changed _keys_filter_params(data, matching_parameter)

* The target can't be empty also in _keys_filter_target_dict

* Update plugins/filter/replace_keys.py

Co-authored-by: Felix Fontein <felix@fontein.de>

* Update plugins/filter/replace_keys.py

Co-authored-by: Felix Fontein <felix@fontein.de>

* Update plugins/filter/replace_keys.py

Co-authored-by: Felix Fontein <felix@fontein.de>

* Test attributes before and after are strings in the iteration of target.

* Update plugins/filter/replace_keys.py

Co-authored-by: Felix Fontein <felix@fontein.de>

---------

Co-authored-by: Felix Fontein <felix@fontein.de>
(cherry picked from commit 1d61541951)

Co-authored-by: Vladimir Botka <vbotka@gmail.com>
2024-06-15 12:00:09 +02:00
patchback[bot]
02de81c39e [PR #8509/d95f4d68 backport][stable-9] fix version vardict was introduced (#8511)
fix version vardict was introduced (#8509)

(cherry picked from commit d95f4d68a3)

Co-authored-by: Alexei Znamensky <103110+russoz@users.noreply.github.com>
2024-06-15 11:52:12 +02:00
patchback[bot]
4096b9fa5a [PR #8479/71f96748 backport][stable-9] cmd_runner mod util: improvements (#8504)
cmd_runner mod util: improvements (#8479)

* deprecate ignore_none in context

* add changelog frag

* raise deprecation notice when passing ignore_value_none to context

* simplify deprecation logic

(cherry picked from commit 71f9674835)

Co-authored-by: Alexei Znamensky <103110+russoz@users.noreply.github.com>
2024-06-14 07:55:02 +02:00
patchback[bot]
fe3a3a7638 [PR #8471/2574cb0d backport][stable-9] feat: proxmox_vm_info - add network information for guests (#8505)
feat: proxmox_vm_info - add network information for guests (#8471)

* feat: add network information for guests

- Uses agent information for qemu-vms
- Uses network information for lxc container

* chore: add changelog fragment

* fix: change default, add doc

* chore: clarify doc

* chore: add optional ,

* chore: fix pep8 indentation warning

* Update plugins/modules/proxmox_vm_info.py

Co-authored-by: Felix Fontein <felix@fontein.de>

* Update plugins/modules/proxmox_vm_info.py

Co-authored-by: Felix Fontein <felix@fontein.de>

---------

Co-authored-by: Jan Wenzel <jan.wenzel@gonicus.de>
Co-authored-by: Felix Fontein <felix@fontein.de>
(cherry picked from commit 2574cb0dea)

Co-authored-by: Jan Wenzel <jan@coffeelover.de>
2024-06-14 07:54:53 +02:00
patchback[bot]
7cac741e77 [PR #8500/49e2a863 backport][stable-9] Add Python 3.13 to CI (#8502)
Add Python 3.13 to CI (#8500)

Add Python 3.13 to CI.

(cherry picked from commit 49e2a8633e)

Co-authored-by: Felix Fontein <felix@fontein.de>
2024-06-14 07:12:20 +02:00
patchback[bot]
f84ebed63f [PR #8497/f0940d82 backport][stable-9] homectl, udm_user: guard crypt imports (#8499)
homectl, udm_user: guard crypt imports (#8497)

Guard crypt import.

(cherry picked from commit f0940d82dc)

Co-authored-by: Felix Fontein <felix@fontein.de>
2024-06-13 22:01:33 +02:00
patchback[bot]
f905a1bc94 [PR #8475/8f60f3ae backport][stable-9] Update docs lists_mergeby (#8495)
Update docs lists_mergeby (#8475)

* Fix #8474. Complete examples and documentation of lists_mergeby

* Fix docs syntax O(_input)

* Update docs.

* Update plugins/filter/lists_mergeby.py

Co-authored-by: Felix Fontein <felix@fontein.de>

* Update plugins/filter/lists_mergeby.py

Co-authored-by: Felix Fontein <felix@fontein.de>

* Update plugins/filter/lists_mergeby.py

Co-authored-by: Felix Fontein <felix@fontein.de>

* Update plugins/filter/lists_mergeby.py

Co-authored-by: Felix Fontein <felix@fontein.de>

---------

Co-authored-by: Felix Fontein <felix@fontein.de>
(cherry picked from commit 8f60f3aef9)

Co-authored-by: Vladimir Botka <vbotka@gmail.com>
2024-06-13 07:48:02 +02:00
patchback[bot]
b0470f2e59 [PR #8464/800bc011 backport][stable-9] feat(redis_info): add option to fetch cluster info (#8493)
feat(redis_info): add option to fetch cluster info (#8464)

* feat(redis_info): add option to fetch cluster info

* add changelog fragment

* update description

Co-authored-by: Felix Fontein <felix@fontein.de>

* Apply suggestions from code review

Co-authored-by: Felix Fontein <felix@fontein.de>

---------

Co-authored-by: Felix Fontein <felix@fontein.de>
(cherry picked from commit 800bc01112)

Co-authored-by: joris <5111464+tyxieblub@users.noreply.github.com>
2024-06-13 07:19:15 +02:00
patchback[bot]
42175e38b2 [PR #8477/ac3c0435 backport][stable-9] Update docsite chapter "Merging lists of dictionaries" (#8492)
Update docsite chapter "Merging lists of dictionaries" (#8477)

* Update docs 'Merging lists of dictionaries'

* Adding links to module and plugin options in
  docs/docsite/helper/lists_mergeby
* Add subsections and improve formatting.
* Add example-009 'Merge single list'

* Fix licenses.

* Fix variables.

* Update docs/docsite/helper/lists_mergeby/filter_guide_abstract_informations_merging_lists_of_dictionaries.rst.j2

Co-authored-by: Felix Fontein <felix@fontein.de>

* Update docs/docsite/rst/filter_guide_abstract_informations_merging_lists_of_dictionaries.rst

Co-authored-by: Felix Fontein <felix@fontein.de>

---------

Co-authored-by: Felix Fontein <felix@fontein.de>
(cherry picked from commit ac3c04357c)

Co-authored-by: Vladimir Botka <vbotka@gmail.com>
2024-06-13 07:19:02 +02:00
patchback[bot]
8e79844b75 [PR #8454/c31499a4 backport][stable-9] django_check: new module (#8490)
django_check: new module (#8454)

* django_check: new module

* sanity fix

* working version

* remove unused import

* add note about the module output

* add note on module failing when rc!=0

(cherry picked from commit c31499a411)

Co-authored-by: Alexei Znamensky <103110+russoz@users.noreply.github.com>
2024-06-13 07:18:54 +02:00
patchback[bot]
1338db358a [PR #8483/1ae6c825 backport][stable-9] CI: Bump Azure test container to 6.0.0 (#8486)
CI: Bump Azure test container to 6.0.0 (#8483)

Bump Azure test container to 6.0.0.

(cherry picked from commit 1ae6c82558)

Co-authored-by: Felix Fontein <felix@fontein.de>
2024-06-10 21:21:34 +02:00
patchback[bot]
06c4439a1c [PR #8441/d2d7deb4 backport][stable-9] #8440 Allow for API Port to be specified when using proxmox_kvm (#8478)
#8440 Allow for API Port to be specified when using proxmox_kvm (#8441)

* added api_port

* added changelog fragments for #8440

* api_port minor changes

- Added documentation on api_port
- Fixed multiple spaces after operator
- Switched from str to int

* Update changelogs/fragments/8440-allow-api-port-specification.yaml

Co-authored-by: Felix Fontein <felix@fontein.de>

* Update changelogs/fragments/8440-allow-api-port-specification.yaml

Co-authored-by: Felix Fontein <felix@fontein.de>

* Update plugins/doc_fragments/proxmox.py

Co-authored-by: Felix Fontein <felix@fontein.de>

* Update plugins/doc_fragments/proxmox.py

Co-authored-by: Felix Fontein <felix@fontein.de>

---------

Co-authored-by: Felix Fontein <felix@fontein.de>
(cherry picked from commit d2d7deb4ec)

Co-authored-by: Thomas Gouverneur <thomas@espix.net>
2024-06-08 14:59:27 +02:00
patchback[bot]
16d5d5fc57 [PR #8443/06f13e79 backport][stable-9] Feature filter remove_keys (#8473)
Feature filter remove_keys (#8443)

* Add filter remove_keys.

* Add filter remove_keys integration test, fragment, and maintainer.

* Update with plugins/plugin_utils/keys_filter.py

* Update according PR #8456

* Update maintainers.

* Fix typo in return doc.

* Remove local keys_filter.py. Then rebase.

* Add local keys_filter.py

* Update plugins/filter/remove_keys.py

Co-authored-by: Felix Fontein <felix@fontein.de>

* Update plugins/filter/remove_keys.py

Co-authored-by: Felix Fontein <felix@fontein.de>

---------

Co-authored-by: Felix Fontein <felix@fontein.de>
(cherry picked from commit 06f13e79b1)

Co-authored-by: Vladimir Botka <vbotka@gmail.com>
2024-06-07 07:14:20 +02:00
patchback[bot]
71af3226f3 [PR #8460/a0ad2d58 backport][stable-9] add docs for the vardict module utils (#8467)
add docs for the vardict module utils (#8460)

* add docs for the vardict module utils

* fix var name

* add entry to BOTMETA

* rollback adjustment in deps guide

* Update docs/docsite/rst/guide_vardict.rst

Co-authored-by: Felix Fontein <felix@fontein.de>

* adjustments

* Update docs/docsite/rst/guide_vardict.rst

Co-authored-by: Felix Fontein <felix@fontein.de>

---------

Co-authored-by: Felix Fontein <felix@fontein.de>
(cherry picked from commit a0ad2d5849)

Co-authored-by: Alexei Znamensky <103110+russoz@users.noreply.github.com>
2024-06-06 13:19:10 +02:00
patchback[bot]
b3037a46be [PR #8452/2a3819a6 backport][stable-9] git_config: fix state=absent if value is present (#8466)
git_config: fix state=absent if value is present (#8452)

* Fix state=absent if value is present.

* Update changelog fragment.

(cherry picked from commit 2a3819a696)

Co-authored-by: Felix Fontein <felix@fontein.de>
2024-06-06 13:19:02 +02:00
patchback[bot]
f7df19adbd [PR #8404/1c4ab7fa backport][stable-9] Add support for SSHFP records to ipa_dnsrecord module (#8468)
Add support for SSHFP records to ipa_dnsrecord module (#8404)

* Add support for SSHFP records to ipa_dnsrecord module

* Create 8404-ipa_dnsrecord_sshfp.yml

* Apply suggestions from code review

Co-authored-by: Felix Fontein <felix@fontein.de>

* Fix a typo in the example for ipa_dnsrecord with type SSHFP

* Update plugins/modules/ipa_dnsrecord.py

Co-authored-by: Felix Fontein <felix@fontein.de>

---------

Co-authored-by: Felix Fontein <felix@fontein.de>
(cherry picked from commit 1c4ab7fafc)

Co-authored-by: Daniel <mail@h3po.de>
2024-06-06 13:18:50 +02:00
patchback[bot]
3bca21aa1b [PR #8456/6f8f12f7 backport][stable-9] Feature filter keep_keys (#8462)
Feature filter keep_keys (#8456)

* Add filter keep_keys. Implement feature request #8438

* Fix comment indentation.

* Fix regex reference.

* Fix indentation.

* Fix isinstance list.

* Update plugins/plugin_utils/keys_filter.py

Co-authored-by: Felix Fontein <felix@fontein.de>

* Update plugins/plugin_utils/keys_filter.py

Co-authored-by: Felix Fontein <felix@fontein.de>

* Update plugins/plugin_utils/keys_filter.py

Co-authored-by: Felix Fontein <felix@fontein.de>

* Update plugins/plugin_utils/keys_filter.py

Co-authored-by: Felix Fontein <felix@fontein.de>

* Update plugins/filter/keep_keys.py

Co-authored-by: Felix Fontein <felix@fontein.de>

* Update documentation, examples, and integration tests.

* _keys_filter_target_str returns tuple of unique target strings if
target is list. Update documentation, function comments, and error
messages.

* Sort maintainers.

* Update plugins/filter/keep_keys.py

Co-authored-by: Felix Fontein <felix@fontein.de>

* Update examples with explicit collection.

---------

Co-authored-by: Felix Fontein <felix@fontein.de>
(cherry picked from commit 6f8f12f762)

Co-authored-by: Vladimir Botka <vbotka@gmail.com>
2024-06-04 07:45:13 +02:00
patchback[bot]
1bb3d41e15 [PR #8453/0129346e backport][stable-9] git_config: deprecate reading values (#8463)
git_config: deprecate reading values (#8453)

Deprecate reading values.

(cherry picked from commit 0129346eda)

Co-authored-by: Felix Fontein <felix@fontein.de>
2024-06-04 06:35:46 +02:00
patchback[bot]
f214f206c3 [PR #8434/961767e2 backport][stable-9] Redfish: Add options to check the availability of the service (#8457)
Redfish: Add options to check the availability of the service (#8434)

* Redfish: Add options to check the availability of the service

Signed-off-by: Mike Raineri <michael.raineri@dell.com>

* Updates based on review feedback

Signed-off-by: Mike Raineri <michael.raineri@dell.com>

* Updated comment to reflect changed behavior

Signed-off-by: Mike Raineri <michael.raineri@dell.com>

* Added changelog fragments

Signed-off-by: Mike Raineri <michael.raineri@dell.com>

* Update changelogs/fragments/8051-Redfish-Wait-For-Service.yml

Co-authored-by: Felix Fontein <felix@fontein.de>

* Update plugins/modules/redfish_command.py

Co-authored-by: Felix Fontein <felix@fontein.de>

* Update plugins/modules/redfish_command.py

Co-authored-by: Felix Fontein <felix@fontein.de>

* Update plugins/modules/redfish_command.py

Co-authored-by: Felix Fontein <felix@fontein.de>

* Update plugins/modules/redfish_command.py

Co-authored-by: Felix Fontein <felix@fontein.de>

---------

Signed-off-by: Mike Raineri <michael.raineri@dell.com>
Co-authored-by: Felix Fontein <felix@fontein.de>
(cherry picked from commit 961767e2dd)

Co-authored-by: Mike Raineri <mraineri@gmail.com>
2024-06-03 07:15:58 +02:00
patchback[bot]
9b8011d692 [PR #8430/5041ebe5 backport][stable-9] fix(opentelemetry): remove request from the logs (#8458)
fix(opentelemetry): remove request from the logs (#8430)

* fix(opentelemetry): remove request from the logs

* add changelog

* filter by task

* add new bugfix

* rename

* support legacy and shortcat ansible tasks

* Update plugins/callback/opentelemetry.py

Co-authored-by: Felix Fontein <felix@fontein.de>

---------

Co-authored-by: Felix Fontein <felix@fontein.de>
(cherry picked from commit 5041ebe5b2)

Co-authored-by: Victor Martinez <victormartinezrubio@gmail.com>
2024-06-03 07:15:49 +02:00
patchback[bot]
f227038f38 [PR #8431/d46e12e2 backport][stable-9] ansible_galaxy_install: add upgrade feature (#8451)
ansible_galaxy_install: add upgrade feature (#8431)

* add upgrade feature

* add changelog frag

* Update plugins/modules/ansible_galaxy_install.py

* Update plugins/modules/ansible_galaxy_install.py

(cherry picked from commit d46e12e280)

Co-authored-by: Alexei Znamensky <103110+russoz@users.noreply.github.com>
2024-06-02 00:25:32 +02:00
patchback[bot]
86a2996814 [PR #8417/5a5188a4 backport][stable-9] deps module_utils: add docs (#8450)
deps module_utils: add docs  (#8417)

* add docs for the deps module utils

* wordsmithing

* fix reference and filename

* add entries to BOTMETA.yml

* Update docs/docsite/rst/moddev_guide_deps.rst

Co-authored-by: Felix Fontein <felix@fontein.de>

* adjust docs organisation

* adjust docs organisation II

* PR adjustments

---------

Co-authored-by: Felix Fontein <felix@fontein.de>
(cherry picked from commit 5a5188a453)

Co-authored-by: Alexei Znamensky <103110+russoz@users.noreply.github.com>
2024-06-02 00:25:24 +02:00
patchback[bot]
eb154003cf [PR #8412/54df0c9b backport][stable-9] django_createcachetable: new module (#8449)
django_createcachetable: new module (#8412)

* django_createcachetabe: new module

* add --noinput arg to testcase

* add module to BOTMETA

* rename module class name

* fix examples documentation

* remove unused config

* adjust version_added

(cherry picked from commit 54df0c9b3a)

Co-authored-by: Alexei Znamensky <103110+russoz@users.noreply.github.com>
2024-06-01 22:54:20 +02:00
patchback[bot]
212871fcaf [PR #8415/7d72300c backport][stable-9] add cmd_runner_fmt.stack decorator (#8448)
add cmd_runner_fmt.stack decorator (#8415)

* add cmd_runner_fmt.stack decorator

* fix sanity

* fix typo

* add changelog frag

(cherry picked from commit 7d72300c36)

Co-authored-by: Alexei Znamensky <103110+russoz@users.noreply.github.com>
2024-06-01 22:54:14 +02:00
patchback[bot]
1795a67b8e [PR #8402/e690317e backport][stable-9] Add partial diff support, not in check mode to openbsd_pkg (#8447)
Add partial diff support, not in check mode to openbsd_pkg (#8402)

* Add partial diff support, not in check mode

* Add changelog fragment

* Fix PEP8. Want to run Black against this so badly.

* Update changelogs/fragments/8402-add-diif-mode-openbsd-pkg.yml

Co-authored-by: Felix Fontein <felix@fontein.de>

* Update plugins/modules/openbsd_pkg.py

Co-authored-by: Felix Fontein <felix@fontein.de>

* Update plugins/modules/openbsd_pkg.py

Co-authored-by: Felix Fontein <felix@fontein.de>

* Remove unneeded comment

---------

Co-authored-by: Allen Smith <allsmith@allsmith.users.ipa.redhat.com>
Co-authored-by: Felix Fontein <felix@fontein.de>
(cherry picked from commit e690317e3a)

Co-authored-by: Allen Smith <lazlor@lotaris.org>
2024-06-01 22:09:42 +02:00
Felix Fontein
a71c0af9cc The next expected release is 9.1.0. 2024-05-27 20:52:56 +02:00
Felix Fontein
569cde6c3e Release 9.0.1. 2024-05-27 20:24:06 +02:00
patchback[bot]
f0db1d1f6b [PR #8406/43cb5a0d backport][stable-9] Fix the homebrew module failing because of warnings (#8425)
Fix the homebrew module failing because of warnings (#8406)

Instead of checking if there is an error message, which can also be a
warning, we now check the return code.

This commit fixes #8229 #7044

Co-authored-by: Strahinja Kustudic <strahinjak@nordeus.com>
(cherry picked from commit 43cb5a0d54)

Co-authored-by: Strahinja Kustudic <kustodian@gmail.com>
2024-05-26 21:17:46 +02:00
patchback[bot]
5a36e84b86 [PR #8403/572caeaa backport][stable-9] keycloak_client: avoid TypeError if result["attributes"] is a list (#8427)
keycloak_client: avoid TypeError if `result["attributes"]` is a list (#8403)

* fix(keycloak_client): avoid TypeError if attributes is a list

As sanitize_cr might be executed after normalise_cr, result['attributes'] can be of type list and we
run into:

TypeError: list indices must be integers or slices, not str

* Update changelog fragment.

---------

Co-authored-by: Felix Fontein <felix@fontein.de>
(cherry picked from commit 572caeaa39)

Co-authored-by: Thomas Bach <63091663+thomasbach-dev@users.noreply.github.com>
2024-05-26 21:17:37 +02:00
Felix Fontein
a74c6db77f Prepare 9.0.1 release. 2024-05-26 16:40:36 +02:00
patchback[bot]
9a14980ca7 [PR #8411/ec886203 backport][stable-9] multiple modules: use new vardict in module (#8419)
multiple modules: use new vardict in module (#8411)

* use new vardict in module

* add changelog frag

* Update changelogs/fragments/8411-locale-gen-vardict.yml

Co-authored-by: Felix Fontein <felix@fontein.de>

* set use_old_vardict to false in snap

* set use_old_vardict to false in cpanm

* set use_old_vardict to false in django mod helper

* set use_old_vardict to false in gconftool2_info

* set use_old_vardict to false in kernel_blacklist

* set use_old_vardict to false in mksysb

* set use_old_vardict to false in pipx_info

* set use_old_vardict to false in snap_alias

* update chglog frag

* fix typo

---------

Co-authored-by: Felix Fontein <felix@fontein.de>
(cherry picked from commit ec886203fc)

Co-authored-by: Alexei Znamensky <103110+russoz@users.noreply.github.com>
2024-05-26 14:13:46 +02:00
patchback[bot]
8c9effce1f [PR #8413/e7ee90a9 backport][stable-9] ansible_galaxy_install: minor refactor (#8420)
ansible_galaxy_install: minor refactor (#8413)

* minor refactor

* add changelog frag

* remove commented code

* set use_old_vardict to false

(cherry picked from commit e7ee90a937)

Co-authored-by: Alexei Znamensky <103110+russoz@users.noreply.github.com>
2024-05-26 14:08:15 +02:00
patchback[bot]
51ec3594dd [PR #8309/d96b2642 backport][stable-9] Update lxd_container.py documentation. (#8422)
Update lxd_container.py documentation. (#8309)

remove dead link from debian example

(cherry picked from commit d96b2642bc)

Co-authored-by: Herschdorfer <herschdorfer@gmail.com>
2024-05-26 14:08:04 +02:00
patchback[bot]
802f8ea224 [PR #8387/da2c87ce backport][stable-9] fix test helper handling of rc (#8414)
fix test helper handling of rc (#8387)

* fix test helper handling of rc

* fix side_effect logic for rc != 0

* fix side_effect func + sanity tests

* fix ignore files

* fix code

* revamp the generator for run_command calls returns in testcase

* remove unused import

* Update tests/sanity/ignore-2.18.txt

Co-authored-by: Felix Fontein <felix@fontein.de>

* Update tests/sanity/ignore-2.17.txt

Co-authored-by: Felix Fontein <felix@fontein.de>

---------

Co-authored-by: Felix Fontein <felix@fontein.de>
(cherry picked from commit da2c87ce0d)

Co-authored-by: Alexei Znamensky <103110+russoz@users.noreply.github.com>
2024-05-24 22:11:42 +02:00
patchback[bot]
23af148021 [PR #8396/4792e214 backport][stable-9] docs: add seealso and notes for yaml callback plugin (#8397)
docs: add seealso and notes for yaml callback plugin (#8396)

* docs: add seealso and notes for yaml callback plugin

* docs: correct links to parameters

Co-authored-by: Felix Fontein <felix@fontein.de>

* docs: shorten the long lines

---------

Co-authored-by: Felix Fontein <felix@fontein.de>
(cherry picked from commit 4792e21416)

Co-authored-by: kurokobo <kuro664@gmail.com>
2024-05-20 16:18:26 +02:00
Felix Fontein
1a2c2d0a64 The next expected release will be 9.0.1. 2024-05-20 13:14:06 +02:00
Felix Fontein
80243f8180 Release 9.0.0. 2024-05-20 12:41:10 +02:00
Felix Fontein
13b5c4092a Update CI cron schedules.
(cherry picked from commit 95e509753e)
2024-05-20 12:36:14 +02:00
961 changed files with 37893 additions and 50738 deletions

View File

@@ -1,436 +0,0 @@
---
# Copyright (c) Ansible Project
# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
# SPDX-License-Identifier: GPL-3.0-or-later
trigger:
batch: true
branches:
include:
- main
- stable-*
pr:
autoCancel: true
branches:
include:
- main
- stable-*
schedules:
- cron: 0 8 * * *
displayName: Nightly (main)
always: true
branches:
include:
- main
- cron: 0 10 * * *
displayName: Nightly (active stable branches)
always: true
branches:
include:
- stable-10
- stable-9
- cron: 0 11 * * 0
displayName: Weekly (old stable branches)
always: true
branches:
include:
- stable-8
variables:
- name: checkoutPath
value: ansible_collections/community/general
- name: coverageBranches
value: main
- name: entryPoint
value: tests/utils/shippable/shippable.sh
- name: fetchDepth
value: 0
resources:
containers:
- container: default
image: quay.io/ansible/azure-pipelines-test-container:6.0.0
pool: Standard
stages:
### Sanity
- stage: Sanity_devel
displayName: Sanity devel
dependsOn: []
jobs:
- template: templates/matrix.yml
parameters:
nameFormat: Test {0}
testFormat: devel/sanity/{0}
targets:
- test: 1
- test: 2
- test: 3
- test: 4
- test: extra
- stage: Sanity_2_18
displayName: Sanity 2.18
dependsOn: []
jobs:
- template: templates/matrix.yml
parameters:
nameFormat: Test {0}
testFormat: 2.18/sanity/{0}
targets:
- test: 1
- test: 2
- test: 3
- test: 4
- stage: Sanity_2_17
displayName: Sanity 2.17
dependsOn: []
jobs:
- template: templates/matrix.yml
parameters:
nameFormat: Test {0}
testFormat: 2.17/sanity/{0}
targets:
- test: 1
- test: 2
- test: 3
- test: 4
- stage: Sanity_2_16
displayName: Sanity 2.16
dependsOn: []
jobs:
- template: templates/matrix.yml
parameters:
nameFormat: Test {0}
testFormat: 2.16/sanity/{0}
targets:
- test: 1
- test: 2
- test: 3
- test: 4
### Units
- stage: Units_devel
displayName: Units devel
dependsOn: []
jobs:
- template: templates/matrix.yml
parameters:
nameFormat: Python {0}
testFormat: devel/units/{0}/1
targets:
- test: 3.8
- test: 3.9
- test: '3.10'
- test: '3.11'
- test: '3.12'
- test: '3.13'
- stage: Units_2_18
displayName: Units 2.18
dependsOn: []
jobs:
- template: templates/matrix.yml
parameters:
nameFormat: Python {0}
testFormat: 2.18/units/{0}/1
targets:
- test: 3.8
- test: "3.13"
- stage: Units_2_17
displayName: Units 2.17
dependsOn: []
jobs:
- template: templates/matrix.yml
parameters:
nameFormat: Python {0}
testFormat: 2.17/units/{0}/1
targets:
- test: 3.7
- test: "3.12"
- stage: Units_2_16
displayName: Units 2.16
dependsOn: []
jobs:
- template: templates/matrix.yml
parameters:
nameFormat: Python {0}
testFormat: 2.16/units/{0}/1
targets:
- test: 2.7
- test: 3.6
- test: "3.11"
## Remote
- stage: Remote_devel_extra_vms
displayName: Remote devel extra VMs
dependsOn: []
jobs:
- template: templates/matrix.yml
parameters:
testFormat: devel/{0}
targets:
- name: Alpine 3.21
test: alpine/3.21
# - name: Fedora 41
# test: fedora/41
- name: Ubuntu 22.04
test: ubuntu/22.04
- name: Ubuntu 24.04
test: ubuntu/24.04
groups:
- vm
- stage: Remote_devel
displayName: Remote devel
dependsOn: []
jobs:
- template: templates/matrix.yml
parameters:
testFormat: devel/{0}
targets:
- name: macOS 15.3
test: macos/15.3
- name: RHEL 9.5
test: rhel/9.5
- name: FreeBSD 14.2
test: freebsd/14.2
- name: FreeBSD 13.5
test: freebsd/13.5
groups:
- 1
- 2
- 3
- stage: Remote_2_18
displayName: Remote 2.18
dependsOn: []
jobs:
- template: templates/matrix.yml
parameters:
testFormat: 2.18/{0}
targets:
- name: macOS 14.3
test: macos/14.3
- name: RHEL 9.4
test: rhel/9.4
- name: FreeBSD 14.1
test: freebsd/14.1
groups:
- 1
- 2
- 3
- stage: Remote_2_17
displayName: Remote 2.17
dependsOn: []
jobs:
- template: templates/matrix.yml
parameters:
testFormat: 2.17/{0}
targets:
- name: FreeBSD 13.3
test: freebsd/13.3
- name: RHEL 9.3
test: rhel/9.3
- name: FreeBSD 14.0
test: freebsd/14.0
groups:
- 1
- 2
- 3
- stage: Remote_2_16
displayName: Remote 2.16
dependsOn: []
jobs:
- template: templates/matrix.yml
parameters:
testFormat: 2.16/{0}
targets:
- name: macOS 13.2
test: macos/13.2
- name: RHEL 9.2
test: rhel/9.2
- name: RHEL 8.8
test: rhel/8.8
- name: RHEL 7.9
test: rhel/7.9
# - name: FreeBSD 13.2
# test: freebsd/13.2
groups:
- 1
- 2
- 3
### Docker
- stage: Docker_devel
displayName: Docker devel
dependsOn: []
jobs:
- template: templates/matrix.yml
parameters:
testFormat: devel/linux/{0}
targets:
- name: Fedora 41
test: fedora41
- name: Alpine 3.21
test: alpine321
- name: Ubuntu 22.04
test: ubuntu2204
- name: Ubuntu 24.04
test: ubuntu2404
groups:
- 1
- 2
- 3
- stage: Docker_2_18
displayName: Docker 2.18
dependsOn: []
jobs:
- template: templates/matrix.yml
parameters:
testFormat: 2.18/linux/{0}
targets:
- name: Fedora 40
test: fedora40
- name: Alpine 3.20
test: alpine320
- name: Ubuntu 24.04
test: ubuntu2404
groups:
- 1
- 2
- 3
- stage: Docker_2_17
displayName: Docker 2.17
dependsOn: []
jobs:
- template: templates/matrix.yml
parameters:
testFormat: 2.17/linux/{0}
targets:
- name: Fedora 39
test: fedora39
- name: Alpine 3.19
test: alpine319
- name: Ubuntu 20.04
test: ubuntu2004
groups:
- 1
- 2
- 3
- stage: Docker_2_16
displayName: Docker 2.16
dependsOn: []
jobs:
- template: templates/matrix.yml
parameters:
testFormat: 2.16/linux/{0}
targets:
- name: Fedora 38
test: fedora38
- name: openSUSE 15
test: opensuse15
- name: Alpine 3
test: alpine3
- name: CentOS 7
test: centos7
groups:
- 1
- 2
- 3
### Community Docker
- stage: Docker_community_devel
displayName: Docker (community images) devel
dependsOn: []
jobs:
- template: templates/matrix.yml
parameters:
testFormat: devel/linux-community/{0}
targets:
- name: Debian Bullseye
test: debian-bullseye/3.9
- name: Debian Bookworm
test: debian-bookworm/3.11
- name: ArchLinux
test: archlinux/3.13
groups:
- 1
- 2
- 3
### Generic
# Right now all generic tests are disabled. Uncomment when at least one of them is re-enabled.
# - stage: Generic_devel
# displayName: Generic devel
# dependsOn: []
# jobs:
# - template: templates/matrix.yml
# parameters:
# nameFormat: Python {0}
# testFormat: devel/generic/{0}/1
# targets:
# - test: '3.8'
# - test: '3.11'
# - test: '3.13'
# - stage: Generic_2_18
# displayName: Generic 2.18
# dependsOn: []
# jobs:
# - template: templates/matrix.yml
# parameters:
# nameFormat: Python {0}
# testFormat: 2.18/generic/{0}/1
# targets:
# - test: '3.8'
# - test: '3.13'
# - stage: Generic_2_17
# displayName: Generic 2.17
# dependsOn: []
# jobs:
# - template: templates/matrix.yml
# parameters:
# nameFormat: Python {0}
# testFormat: 2.17/generic/{0}/1
# targets:
# - test: '3.7'
# - test: '3.12'
# - stage: Generic_2_16
# displayName: Generic 2.16
# dependsOn: []
# jobs:
# - template: templates/matrix.yml
# parameters:
# nameFormat: Python {0}
# testFormat: 2.16/generic/{0}/1
# targets:
# - test: '2.7'
# - test: '3.6'
# - test: '3.11'
- stage: Summary
condition: succeededOrFailed()
dependsOn:
- Sanity_devel
- Sanity_2_18
- Sanity_2_17
- Sanity_2_16
- Units_devel
- Units_2_18
- Units_2_17
- Units_2_16
- Remote_devel_extra_vms
- Remote_devel
- Remote_2_18
- Remote_2_17
- Remote_2_16
- Docker_devel
- Docker_2_18
- Docker_2_17
- Docker_2_16
- Docker_community_devel
# Right now all generic tests are disabled. Uncomment when at least one of them is re-enabled.
# - Generic_devel
# - Generic_2_18
# - Generic_2_17
# - Generic_2_16
jobs:
- template: templates/coverage.yml

View File

@@ -1,24 +0,0 @@
#!/usr/bin/env bash
# Copyright (c) Ansible Project
# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
# SPDX-License-Identifier: GPL-3.0-or-later
# Aggregate code coverage results for later processing.
set -o pipefail -eu
agent_temp_directory="$1"
PATH="${PWD}/bin:${PATH}"
mkdir "${agent_temp_directory}/coverage/"
options=(--venv --venv-system-site-packages --color -v)
ansible-test coverage combine --group-by command --export "${agent_temp_directory}/coverage/" "${options[@]}"
if ansible-test coverage analyze targets generate --help >/dev/null 2>&1; then
# Only analyze coverage if the installed version of ansible-test supports it.
# Doing so allows this script to work unmodified for multiple Ansible versions.
ansible-test coverage analyze targets generate "${agent_temp_directory}/coverage/coverage-analyze-targets.json" "${options[@]}"
fi

View File

@@ -1,64 +0,0 @@
#!/usr/bin/env python
# Copyright (c) Ansible Project
# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
# SPDX-License-Identifier: GPL-3.0-or-later
"""
Combine coverage data from multiple jobs, keeping the data only from the most recent attempt from each job.
Coverage artifacts must be named using the format: "Coverage $(System.JobAttempt) {StableUniqueNameForEachJob}"
The recommended coverage artifact name format is: Coverage $(System.JobAttempt) $(System.StageDisplayName) $(System.JobDisplayName)
Keep in mind that Azure Pipelines does not enforce unique job display names (only names).
It is up to pipeline authors to avoid name collisions when deviating from the recommended format.
"""
from __future__ import (absolute_import, division, print_function)
__metaclass__ = type
import os
import re
import shutil
import sys
def main():
"""Main program entry point."""
source_directory = sys.argv[1]
if '/ansible_collections/' in os.getcwd():
output_path = "tests/output"
else:
output_path = "test/results"
destination_directory = os.path.join(output_path, 'coverage')
if not os.path.exists(destination_directory):
os.makedirs(destination_directory)
jobs = {}
count = 0
for name in os.listdir(source_directory):
match = re.search('^Coverage (?P<attempt>[0-9]+) (?P<label>.+)$', name)
label = match.group('label')
attempt = int(match.group('attempt'))
jobs[label] = max(attempt, jobs.get(label, 0))
for label, attempt in jobs.items():
name = 'Coverage {attempt} {label}'.format(label=label, attempt=attempt)
source = os.path.join(source_directory, name)
source_files = os.listdir(source)
for source_file in source_files:
source_path = os.path.join(source, source_file)
destination_path = os.path.join(destination_directory, source_file + '.' + label)
print('"%s" -> "%s"' % (source_path, destination_path))
shutil.copyfile(source_path, destination_path)
count += 1
print('Coverage file count: %d' % count)
print('##vso[task.setVariable variable=coverageFileCount]%d' % count)
print('##vso[task.setVariable variable=outputPath]%s' % output_path)
if __name__ == '__main__':
main()

View File

@@ -1,28 +0,0 @@
#!/usr/bin/env bash
# Copyright (c) Ansible Project
# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
# SPDX-License-Identifier: GPL-3.0-or-later
# Check the test results and set variables for use in later steps.
set -o pipefail -eu
if [[ "$PWD" =~ /ansible_collections/ ]]; then
output_path="tests/output"
else
output_path="test/results"
fi
echo "##vso[task.setVariable variable=outputPath]${output_path}"
if compgen -G "${output_path}"'/junit/*.xml' > /dev/null; then
echo "##vso[task.setVariable variable=haveTestResults]true"
fi
if compgen -G "${output_path}"'/bot/ansible-test-*' > /dev/null; then
echo "##vso[task.setVariable variable=haveBotResults]true"
fi
if compgen -G "${output_path}"'/coverage/*' > /dev/null; then
echo "##vso[task.setVariable variable=haveCoverageData]true"
fi

View File

@@ -1,105 +0,0 @@
#!/usr/bin/env python
# Copyright (c) Ansible Project
# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
# SPDX-License-Identifier: GPL-3.0-or-later
"""
Upload code coverage reports to codecov.io.
Multiple coverage files from multiple languages are accepted and aggregated after upload.
Python coverage, as well as PowerShell and Python stubs can all be uploaded.
"""
import argparse
import dataclasses
import pathlib
import shutil
import subprocess
import tempfile
import typing as t
import urllib.request
@dataclasses.dataclass(frozen=True)
class CoverageFile:
name: str
path: pathlib.Path
flags: t.List[str]
@dataclasses.dataclass(frozen=True)
class Args:
dry_run: bool
path: pathlib.Path
def parse_args() -> Args:
parser = argparse.ArgumentParser()
parser.add_argument('-n', '--dry-run', action='store_true')
parser.add_argument('path', type=pathlib.Path)
args = parser.parse_args()
# Store arguments in a typed dataclass
fields = dataclasses.fields(Args)
kwargs = {field.name: getattr(args, field.name) for field in fields}
return Args(**kwargs)
def process_files(directory: pathlib.Path) -> t.Tuple[CoverageFile, ...]:
processed = []
for file in directory.joinpath('reports').glob('coverage*.xml'):
name = file.stem.replace('coverage=', '')
# Get flags from name
flags = name.replace('-powershell', '').split('=') # Drop '-powershell' suffix
flags = [flag if not flag.startswith('stub') else flag.split('-')[0] for flag in flags] # Remove "-01" from stub files
processed.append(CoverageFile(name, file, flags))
return tuple(processed)
def upload_files(codecov_bin: pathlib.Path, files: t.Tuple[CoverageFile, ...], dry_run: bool = False) -> None:
for file in files:
cmd = [
str(codecov_bin),
'--name', file.name,
'--file', str(file.path),
]
for flag in file.flags:
cmd.extend(['--flags', flag])
if dry_run:
print(f'DRY-RUN: Would run command: {cmd}')
continue
subprocess.run(cmd, check=True)
def download_file(url: str, dest: pathlib.Path, flags: int, dry_run: bool = False) -> None:
if dry_run:
print(f'DRY-RUN: Would download {url} to {dest} and set mode to {flags:o}')
return
with urllib.request.urlopen(url) as resp:
with dest.open('w+b') as f:
# Read data in chunks rather than all at once
shutil.copyfileobj(resp, f, 64 * 1024)
dest.chmod(flags)
def main():
args = parse_args()
url = 'https://ansible-ci-files.s3.amazonaws.com/codecov/linux/codecov'
with tempfile.TemporaryDirectory(prefix='codecov-') as tmpdir:
codecov_bin = pathlib.Path(tmpdir) / 'codecov'
download_file(url, codecov_bin, 0o755, args.dry_run)
files = process_files(args.path)
upload_files(codecov_bin, files, args.dry_run)
if __name__ == '__main__':
main()

View File

@@ -1,19 +0,0 @@
#!/usr/bin/env bash
# Copyright (c) Ansible Project
# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
# SPDX-License-Identifier: GPL-3.0-or-later
# Generate code coverage reports for uploading to Azure Pipelines and codecov.io.
set -o pipefail -eu
PATH="${PWD}/bin:${PATH}"
if ! ansible-test --help >/dev/null 2>&1; then
# Install the devel version of ansible-test for generating code coverage reports.
# This is only used by Ansible Collections, which are typically tested against multiple Ansible versions (in separate jobs).
# Since a version of ansible-test is required that can work the output from multiple older releases, the devel version is used.
pip install https://github.com/ansible/ansible/archive/devel.tar.gz --disable-pip-version-check
fi
ansible-test coverage xml --group-by command --stub --venv --venv-system-site-packages --color -v

View File

@@ -1,38 +0,0 @@
#!/usr/bin/env bash
# Copyright (c) Ansible Project
# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
# SPDX-License-Identifier: GPL-3.0-or-later
# Configure the test environment and run the tests.
set -o pipefail -eu
entry_point="$1"
test="$2"
read -r -a coverage_branches <<< "$3" # space separated list of branches to run code coverage on for scheduled builds
export COMMIT_MESSAGE
export COMPLETE
export COVERAGE
export IS_PULL_REQUEST
if [ "${SYSTEM_PULLREQUEST_TARGETBRANCH:-}" ]; then
IS_PULL_REQUEST=true
COMMIT_MESSAGE=$(git log --format=%B -n 1 HEAD^2)
else
IS_PULL_REQUEST=
COMMIT_MESSAGE=$(git log --format=%B -n 1 HEAD)
fi
COMPLETE=
COVERAGE=
if [ "${BUILD_REASON}" = "Schedule" ]; then
COMPLETE=yes
if printf '%s\n' "${coverage_branches[@]}" | grep -q "^${BUILD_SOURCEBRANCHNAME}$"; then
COVERAGE=yes
fi
fi
"${entry_point}" "${test}" 2>&1 | "$(dirname "$0")/time-command.py"

View File

@@ -1,29 +0,0 @@
#!/usr/bin/env python
# Copyright (c) Ansible Project
# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
# SPDX-License-Identifier: GPL-3.0-or-later
"""Prepends a relative timestamp to each input line from stdin and writes it to stdout."""
from __future__ import (absolute_import, division, print_function)
__metaclass__ = type
import sys
import time
def main():
"""Main program entry point."""
start = time.time()
sys.stdin.reconfigure(errors='surrogateescape')
sys.stdout.reconfigure(errors='surrogateescape')
for line in sys.stdin:
seconds = time.time() - start
sys.stdout.write('%02d:%02d %s' % (seconds // 60, seconds % 60, line))
sys.stdout.flush()
if __name__ == '__main__':
main()

View File

@@ -1,34 +0,0 @@
---
# Copyright (c) Ansible Project
# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
# SPDX-License-Identifier: GPL-3.0-or-later
# This template adds a job for processing code coverage data.
# It will upload results to Azure Pipelines and codecov.io.
# Use it from a job stage that completes after all other jobs have completed.
# This can be done by placing it in a separate summary stage that runs after the test stage(s) have completed.
jobs:
- job: Coverage
displayName: Code Coverage
container: default
workspace:
clean: all
steps:
- checkout: self
fetchDepth: $(fetchDepth)
path: $(checkoutPath)
- task: DownloadPipelineArtifact@2
displayName: Download Coverage Data
inputs:
path: coverage/
patterns: "Coverage */*=coverage.combined"
- bash: .azure-pipelines/scripts/combine-coverage.py coverage/
displayName: Combine Coverage Data
- bash: .azure-pipelines/scripts/report-coverage.sh
displayName: Generate Coverage Report
condition: gt(variables.coverageFileCount, 0)
- bash: .azure-pipelines/scripts/publish-codecov.py "$(outputPath)"
displayName: Publish to codecov.io
condition: gt(variables.coverageFileCount, 0)
continueOnError: true

View File

@@ -1,60 +0,0 @@
---
# Copyright (c) Ansible Project
# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
# SPDX-License-Identifier: GPL-3.0-or-later
# This template uses the provided targets and optional groups to generate a matrix which is then passed to the test template.
# If this matrix template does not provide the required functionality, consider using the test template directly instead.
parameters:
# A required list of dictionaries, one per test target.
# Each item in the list must contain a "test" or "name" key.
# Both may be provided. If one is omitted, the other will be used.
- name: targets
type: object
# An optional list of values which will be used to multiply the targets list into a matrix.
# Values can be strings or numbers.
- name: groups
type: object
default: []
# An optional format string used to generate the job name.
# - {0} is the name of an item in the targets list.
- name: nameFormat
type: string
default: "{0}"
# An optional format string used to generate the test name.
# - {0} is the name of an item in the targets list.
- name: testFormat
type: string
default: "{0}"
# An optional format string used to add the group to the job name.
# {0} is the formatted name of an item in the targets list.
# {{1}} is the group -- be sure to include the double "{{" and "}}".
- name: nameGroupFormat
type: string
default: "{0} - {{1}}"
# An optional format string used to add the group to the test name.
# {0} is the formatted test of an item in the targets list.
# {{1}} is the group -- be sure to include the double "{{" and "}}".
- name: testGroupFormat
type: string
default: "{0}/{{1}}"
jobs:
- template: test.yml
parameters:
jobs:
- ${{ if eq(length(parameters.groups), 0) }}:
- ${{ each target in parameters.targets }}:
- name: ${{ format(parameters.nameFormat, coalesce(target.name, target.test)) }}
test: ${{ format(parameters.testFormat, coalesce(target.test, target.name)) }}
- ${{ if not(eq(length(parameters.groups), 0)) }}:
- ${{ each group in parameters.groups }}:
- ${{ each target in parameters.targets }}:
- name: ${{ format(format(parameters.nameGroupFormat, parameters.nameFormat), coalesce(target.name, target.test), group) }}
test: ${{ format(format(parameters.testGroupFormat, parameters.testFormat), coalesce(target.test, target.name), group) }}

View File

@@ -1,50 +0,0 @@
---
# Copyright (c) Ansible Project
# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
# SPDX-License-Identifier: GPL-3.0-or-later
# This template uses the provided list of jobs to create test one or more test jobs.
# It can be used directly if needed, or through the matrix template.
parameters:
# A required list of dictionaries, one per test job.
# Each item in the list must contain a "job" and "name" key.
- name: jobs
type: object
jobs:
- ${{ each job in parameters.jobs }}:
- job: test_${{ replace(replace(replace(job.test, '/', '_'), '.', '_'), '-', '_') }}
displayName: ${{ job.name }}
container: default
workspace:
clean: all
steps:
- checkout: self
fetchDepth: $(fetchDepth)
path: $(checkoutPath)
- bash: .azure-pipelines/scripts/run-tests.sh "$(entryPoint)" "${{ job.test }}" "$(coverageBranches)"
displayName: Run Tests
- bash: .azure-pipelines/scripts/process-results.sh
condition: succeededOrFailed()
displayName: Process Results
- bash: .azure-pipelines/scripts/aggregate-coverage.sh "$(Agent.TempDirectory)"
condition: eq(variables.haveCoverageData, 'true')
displayName: Aggregate Coverage Data
- task: PublishTestResults@2
condition: eq(variables.haveTestResults, 'true')
inputs:
testResultsFiles: "$(outputPath)/junit/*.xml"
displayName: Publish Test Results
- task: PublishPipelineArtifact@1
condition: eq(variables.haveBotResults, 'true')
displayName: Publish Bot Results
inputs:
targetPath: "$(outputPath)/bot/"
artifactName: "Bot $(System.JobAttempt) $(System.StageDisplayName) $(System.JobDisplayName)"
- task: PublishPipelineArtifact@1
condition: eq(variables.haveCoverageData, 'true')
displayName: Publish Coverage Data
inputs:
targetPath: "$(Agent.TempDirectory)/coverage/"
artifactName: "Coverage $(System.JobAttempt) $(System.StageDisplayName) $(System.JobDisplayName)"

64
.github/BOTMETA.yml vendored
View File

@@ -61,6 +61,7 @@ files:
$callbacks/elastic.py:
keywords: apm observability
maintainers: v1v
$callbacks/hipchat.py: {}
$callbacks/jabber.py: {}
$callbacks/log_plays.py: {}
$callbacks/loganalytics.py:
@@ -111,9 +112,6 @@ files:
$connections/lxd.py:
labels: lxd
maintainers: mattclay
$connections/proxmox_pct_remote.py:
labels: proxmox
maintainers: mietzen
$connections/qubes.py:
maintainers: kushaldas
$connections/saltstack.py:
@@ -123,8 +121,6 @@ files:
maintainers: $team_ansible_core
$doc_fragments/:
labels: docs_fragments
$doc_fragments/clc.py:
maintainers: clc-runner russoz
$doc_fragments/django.py:
maintainers: russoz
$doc_fragments/hpe3par.py:
@@ -140,8 +136,6 @@ files:
$doc_fragments/xenserver.py:
labels: xenserver
maintainers: bvitnik
$filters/accumulate.py:
maintainers: VannTen
$filters/counter.py:
maintainers: keilr
$filters/crc32.py:
@@ -164,14 +158,6 @@ files:
maintainers: Ajpantuso
$filters/jc.py:
maintainers: kellyjonbrazil
$filters/json_diff.yml:
maintainers: numo68
$filters/json_patch.py:
maintainers: numo68
$filters/json_patch.yml:
maintainers: numo68
$filters/json_patch_recipe.yml:
maintainers: numo68
$filters/json_query.py: {}
$filters/keep_keys.py:
maintainers: vbotka
@@ -226,8 +212,6 @@ files:
maintainers: opoplawski
$inventories/gitlab_runners.py:
maintainers: morph027
$inventories/iocage.py:
maintainers: vbotka
$inventories/icinga2.py:
maintainers: BongoEADGC6
$inventories/linode.py:
@@ -307,8 +291,6 @@ files:
$lookups/onepassword_raw.py:
ignore: scottsb
maintainers: azenk
$lookups/onepassword_ssh_key.py:
maintainers: mohammedbabelly20
$lookups/passwordstore.py: {}
$lookups/random_pet.py:
maintainers: Akasurde
@@ -326,12 +308,8 @@ files:
maintainers: delineaKrehl tylerezimmerman
$module_utils/:
labels: module_utils
$module_utils/android_sdkmanager.py:
maintainers: shamilovstas
$module_utils/btrfs.py:
maintainers: gnfzdz
$module_utils/cmd_runner_fmt.py:
maintainers: russoz
$module_utils/cmd_runner.py:
maintainers: russoz
$module_utils/deps.py:
@@ -378,8 +356,6 @@ files:
$module_utils/oracle/oci_utils.py:
labels: cloud
maintainers: $team_oracle
$module_utils/pacemaker.py:
maintainers: munchtoast
$module_utils/pipx.py:
labels: pipx
maintainers: russoz
@@ -404,8 +380,6 @@ files:
maintainers: russoz
$module_utils/ssh.py:
maintainers: russoz
$module_utils/systemd.py:
maintainers: NomakCooper
$module_utils/storage/hpe3par/hpe3par.py:
maintainers: farhan7500 gautamphegde
$module_utils/utm_utils.py:
@@ -443,8 +417,6 @@ files:
ignore: DavidWittman jiuka
labels: alternatives
maintainers: mulby
$modules/android_sdk.py:
maintainers: shamilovstas
$modules/ansible_galaxy_install.py:
maintainers: russoz
$modules/apache2_mod_proxy.py:
@@ -533,8 +505,6 @@ files:
ignore: skornehl
$modules/dconf.py:
maintainers: azaghal
$modules/decompress.py:
maintainers: shamilovstas
$modules/deploy_helper.py:
maintainers: ramondelafuente
$modules/dimensiondata_network.py:
@@ -791,8 +761,6 @@ files:
maintainers: sermilrod
$modules/jenkins_job_info.py:
maintainers: stpierre
$modules/jenkins_node.py:
maintainers: phyrwork
$modules/jenkins_plugin.py:
maintainers: jtyr
$modules/jenkins_script.py:
@@ -829,8 +797,6 @@ files:
maintainers: fynncfchen johncant
$modules/keycloak_clientsecret_regenerate.py:
maintainers: fynncfchen johncant
$modules/keycloak_component.py:
maintainers: fivetide
$modules/keycloak_group.py:
maintainers: adamgoossens
$modules/keycloak_identity_provider.py:
@@ -863,8 +829,6 @@ files:
maintainers: ahussey-redhat
$modules/kibana_plugin.py:
maintainers: barryib
$modules/krb_ticket.py:
maintainers: abakanovskii
$modules/launchd.py:
maintainers: martinm82
$modules/layman.py:
@@ -875,8 +839,6 @@ files:
maintainers: drybjed jtyr noles
$modules/ldap_entry.py:
maintainers: jtyr
$modules/ldap_inc.py:
maintainers: pduveau
$modules/ldap_passwd.py:
maintainers: KellerFuchs jtyr
$modules/ldap_search.py:
@@ -1058,8 +1020,6 @@ files:
maintainers: fraff
$modules/pacemaker_cluster.py:
maintainers: matbu
$modules/pacemaker_resource.py:
maintainers: munchtoast
$modules/packet_:
maintainers: nurfet-becirevic t0mk
$modules/packet_device.py:
@@ -1150,10 +1110,6 @@ files:
$modules/proxmox_kvm.py:
ignore: skvidal
maintainers: helldorado krauthosting
$modules/proxmox_backup.py:
maintainers: IamLunchbox
$modules/proxmox_backup_info.py:
maintainers: raoufnezhad mmayabi
$modules/proxmox_nic.py:
maintainers: Kogelvis krauthosting
$modules/proxmox_node_info.py:
@@ -1203,6 +1159,12 @@ files:
keywords: kvm libvirt proxmox qemu
labels: rhevm virt
maintainers: $team_virt TimothyVandenbrande
$modules/rhn_channel.py:
labels: rhn_channel
maintainers: vincentvdk alikins $team_rhn
$modules/rhn_register.py:
labels: rhn_register
maintainers: jlaska $team_rhn
$modules/rhsm_release.py:
maintainers: seandst $team_rhsm
$modules/rhsm_repository.py:
@@ -1366,12 +1328,6 @@ files:
maintainers: precurse
$modules/sysrc.py:
maintainers: dlundgren
$modules/systemd_creds_decrypt.py:
maintainers: konstruktoid
$modules/systemd_creds_encrypt.py:
maintainers: konstruktoid
$modules/systemd_info.py:
maintainers: NomakCooper
$modules/sysupgrade.py:
maintainers: precurse
$modules/taiga_issue.py:
@@ -1491,9 +1447,6 @@ files:
maintainers: $team_suse
$plugin_utils/ansible_type.py:
maintainers: vbotka
$modules/zypper_repository_info.py:
labels: zypper
maintainers: $team_suse TobiasZeuch181
$plugin_utils/keys_filter.py:
maintainers: vbotka
$plugin_utils/unsafe.py:
@@ -1551,8 +1504,6 @@ files:
maintainers: baldwinSPC nurfet-becirevic t0mk teebes
docs/docsite/rst/guide_scaleway.rst:
maintainers: $team_scaleway
docs/docsite/rst/guide_uthelper.rst:
maintainers: russoz
docs/docsite/rst/guide_vardict.rst:
maintainers: russoz
docs/docsite/rst/test_guide.rst:
@@ -1604,6 +1555,7 @@ macros:
team_oracle: manojmeda mross22 nalsaber
team_purestorage: bannaych dnix101 genegr lionmax opslounge raekins sdodsley sile16
team_redfish: mraineri tomasg2012 xmadsen renxulei rajeevkallur bhavya06 jyundt
team_rhn: FlossWare alikins barnabycourt vritant
team_rhsm: cnsnyder ptoscano
team_scaleway: remyleone abarbare
team_solaris: bcoca fishman jasperla jpdasma mator scathatheworm troy2914 xen0l

View File

@@ -1,182 +0,0 @@
---
# Copyright (c) Ansible Project
# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
# SPDX-License-Identifier: GPL-3.0-or-later
# For the comprehensive list of the inputs supported by the ansible-community/ansible-test-gh-action GitHub Action, see
# https://github.com/marketplace/actions/ansible-test
name: EOL CI
on:
# Run EOL CI against all pushes (direct commits, also merged PRs), Pull Requests
push:
branches:
- main
- stable-*
pull_request:
# Run EOL CI once per day (at 08:00 UTC)
schedule:
- cron: '0 8 * * *'
concurrency:
# Make sure there is at most one active run per PR, but do not cancel any non-PR runs
group: ${{ github.workflow }}-${{ (github.head_ref && github.event.number) || github.run_id }}
cancel-in-progress: true
jobs:
sanity:
name: EOL Sanity (Ⓐ${{ matrix.ansible }})
strategy:
matrix:
ansible:
- '2.15'
# Ansible-test on various stable branches does not yet work well with cgroups v2.
# Since ubuntu-latest now uses Ubuntu 22.04, we need to fall back to the ubuntu-20.04
# image for these stable branches. The list of branches where this is necessary will
# shrink over time, check out https://github.com/ansible-collections/news-for-maintainers/issues/28
# for the latest list.
runs-on: ubuntu-latest
steps:
- name: Perform sanity testing
uses: felixfontein/ansible-test-gh-action@main
with:
ansible-core-version: stable-${{ matrix.ansible }}
codecov-token: ${{ secrets.CODECOV_TOKEN }}
coverage: ${{ github.event_name == 'schedule' && 'always' || 'never' }}
pull-request-change-detection: 'true'
testing-type: sanity
pre-test-cmd: >-
git clone --depth=1 --single-branch https://github.com/ansible-collections/community.internal_test_tools.git ../../community/internal_test_tools
units:
# Ansible-test on various stable branches does not yet work well with cgroups v2.
# Since ubuntu-latest now uses Ubuntu 22.04, we need to fall back to the ubuntu-20.04
# image for these stable branches. The list of branches where this is necessary will
# shrink over time, check out https://github.com/ansible-collections/news-for-maintainers/issues/28
# for the latest list.
runs-on: ubuntu-latest
name: EOL Units (Ⓐ${{ matrix.ansible }}+py${{ matrix.python }})
strategy:
# As soon as the first unit test fails, cancel the others to free up the CI queue
fail-fast: true
matrix:
ansible:
- ''
python:
- ''
exclude:
- ansible: ''
include:
- ansible: '2.15'
python: '2.7'
- ansible: '2.15'
python: '3.5'
- ansible: '2.15'
python: '3.10'
steps:
- name: >-
Perform unit testing against
Ansible version ${{ matrix.ansible }}
uses: felixfontein/ansible-test-gh-action@main
with:
ansible-core-version: stable-${{ matrix.ansible }}
codecov-token: ${{ secrets.CODECOV_TOKEN }}
coverage: ${{ github.event_name == 'schedule' && 'always' || 'never' }}
pre-test-cmd: >-
mkdir -p ../../ansible
;
git clone --depth=1 --single-branch https://github.com/ansible-collections/community.internal_test_tools.git ../../community/internal_test_tools
pull-request-change-detection: 'true'
target-python-version: ${{ matrix.python }}
testing-type: units
integration:
# Ansible-test on various stable branches does not yet work well with cgroups v2.
# Since ubuntu-latest now uses Ubuntu 22.04, we need to fall back to the ubuntu-20.04
# image for these stable branches. The list of branches where this is necessary will
# shrink over time, check out https://github.com/ansible-collections/news-for-maintainers/issues/28
# for the latest list.
runs-on: ubuntu-latest
name: EOL I (Ⓐ${{ matrix.ansible }}+${{ matrix.docker }}+py${{ matrix.python }}:${{ matrix.target }})
strategy:
fail-fast: false
matrix:
ansible:
- ''
docker:
- ''
python:
- ''
target:
- ''
exclude:
- ansible: ''
include:
# 2.15
- ansible: '2.15'
docker: alpine3
python: ''
target: azp/posix/1/
- ansible: '2.15'
docker: alpine3
python: ''
target: azp/posix/2/
- ansible: '2.15'
docker: alpine3
python: ''
target: azp/posix/3/
- ansible: '2.15'
docker: fedora37
python: ''
target: azp/posix/1/
- ansible: '2.15'
docker: fedora37
python: ''
target: azp/posix/2/
- ansible: '2.15'
docker: fedora37
python: ''
target: azp/posix/3/
# Right now all generic tests are disabled. Uncomment when at least one of them is re-enabled.
# - ansible: '2.13'
# docker: default
# python: '3.9'
# target: azp/generic/1/
# - ansible: '2.14'
# docker: default
# python: '3.10'
# target: azp/generic/1/
# - ansible: '2.15'
# docker: default
# python: '3.9'
# target: azp/generic/1/
steps:
- name: >-
Perform integration testing against
Ansible version ${{ matrix.ansible }}
under Python ${{ matrix.python }}
uses: felixfontein/ansible-test-gh-action@main
with:
ansible-core-version: stable-${{ matrix.ansible }}
codecov-token: ${{ secrets.CODECOV_TOKEN }}
coverage: ${{ github.event_name == 'schedule' && 'always' || 'never' }}
docker-image: ${{ matrix.docker }}
integration-continue-on-error: 'false'
integration-diff: 'false'
integration-retry-on-error: 'true'
pre-test-cmd: >-
mkdir -p ../../ansible
;
git clone --depth=1 --single-branch https://github.com/ansible-collections/ansible.posix.git ../../ansible/posix
;
git clone --depth=1 --single-branch https://github.com/ansible-collections/community.crypto.git ../../community/crypto
;
git clone --depth=1 --single-branch https://github.com/ansible-collections/community.docker.git ../../community/docker
;
git clone --depth=1 --single-branch https://github.com/ansible-collections/community.internal_test_tools.git ../../community/internal_test_tools
pull-request-change-detection: 'true'
target: ${{ matrix.target }}
target-python-version: ${{ matrix.python }}
testing-type: integration

View File

@@ -1,38 +0,0 @@
---
# Copyright (c) Ansible Project
# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
# SPDX-License-Identifier: GPL-3.0-or-later
name: "Code scanning - action"
on:
schedule:
- cron: '26 19 * * 1'
workflow_dispatch:
permissions:
contents: read
jobs:
CodeQL-Build:
permissions:
actions: read # for github/codeql-action/init to get workflow details
contents: read # for actions/checkout to fetch code
security-events: write # for github/codeql-action/autobuild to send a status report
runs-on: ubuntu-latest
steps:
- name: Checkout repository
uses: actions/checkout@v4
with:
persist-credentials: false
# Initializes the CodeQL tools for scanning.
- name: Initialize CodeQL
uses: github/codeql-action/init@v3
with:
languages: python
- name: Perform CodeQL Analysis
uses: github/codeql-action/analyze@v3

View File

@@ -1,20 +0,0 @@
---
# Copyright (c) Ansible Project
# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
# SPDX-License-Identifier: GPL-3.0-or-later
name: import-galaxy
'on':
# Run CI against all pushes (direct commits, also merged PRs) to main, and all Pull Requests
push:
branches:
- main
- stable-*
pull_request:
jobs:
import-galaxy:
permissions:
contents: read
name: Test to import built collection artifact with Galaxy importer
uses: ansible-community/github-action-test-galaxy-import/.github/workflows/test-galaxy-import.yml@main

View File

@@ -1,35 +0,0 @@
---
# Copyright (c) Ansible Project
# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
# SPDX-License-Identifier: GPL-3.0-or-later
name: Verify REUSE
on:
push:
branches:
- main
- stable-*
pull_request:
types: [opened, synchronize, reopened]
branches:
- main
- stable-*
# Run CI once per day (at 07:30 UTC)
schedule:
- cron: '30 7 * * *'
jobs:
check:
permissions:
contents: read
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
with:
persist-credentials: false
ref: ${{ github.event.pull_request.head.sha || '' }}
- name: REUSE Compliance Check
uses: fsfe/reuse-action@v5

14
.gitignore vendored
View File

@@ -383,6 +383,16 @@ cython_debug/
# option (not recommended) you can uncomment the following to ignore the entire idea folder.
#.idea/
### Python Patch ###
# Poetry local configuration file - https://python-poetry.org/docs/configuration/#local-configuration
poetry.toml
# ruff
.ruff_cache/
# LSP config files
pyrightconfig.json
### Vim ###
# Swap
[._]*.s[a-v][a-z]
@@ -482,6 +492,10 @@ tags
# https://plugins.jetbrains.com/plugin/12206-codestream
.idea/codestream.xml
# Azure Toolkit for IntelliJ plugin
# https://plugins.jetbrains.com/plugin/8053-azure-toolkit-for-intellij
.idea/**/azureSettings.xml
### Windows ###
# Windows thumbnail cache files
Thumbs.db

View File

@@ -1,5 +0,0 @@
Format: https://www.debian.org/doc/packaging-manuals/copyright-format/1.0/
Files: changelogs/fragments/*
Copyright: Ansible Project
License: GPL-3.0-or-later

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -44,7 +44,49 @@ If you want to test a PR locally, refer to [our testing guide](https://github.co
If you find any inconsistencies or places in this document which can be improved, feel free to raise an issue or pull request to fix it.
## Run sanity, unit or integration tests locally
## Run sanity or unit locally (with antsibull-nox)
The easiest way to run sanity and unit tests locally is to use [antsibull-nox](https://ansible.readthedocs.io/projects/antsibull-nox/).
(If you have [nox](https://nox.thea.codes/en/stable/) installed, it will automatically install antsibull-nox in a virtual environment for you.)
### Sanity tests
The following commands show how to run ansible-test sanity tests:
```.bash
# Run basic sanity tests for all files in the collection:
nox -Re ansible-test-sanity-devel
# Run basic sanity tests for the given files and directories:
nox -Re ansible-test-sanity-devel -- plugins/modules/system/pids.py tests/integration/targets/pids/
# Run all other sanity tests for all files in the collection:
nox -R
```
If you replace `-Re` with `-e`, respectively. If you leave `-R` away, then the virtual environments will be re-created. The `-R` re-uses them (if they already exist).
### Unit tests
The following commands show how to run unit tests:
```.bash
# Run all unit tests:
nox -Re ansible-test-units-devel
# Run all unit tests for one Python version (a lot faster):
nox -Re ansible-test-units-devel -- --python 3.13
# Run a specific unit test (for the nmcli module) for one Python version:
nox -Re ansible-test-units-devel -- --python 3.13 tests/unit/plugins/modules/net_tools/test_nmcli.py
```
If you replace `-Re` with `-e`, then the virtual environments will be re-created. The `-R` re-uses them (if they already exist).
## Run basic sanity, unit or integration tests locally (with ansible-test)
Instead of using antsibull-nox, you can also run sanity and unit tests with ansible-test directly.
This also allows you to run integration tests.
You have to check out the repository into a specific path structure to be able to run `ansible-test`. The path to the git checkout must end with `.../ansible_collections/community/general`. Please see [our testing guide](https://github.com/ansible/community-docs/blob/main/test_pr_locally_guide.rst) for instructions on how to check out the repository into a correct path structure. The short version of these instructions is:
@@ -56,20 +98,27 @@ cd ~/dev/ansible_collections/community/general
Then you can run `ansible-test` (which is a part of [ansible-core](https://pypi.org/project/ansible-core/)) inside the checkout. The following example commands expect that you have installed Docker or Podman. Note that Podman has only been supported by more recent ansible-core releases. If you are using Docker, the following will work with Ansible 2.9+.
### Sanity tests
### Basic sanity tests
The following commands show how to run sanity tests:
The following commands show how to run basic sanity tests:
```.bash
# Run sanity tests for all files in the collection:
# Run basic sanity tests for all files in the collection:
ansible-test sanity --docker -v
# Run sanity tests for the given files and directories:
# Run basic sanity tests for the given files and directories:
ansible-test sanity --docker -v plugins/modules/system/pids.py tests/integration/targets/pids/
```
### Unit tests
Note that for running unit tests, you need to install required collections in the same folder structure that `community.general` is checked out in.
Right now, you need to install [`community.internal_test_tools`](https://github.com/ansible-collections/community.internal_test_tools).
If you want to use the latest version from GitHub, you can run:
```
git clone https://github.com/ansible-collections/community.internal_test_tools.git ~/dev/ansible_collections/community/internal_test_tools
```
The following commands show how to run unit tests:
```.bash
@@ -85,6 +134,16 @@ ansible-test units --docker -v --python 3.8 tests/unit/plugins/modules/net_tools
### Integration tests
Note that for running integration tests, you need to install required collections in the same folder structure that `community.general` is checked out in.
Right now, depending on the test, you need to install [`ansible.posix`](https://github.com/ansible-collections/ansible.posix), [`community.crypto`](https://github.com/ansible-collections/community.crypto), and [`community.docker`](https://github.com/ansible-collections/community.docker):
If you want to use the latest versions from GitHub, you can run:
```
mkdir -p ~/dev/ansible_collections/ansible
git clone https://github.com/ansible-collections/ansible.posix.git ~/dev/ansible_collections/ansible/posix
git clone https://github.com/ansible-collections/community.crypto.git ~/dev/ansible_collections/community/crypto
git clone https://github.com/ansible-collections/community.docker.git ~/dev/ansible_collections/community/docker
```
The following commands show how to run integration tests:
#### In Docker
@@ -92,8 +151,8 @@ The following commands show how to run integration tests:
Integration tests on Docker have the following parameters:
- `image_name` (required): The name of the Docker image. To get the list of supported Docker images, run
`ansible-test integration --help` and look for _target docker images_.
- `test_name` (optional): The name of the integration test.
For modules, this equals the short name of the module; for example, `pacman` in case of `community.general.pacman`.
- `test_name` (optional): The name of the integration test.
For modules, this equals the short name of the module; for example, `pacman` in case of `community.general.pacman`.
For plugins, the plugin type is added before the plugin's short name, for example `callback_yaml` for the `community.general.yaml` callback.
```.bash
# Test all plugins/modules on fedora40

View File

@@ -7,8 +7,9 @@ SPDX-License-Identifier: GPL-3.0-or-later
# Community General Collection
[![Documentation](https://img.shields.io/badge/docs-brightgreen.svg)](https://docs.ansible.com/ansible/latest/collections/community/general/)
[![Build Status](https://dev.azure.com/ansible/community.general/_apis/build/status/CI?branchName=stable-10)](https://dev.azure.com/ansible/community.general/_build?definitionId=31)
[![EOL CI](https://github.com/ansible-collections/community.general/actions/workflows/ansible-test.yml/badge.svg?branch=stable-10)](https://github.com/ansible-collections/community.general/actions)
[![Build Status](https://dev.azure.com/ansible/community.general/_apis/build/status/CI?branchName=stable-9)](https://dev.azure.com/ansible/community.general/_build?definitionId=31)
[![EOL CI](https://github.com/ansible-collections/community.general/actions/workflows/ansible-test.yml/badge.svg?branch=stable-9)](https://github.com/ansible-collections/community.general/actions)
[![Nox CI](https://github.com/ansible-collections/community.general/actions/workflows/nox.yml/badge.svg?branch=stable-9)](https://github.com/ansible-collections/community.general/actions)
[![Codecov](https://img.shields.io/codecov/c/github/ansible-collections/community.general)](https://codecov.io/gh/ansible-collections/community.general)
[![REUSE status](https://api.reuse.software/badge/github.com/ansible-collections/community.general)](https://api.reuse.software/info/github.com/ansible-collections/community.general)
@@ -38,7 +39,7 @@ For more information about communication, see the [Ansible communication guide](
## Tested with Ansible
Tested with the current ansible-core 2.15, ansible-core 2.16, ansible-core 2.17, ansible-core 2.18 releases and the current development version of ansible-core. Ansible-core versions before 2.15.0 are not supported. This includes all ansible-base 2.10 and Ansible 2.9 releases.
Tested with the current ansible-core 2.13, ansible-core 2.14, ansible-core 2.15, ansible-core 2.16, ansible-core 2.17, ansible-core 2.18, and ansible-core 2.19 releases. Ansible-core versions before 2.13.0 are not supported. This includes all ansible-base 2.10 and Ansible 2.9 releases.
## External requirements
@@ -117,7 +118,7 @@ See the [Releasing guidelines](https://github.com/ansible/community-docs/blob/ma
## Release notes
See the [changelog](https://github.com/ansible-collections/community.general/blob/stable-10/CHANGELOG.md).
See the [changelog](https://github.com/ansible-collections/community.general/blob/stable-9/CHANGELOG.md).
## Roadmap
@@ -136,8 +137,8 @@ See [this issue](https://github.com/ansible-collections/community.general/issues
This collection is primarily licensed and distributed as a whole under the GNU General Public License v3.0 or later.
See [LICENSES/GPL-3.0-or-later.txt](https://github.com/ansible-collections/community.general/blob/stable-10/COPYING) for the full text.
See [LICENSES/GPL-3.0-or-later.txt](https://github.com/ansible-collections/community.general/blob/stable-9/COPYING) for the full text.
Parts of the collection are licensed under the [BSD 2-Clause license](https://github.com/ansible-collections/community.general/blob/stable-10/LICENSES/BSD-2-Clause.txt), the [MIT license](https://github.com/ansible-collections/community.general/blob/stable-10/LICENSES/MIT.txt), and the [PSF 2.0 license](https://github.com/ansible-collections/community.general/blob/stable-10/LICENSES/PSF-2.0.txt).
Parts of the collection are licensed under the [BSD 2-Clause license](https://github.com/ansible-collections/community.general/blob/stable-9/LICENSES/BSD-2-Clause.txt), the [MIT license](https://github.com/ansible-collections/community.general/blob/stable-9/LICENSES/MIT.txt), and the [PSF 2.0 license](https://github.com/ansible-collections/community.general/blob/stable-9/LICENSES/PSF-2.0.txt).
All files have a machine readable `SDPX-License-Identifier:` comment denoting its respective license(s) or an equivalent entry in an accompanying `.license` file. Only changelog fragments (which will not be part of a release) are covered by a blanket statement in `.reuse/dep5`. This conforms to the [REUSE specification](https://reuse.software/spec/).
All files have a machine readable `SDPX-License-Identifier:` comment denoting its respective license(s) or an equivalent entry in an accompanying `.license` file. Only changelog fragments (which will not be part of a release) are covered by a blanket statement in `REUSE.toml`. This conforms to the [REUSE specification](https://reuse.software/spec/).

View File

@@ -2,10 +2,10 @@
# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
# SPDX-License-Identifier: GPL-3.0-or-later
needs/root
version = 1
azp/posix/1
skip/aix
skip/freebsd
skip/osx
skip/macos
[[annotations]]
path = "changelogs/fragments/**"
precedence = "aggregate"
SPDX-FileCopyrightText = "Ansible Project"
SPDX-License-Identifier = "GPL-3.0-or-later"

68
antsibull-nox.toml Normal file
View File

@@ -0,0 +1,68 @@
# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
# SPDX-License-Identifier: GPL-3.0-or-later
# SPDX-FileCopyrightText: 2025 Felix Fontein <felix@fontein.de>
[collection_sources]
"ansible.posix" = "git+https://github.com/ansible-collections/ansible.posix.git,main"
"community.crypto" = "git+https://github.com/ansible-collections/community.crypto.git,main"
"community.docker" = "git+https://github.com/ansible-collections/community.docker.git,main"
"community.internal_test_tools" = "git+https://github.com/ansible-collections/community.internal_test_tools.git,main"
[collection_sources_per_ansible.'2.13']
"community.crypto" = "git+https://github.com/ansible-collections/community.crypto.git,stable-2"
[collection_sources_per_ansible.'2.14']
"community.crypto" = "git+https://github.com/ansible-collections/community.crypto.git,stable-2"
[collection_sources_per_ansible.'2.15']
# community.crypto's main branch needs ansible-core >= 2.17
"community.crypto" = "git+https://github.com/ansible-collections/community.crypto.git,stable-2"
[collection_sources_per_ansible.'2.16']
# community.crypto's main branch needs ansible-core >= 2.17
"community.crypto" = "git+https://github.com/ansible-collections/community.crypto.git,stable-2"
[vcs]
vcs = "git"
development_branch = "main"
stable_branches = [ "stable-*" ]
[sessions]
[sessions.docs_check]
validate_collection_refs="all"
[sessions.license_check]
[sessions.extra_checks]
run_no_unwanted_files = true
no_unwanted_files_module_extensions = [".py"]
no_unwanted_files_yaml_extensions = [".yml"]
run_action_groups = true
[[sessions.extra_checks.action_groups_config]]
name = "consul"
pattern = "^consul_.*$"
exclusions = [
"consul_acl",
"consul_acl_bootstrap",
"consul_kv",
]
doc_fragment = "community.general.consul.actiongroup_consul"
[[sessions.extra_checks.action_groups_config]]
name = "proxmox"
pattern = "^proxmox(_.*)?$"
exclusions = []
doc_fragment = "community.general.proxmox.actiongroup_proxmox"
[sessions.build_import_check]
run_galaxy_importer = true
[sessions.ansible_test_sanity]
include_devel = false
max_version = "2.19"
[sessions.ansible_test_units]
include_devel = false
max_version = "2.19"

File diff suppressed because it is too large Load Diff

View File

@@ -7,9 +7,9 @@ changelog_filename_template: ../CHANGELOG.rst
changelog_filename_version_depth: 0
changes_file: changelog.yaml
changes_format: combined
ignore_other_fragment_extensions: true
keep_fragments: false
mention_ancestor: true
flatmap: true
new_plugins_after_name: removed_features
notesdir: fragments
output_formats:
@@ -40,3 +40,4 @@ use_fqcn: true
add_plugin_period: true
changelog_nice_yaml: true
changelog_sort: version
vcs: auto

View File

@@ -20,4 +20,3 @@ sections:
- guide_vardict
- guide_cmdrunner
- guide_modulehelper
- guide_uthelper

View File

@@ -267,54 +267,24 @@ In these descriptions ``value`` refers to the single parameter passed to the for
+------------+-------------------------+
- ``cmd_runner_fmt.as_fixed()``
This method defines one or more fixed arguments that are returned by the generated function
regardless whether ``value`` is passed to it or not.
This method accepts these arguments in one of three forms:
* one scalar parameter ``arg``, which will be returned as ``[arg]`` by the function, or
* one sequence parameter, such as a list, ``arg``, which will be returned by the function as ``arg[0]``, or
* multiple parameters ``args``, which will be returned as ``args`` directly by the function.
See the examples below for each one of those forms. And, stressing that the generated function expects no ``value`` - if one
This method receives one parameter ``arg``, the function expects no ``value`` - if one
is provided then it is ignored.
The function returns ``arg`` as-is.
- Creation (one scalar argument):
* ``cmd_runner_fmt.as_fixed("--version")``
- Creation:
``cmd_runner_fmt.as_fixed("--version")``
- Examples:
+---------+--------------------------------------+
| Value | Outcome |
+=========+======================================+
| | * ``["--version"]`` |
+---------+--------------------------------------+
| 57 | * ``["--version"]`` |
+---------+--------------------------------------+
- Creation (one sequence argument):
* ``cmd_runner_fmt.as_fixed(["--list", "--json"])``
- Examples:
+---------+--------------------------------------+
| Value | Outcome |
+=========+======================================+
| | * ``["--list", "--json"]`` |
+---------+--------------------------------------+
| True | * ``["--list", "--json"]`` |
+---------+--------------------------------------+
- Creation (multiple arguments):
* ``cmd_runner_fmt.as_fixed("--one", "--two", "--three")``
- Examples:
+---------+--------------------------------------+
| Value | Outcome |
+=========+======================================+
| | * ``["--one", "--two", "--three"]`` |
+---------+--------------------------------------+
| False | * ``["--one", "--two", "--three"]`` |
+---------+--------------------------------------+
+---------+-----------------------+
| Value | Outcome |
+=========+=======================+
| | ``["--version"]`` |
+---------+-----------------------+
| 57 | ``["--version"]`` |
+---------+-----------------------+
- Note:
This is the only special case in which a value can be missing for the formatting function.
The first example here comes from the code in `Quickstart`_.
The example also comes from the code in `Quickstart`_.
In that case, the module has code to determine the command's version so that it can assert compatibility.
There is no *value* to be passed for that CLI argument.

View File

@@ -22,6 +22,7 @@ The same example from the Developer Guide would become:
from ansible_collections.community.general.plugins.module_utils import deps
with deps.declare("foo"):
import foo

View File

@@ -75,6 +75,7 @@ section above, but there are more elements that will take part in it.
from ansible_collections.community.general.plugins.module_utils.module_helper import ModuleHelper
class MyTest(ModuleHelper):
output_params = ()
change_params = ()
@@ -256,9 +257,9 @@ With that, MH will automatically generate the diff output for variables that hav
class MyTest(ModuleHelper):
diff_params = ('value', )
def __run__(self):
# example from community.general.gio_mime
self.vars.set_meta("handler", initial_value=gio_mime_get(self.runner, self.vars.mime_type), diff=True, change=True)
def __run__(self):
# example from community.general.gio_mime
self.vars.set_meta("handler", initial_value=gio_mime_get(self.runner, self.vars.mime_type), diff=True, change=True)
Moreover, if a module is set to return *facts* instead of return values, then again use the metadata ``fact=True`` and ``fact_params`` for module parameters.
Additionally, you must specify ``facts_name``, as in:
@@ -346,8 +347,6 @@ However, you can set output variables specifically for that exception, if you so
.. code-block:: python
from ansible_collections.community.general.plugins.module_utils.module_helper import ModuleHelperException
def __init_module__(self):
if not complex_validation():
self.do_raise("Validation failed!")
@@ -356,16 +355,11 @@ However, you can set output variables specifically for that exception, if you so
awesomeness = calculate_awesomeness()
if awesomeness > 1000:
self.do_raise("Over awesome, I cannot handle it!", update_output={"awesomeness": awesomeness})
# which is just a convenience shortcut for
raise ModuleHelperException("...", update_output={...})
All exceptions derived from ``Exception`` are captured and translated into a ``fail_json()`` call.
However, if you do want to call ``self.module.fail_json()`` yourself it will work,
just keep in mind that there will be no automatic handling of output variables in that case.
Behind the curtains, all ``do_raise()`` does is to raise a ``ModuleHelperException``.
If you want to create specialized error handling for your code, the best way is to extend that clas and raise it when needed.
.. _ansible_collections.community.general.docsite.guide_modulehelper.statemh:
StateModuleHelper
@@ -468,11 +462,6 @@ Additionally, MH will also delegate:
- ``diff_mode`` to ``self.module._diff``
- ``verbosity`` to ``self.module._verbosity``
Starting in community.general 10.3.0, MH will also delegate the method ``debug`` to ``self.module``.
If any existing module already has a ``debug`` attribute defined, a warning message will be generated,
requesting it to be renamed. Upon the release of community.general 12.0.0, the delegation will be
preemptive and will override any existing method or property in the subclasses.
Decorators
""""""""""

View File

@@ -1,394 +0,0 @@
..
Copyright (c) Ansible Project
GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
SPDX-License-Identifier: GPL-3.0-or-later
.. _ansible_collections.community.general.docsite.guide_uthelper:
UTHelper Guide
==============
Introduction
^^^^^^^^^^^^
``UTHelper`` was written to reduce the boilerplate code used in unit tests for modules.
It was originally written to handle tests of modules that run external commands using ``AnsibleModule.run_command()``.
At the time of writing (Feb 2025) that remains the only type of tests you can use
``UTHelper`` for, but it aims to provide support for other types of interactions.
Until now, there are many different ways to implement unit tests that validate a module based on the execution of external commands. See some examples:
* `test_apk.py <https://github.com/ansible-collections/community.general/blob/10.3.0/tests/unit/plugins/modules/test_apk.py>`_ - A very simple one
* `test_bootc_manage.py <https://github.com/ansible-collections/community.general/blob/10.3.0/tests/unit/plugins/modules/test_bootc_manage.py>`_ -
This one has more test cases, but do notice how the code is repeated amongst them.
* `test_modprobe.py <https://github.com/ansible-collections/community.general/blob/10.3.0/tests/unit/plugins/modules/test_modprobe.py>`_ -
This one has 15 tests in it, but to achieve that it declares 8 classes repeating quite a lot of code.
As you can notice, there is no consistency in the way these tests are executed -
they all do the same thing eventually, but each one is written in a very distinct way.
``UTHelper`` aims to:
* provide a consistent idiom to define unit tests
* reduce the code to a bare minimal, and
* define tests as data instead
* allow the test cases definition to be expressed not only as a Python data structure but also as YAML content
Quickstart
""""""""""
To use UTHelper, your test module will need only a bare minimal of code:
.. code-block:: python
# tests/unit/plugin/modules/test_ansible_module.py
from ansible_collections.community.general.plugins.modules import ansible_module
from .uthelper import UTHelper, RunCommandMock
UTHelper.from_module(ansible_module, __name__, mocks=[RunCommandMock])
Then, in the test specification file, you have:
.. code-block:: yaml
# tests/unit/plugin/modules/test_ansible_module.yaml
test_cases:
- id: test_ansible_module
flags:
diff: true
input:
state: present
name: Roger the Shrubber
output:
shrubbery:
looks: nice
price: not too expensive
changed: true
diff:
before:
shrubbery: null
after:
shrubbery:
looks: nice
price: not too expensive
mocks:
run_command:
- command: [/testbin/shrubber, --version]
rc: 0
out: "2.80.0\n"
err: ''
- command: [/testbin/shrubber, --make-shrubbery]
rc: 0
out: 'Shrubbery created'
err: ''
.. note::
If you prefer to pick a different YAML file for the test cases, or if you prefer to define them in plain Python,
you can use the convenience methods ``UTHelper.from_file()`` and ``UTHelper.from_spec()``, respectively.
See more details below.
Using ``UTHelper``
^^^^^^^^^^^^^^^^^^
Test Module
"""""""""""
``UTHelper`` is **strictly for unit tests**. To use it, you import the ``.uthelper.UTHelper`` class.
As mentioned in different parts of this guide, there are three different mechanisms to load the test cases.
.. seealso::
See the UTHelper class reference below for API details on the three different mechanisms.
The easies and most recommended way of using ``UTHelper`` is literally the example shown.
See a real world example at
`test_gconftool2.py <https://github.com/ansible-collections/community.general/blob/10.3.0/tests/unit/plugins/modules/test_gconftool2.py>`_.
The ``from_module()`` method will pick the filename of the test module up (in the example above, ``tests/unit/plugins/modules/test_gconftool2.py``)
and it will search for ``tests/unit/plugins/modules/test_gconftool2.yaml`` (or ``.yml`` if that is not found).
In that file it will expect to find the test specification expressed in YAML format, conforming to the structure described below LINK LINK LINK.
If you prefer to read the test specifications a different file path, use ``from_file()`` passing the file handle for the YAML file.
And, if for any reason you prefer or need to pass the data structure rather than dealing with YAML files, use the ``from_spec()`` method.
A real world example for that can be found at
`test_snap.py <https://github.com/ansible-collections/community.general/blob/main/tests/unit/plugins/modules/test_snap.py>`_.
Test Specification
""""""""""""""""""
The structure of the test specification data is described below.
Top level
---------
At the top level there are two accepted keys:
- ``anchors: dict``
Optional. Placeholder for you to define YAML anchors that can be repeated in the test cases.
Its contents are never accessed directly by test Helper.
- ``test_cases: list``
Mandatory. List of test cases, see below for definition.
Test cases
----------
You write the test cases with five elements:
- ``id: str``
Mandatory. Used to identify the test case.
- ``flags: dict``
Optional. Flags controling the behavior of the test case. All flags are optional. Accepted flags:
* ``check: bool``: set to ``true`` if the module is to be executed in **check mode**.
* ``diff: bool``: set to ``true`` if the module is to be executed in **diff mode**.
* ``skip: str``: set the test case to be skipped, providing the message for ``pytest.skip()``.
* ``xfail: str``: set the test case to expect failure, providing the message for ``pytest.xfail()``.
- ``input: dict``
Optional. Parameters for the Ansible module, it can be empty.
- ``output: dict``
Optional. Expected return values from the Ansible module.
All RV names are used here are expected to be found in the module output, but not all RVs in the output must be here.
It can include special RVs such as ``changed`` and ``diff``.
It can be empty.
- ``mocks: dict``
Optional. Mocked interactions, ``run_command`` being the only one supported for now.
Each key in this dictionary refers to one subclass of ``TestCaseMock`` and its
structure is dictated by the ``TestCaseMock`` subclass implementation.
All keys are expected to be named using snake case, as in ``run_command``.
The ``TestCaseMock`` subclass is responsible for defining the name used in the test specification.
The structure for that specification is dependent on the implementing class.
See more details below for the implementation of ``RunCommandMock``
Example using YAML
------------------
We recommend you use ``UTHelper`` reading the test specifications from a YAML file.
See an example below of how one actually looks like (excerpt from ``test_opkg.yaml``):
.. code-block:: yaml
---
anchors:
environ: &env-def {environ_update: {LANGUAGE: C, LC_ALL: C}, check_rc: false}
test_cases:
- id: install_zlibdev
input:
name: zlib-dev
state: present
output:
msg: installed 1 package(s)
mocks:
run_command:
- command: [/testbin/opkg, --version]
environ: *env-def
rc: 0
out: ''
err: ''
- command: [/testbin/opkg, list-installed, zlib-dev]
environ: *env-def
rc: 0
out: ''
err: ''
- command: [/testbin/opkg, install, zlib-dev]
environ: *env-def
rc: 0
out: |
Installing zlib-dev (1.2.11-6) to root...
Downloading https://downloads.openwrt.org/releases/22.03.0/packages/mips_24kc/base/zlib-dev_1.2.11-6_mips_24kc.ipk
Installing zlib (1.2.11-6) to root...
Downloading https://downloads.openwrt.org/releases/22.03.0/packages/mips_24kc/base/zlib_1.2.11-6_mips_24kc.ipk
Configuring zlib.
Configuring zlib-dev.
err: ''
- command: [/testbin/opkg, list-installed, zlib-dev]
environ: *env-def
rc: 0
out: |
zlib-dev - 1.2.11-6
err: ''
- id: install_zlibdev_present
input:
name: zlib-dev
state: present
output:
msg: package(s) already present
mocks:
run_command:
- command: [/testbin/opkg, --version]
environ: *env-def
rc: 0
out: ''
err: ''
- command: [/testbin/opkg, list-installed, zlib-dev]
environ: *env-def
rc: 0
out: |
zlib-dev - 1.2.11-6
err: ''
TestCaseMocks Specifications
^^^^^^^^^^^^^^^^^^^^^^^^^^^^
The ``TestCaseMock`` subclass is free to define the expected data structure.
RunCommandMock Specification
""""""""""""""""""""""""""""
``RunCommandMock`` mocks can be specified with the key ``run_command`` and it expects a ``list`` in which elements follow the structure:
- ``command: Union[list, str]``
Mandatory. The command that is expected to be executed by the module. It corresponds to the parameter ``args`` of the ``AnsibleModule.run_command()`` call.
It can be either a list or a string, though the list form is generally recommended.
- ``environ: dict``
Mandatory. All other parameters passed to the ``AnsibleModule.run_command()`` call.
Most commonly used are ``environ_update`` and ``check_rc``.
Must include all parameters the Ansible module uses in the ``AnsibleModule.run_command()`` call, otherwise the test will fail.
- ``rc: int``
Mandatory. The return code for the command execution.
As per usual in bash scripting, a value of ``0`` means success, whereas any other number is an error code.
- ``out: str``
Mandatory. The *stdout* result of the command execution, as one single string containing zero or more lines.
- ``err: str``
Mandatory. The *stderr* result of the command execution, as one single string containing zero or more lines.
``UTHelper`` Reference
^^^^^^^^^^^^^^^^^^^^^^
.. py:module:: .uthelper
.. py:class:: UTHelper
A class to encapsulate unit tests.
.. py:staticmethod:: from_spec(ansible_module, test_module, test_spec, mocks=None)
Creates an ``UTHelper`` instance from a given test specification.
:param ansible_module: The Ansible module to be tested.
:type ansible_module: module
:param test_module: The test module.
:type test_module: module
:param test_spec: The test specification.
:type test_spec: dict
:param mocks: List of ``TestCaseMocks`` to be used during testing. Currently only ``RunCommandMock`` exists.
:type mocks: list or None
:return: An ``UTHelper`` instance.
:rtype: UTHelper
Example usage of ``from_spec()``:
.. code-block:: python
import sys
from ansible_collections.community.general.plugins.modules import ansible_module
from .uthelper import UTHelper, RunCommandMock
TEST_SPEC = dict(
test_cases=[
...
]
)
helper = UTHelper.from_spec(ansible_module, sys.modules[__name__], TEST_SPEC, mocks=[RunCommandMock])
.. py:staticmethod:: from_file(ansible_module, test_module, test_spec_filehandle, mocks=None)
Creates an ``UTHelper`` instance from a test specification file.
:param ansible_module: The Ansible module to be tested.
:type ansible_module: module
:param test_module: The test module.
:type test_module: module
:param test_spec_filehandle: A file handle to an file stream handle providing the test specification in YAML format.
:type test_spec_filehandle: file
:param mocks: List of ``TestCaseMocks`` to be used during testing. Currently only ``RunCommandMock`` exists.
:type mocks: list or None
:return: An ``UTHelper`` instance.
:rtype: UTHelper
Example usage of ``from_file()``:
.. code-block:: python
import sys
from ansible_collections.community.general.plugins.modules import ansible_module
from .uthelper import UTHelper, RunCommandMock
with open("test_spec.yaml", "r") as test_spec_filehandle:
helper = UTHelper.from_file(ansible_module, sys.modules[__name__], test_spec_filehandle, mocks=[RunCommandMock])
.. py:staticmethod:: from_module(ansible_module, test_module_name, mocks=None)
Creates an ``UTHelper`` instance from a given Ansible module and test module.
:param ansible_module: The Ansible module to be tested.
:type ansible_module: module
:param test_module_name: The name of the test module. It works if passed ``__name__``.
:type test_module_name: str
:param mocks: List of ``TestCaseMocks`` to be used during testing. Currently only ``RunCommandMock`` exists.
:type mocks: list or None
:return: An ``UTHelper`` instance.
:rtype: UTHelper
Example usage of ``from_module()``:
.. code-block:: python
from ansible_collections.community.general.plugins.modules import ansible_module
from .uthelper import UTHelper, RunCommandMock
# Example usage
helper = UTHelper.from_module(ansible_module, __name__, mocks=[RunCommandMock])
Creating TestCaseMocks
^^^^^^^^^^^^^^^^^^^^^^
To create a new ``TestCaseMock`` you must extend that class and implement the relevant parts:
.. code-block:: python
class ShrubberyMock(TestCaseMock):
# this name is mandatory, it is the name used in the test specification
name = "shrubbery"
def setup(self, mocker):
# perform setup, commonly using mocker to patch some other piece of code
...
def check(self, test_case, results):
# verify the tst execution met the expectations of the test case
# for example the function was called as many times as it should
...
def fixtures(self):
# returns a dict mapping names to pytest fixtures that should be used for the test case
# for example, in RunCommandMock it creates a fixture that patches AnsibleModule.get_bin_path
...
Caveats
^^^^^^^
Known issues/opportunities for improvement:
* Only one ``UTHelper`` per test module: UTHelper injects a test function with a fixed name into the module's namespace,
so placing a second ``UTHelper`` instance is going to overwrite the function created by the first one.
* Order of elements in module's namespace is not consistent across executions in Python 3.5, so if adding more tests to the test module
might make Test Helper add its function before or after the other test functions.
In the community.general collection the CI processes uses ``pytest-xdist`` to paralellize and distribute the tests,
and it requires the order of the tests to be consistent.
.. versionadded:: 7.5.0

View File

@@ -5,7 +5,7 @@
namespace: community
name: general
version: 10.5.0
version: 9.5.13
readme: README.md
authors:
- Ansible (https://github.com/ansible)

View File

@@ -3,7 +3,7 @@
# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
# SPDX-License-Identifier: GPL-3.0-or-later
requires_ansible: '>=2.15.0'
requires_ansible: '>=2.13.0'
action_groups:
consul:
- consul_agent_check
@@ -16,8 +16,6 @@ action_groups:
- consul_token
proxmox:
- proxmox
- proxmox_backup
- proxmox_backup_info
- proxmox_disk
- proxmox_domain_info
- proxmox_group_info
@@ -33,34 +31,6 @@ action_groups:
- proxmox_template
- proxmox_user_info
- proxmox_vm_info
keycloak:
- keycloak_authentication
- keycloak_authentication_required_actions
- keycloak_authz_authorization_scope
- keycloak_authz_custom_policy
- keycloak_authz_permission
- keycloak_authz_permission_info
- keycloak_client
- keycloak_client_rolemapping
- keycloak_client_rolescope
- keycloak_clientscope
- keycloak_clientscope_type
- keycloak_clientsecret_info
- keycloak_clientsecret_regenerate
- keycloak_clienttemplate
- keycloak_component
- keycloak_component_info
- keycloak_group
- keycloak_identity_provider
- keycloak_realm
- keycloak_realm_key
- keycloak_realm_keys_metadata_info
- keycloak_realm_rolemapping
- keycloak_role
- keycloak_user
- keycloak_user_federation
- keycloak_user_rolemapping
- keycloak_userprofile
plugin_routing:
callback:
actionable:
@@ -74,7 +44,7 @@ plugin_routing:
warning_text: Use the 'default' callback plugin with 'display_skipped_hosts
= no' option.
hipchat:
tombstone:
deprecation:
removal_version: 10.0.0
warning_text: The hipchat service has been discontinued and the self-hosted variant has been End of Life since 2020.
osx_say:
@@ -84,10 +54,6 @@ plugin_routing:
removal_version: 2.0.0
warning_text: Use the 'default' callback plugin with 'display_failed_stderr
= yes' option.
yaml:
deprecation:
removal_version: 13.0.0
warning_text: The plugin has been superseded by the the option `result_format=yaml` in callback plugin ansible.builtin.default from ansible-core 2.13 onwards.
connection:
docker:
redirect: community.docker.docker
@@ -105,64 +71,140 @@ plugin_routing:
nios_next_network:
redirect: infoblox.nios_modules.nios_next_network
modules:
consul_acl:
deprecation:
removal_version: 10.0.0
warning_text: Use community.general.consul_token and/or community.general.consul_policy instead.
hipchat:
deprecation:
removal_version: 11.0.0
warning_text: The hipchat service has been discontinued and the self-hosted variant has been End of Life since 2020.
rax_cbs_attachments:
tombstone:
removal_version: 9.0.0
warning_text: This module relied on the deprecated package pyrax.
rax_cbs:
tombstone:
removal_version: 9.0.0
warning_text: This module relied on the deprecated package pyrax.
rax_cdb_database:
tombstone:
removal_version: 9.0.0
warning_text: This module relied on the deprecated package pyrax.
rax_cdb_user:
tombstone:
removal_version: 9.0.0
warning_text: This module relied on the deprecated package pyrax.
rax_cdb:
tombstone:
removal_version: 9.0.0
warning_text: This module relied on the deprecated package pyrax.
rax_clb_nodes:
tombstone:
removal_version: 9.0.0
warning_text: This module relied on the deprecated package pyrax.
rax_clb_ssl:
tombstone:
removal_version: 9.0.0
warning_text: This module relied on the deprecated package pyrax.
rax_clb:
tombstone:
removal_version: 9.0.0
warning_text: This module relied on the deprecated package pyrax.
rax_dns_record:
tombstone:
removal_version: 9.0.0
warning_text: This module relied on the deprecated package pyrax.
rax_dns:
tombstone:
removal_version: 9.0.0
warning_text: This module relied on the deprecated package pyrax.
rax_facts:
tombstone:
removal_version: 9.0.0
warning_text: This module relied on the deprecated package pyrax.
rax_files_objects:
tombstone:
removal_version: 9.0.0
warning_text: This module relied on the deprecated package pyrax.
rax_files:
tombstone:
removal_version: 9.0.0
warning_text: This module relied on the deprecated package pyrax.
rax_identity:
tombstone:
removal_version: 9.0.0
warning_text: This module relied on the deprecated package pyrax.
rax_keypair:
tombstone:
removal_version: 9.0.0
warning_text: This module relied on the deprecated package pyrax.
rax_meta:
tombstone:
removal_version: 9.0.0
warning_text: This module relied on the deprecated package pyrax.
rax_mon_alarm:
tombstone:
removal_version: 9.0.0
warning_text: This module relied on the deprecated package pyrax.
rax:
tombstone:
removal_version: 9.0.0
warning_text: This module relied on the deprecated package pyrax.
rax_mon_check:
tombstone:
removal_version: 9.0.0
warning_text: This module relied on the deprecated package pyrax.
rax_mon_entity:
tombstone:
removal_version: 9.0.0
warning_text: This module relied on the deprecated package pyrax.
rax_mon_notification_plan:
tombstone:
removal_version: 9.0.0
warning_text: This module relied on the deprecated package pyrax.
rax_mon_notification:
tombstone:
removal_version: 9.0.0
warning_text: This module relied on the deprecated package pyrax.
rax_network:
tombstone:
removal_version: 9.0.0
warning_text: This module relied on the deprecated package pyrax.
rax_queue:
tombstone:
removal_version: 9.0.0
warning_text: This module relied on the deprecated package pyrax.
rax_scaling_group:
tombstone:
removal_version: 9.0.0
warning_text: This module relied on the deprecated package pyrax.
rax_scaling_policy:
tombstone:
removal_version: 9.0.0
warning_text: This module relied on the deprecated package pyrax.
rhn_channel:
deprecation:
removal_version: 10.0.0
warning_text: RHN is EOL, please contact the community.general maintainers
if still using this; see the module documentation for more details.
rhn_register:
deprecation:
removal_version: 10.0.0
warning_text: RHN is EOL, please contact the community.general maintainers
if still using this; see the module documentation for more details.
stackdriver:
tombstone:
removal_version: 9.0.0
warning_text: This module relied on HTTPS APIs that do not exist anymore,
and any new development in the direction of providing an alternative should
happen in the context of the google.cloud collection.
ali_instance_facts:
tombstone:
removal_version: 3.0.0
warning_text: Use community.general.ali_instance_info instead.
atomic_container:
deprecation:
removal_version: 13.0.0
warning_text: Project Atomic was sunset by the end of 2019.
atomic_host:
deprecation:
removal_version: 13.0.0
warning_text: Project Atomic was sunset by the end of 2019.
atomic_image:
deprecation:
removal_version: 13.0.0
warning_text: Project Atomic was sunset by the end of 2019.
cisco_spark:
redirect: community.general.cisco_webex
clc_alert_policy:
deprecation:
removal_version: 11.0.0
warning_text: CenturyLink Cloud services went EOL in September 2023.
clc_blueprint_package:
deprecation:
removal_version: 11.0.0
warning_text: CenturyLink Cloud services went EOL in September 2023.
clc_firewall_policy:
deprecation:
removal_version: 11.0.0
warning_text: CenturyLink Cloud services went EOL in September 2023.
clc_group:
deprecation:
removal_version: 11.0.0
warning_text: CenturyLink Cloud services went EOL in September 2023.
clc_loadbalancer:
deprecation:
removal_version: 11.0.0
warning_text: CenturyLink Cloud services went EOL in September 2023.
clc_modify_server:
deprecation:
removal_version: 11.0.0
warning_text: CenturyLink Cloud services went EOL in September 2023.
clc_publicip:
deprecation:
removal_version: 11.0.0
warning_text: CenturyLink Cloud services went EOL in September 2023.
clc_server:
deprecation:
removal_version: 11.0.0
warning_text: CenturyLink Cloud services went EOL in September 2023.
clc_server_snapshot:
deprecation:
removal_version: 11.0.0
warning_text: CenturyLink Cloud services went EOL in September 2023.
consul_acl:
tombstone:
removal_version: 10.0.0
warning_text: Use community.general.consul_token and/or community.general.consul_policy instead.
docker_compose:
redirect: community.docker.docker_compose
docker_config:
@@ -217,10 +259,6 @@ plugin_routing:
redirect: community.docker.docker_volume
docker_volume_info:
redirect: community.docker.docker_volume_info
facter:
deprecation:
removal_version: 12.0.0
warning_text: Use community.general.facter_facts instead.
flowdock:
tombstone:
removal_version: 9.0.0
@@ -314,10 +352,6 @@ plugin_routing:
redirect: community.hrobot.firewall
hetzner_firewall_info:
redirect: community.hrobot.firewall_info
hipchat:
deprecation:
removal_version: 11.0.0
warning_text: The hipchat service has been discontinued and the self-hosted variant has been End of Life since 2020.
hpilo_facts:
tombstone:
removal_version: 3.0.0
@@ -639,26 +673,6 @@ plugin_routing:
redirect: community.postgresql.postgresql_user
postgresql_user_obj_stat_info:
redirect: community.postgresql.postgresql_user_obj_stat_info
profitbricks:
deprecation:
removal_version: 11.0.0
warning_text: Supporting library is unsupported since 2021.
profitbricks_datacenter:
deprecation:
removal_version: 11.0.0
warning_text: Supporting library is unsupported since 2021.
profitbricks_nic:
deprecation:
removal_version: 11.0.0
warning_text: Supporting library is unsupported since 2021.
profitbricks_volume:
deprecation:
removal_version: 11.0.0
warning_text: Supporting library is unsupported since 2021.
profitbricks_volume_attachments:
deprecation:
removal_version: 11.0.0
warning_text: Supporting library is unsupported since 2021.
purefa_facts:
tombstone:
removal_version: 3.0.0
@@ -671,122 +685,10 @@ plugin_routing:
tombstone:
removal_version: 3.0.0
warning_text: Use community.general.python_requirements_info instead.
rax_cbs_attachments:
tombstone:
removal_version: 9.0.0
warning_text: This module relied on the deprecated package pyrax.
rax_cbs:
tombstone:
removal_version: 9.0.0
warning_text: This module relied on the deprecated package pyrax.
rax_cdb_database:
tombstone:
removal_version: 9.0.0
warning_text: This module relied on the deprecated package pyrax.
rax_cdb_user:
tombstone:
removal_version: 9.0.0
warning_text: This module relied on the deprecated package pyrax.
rax_cdb:
tombstone:
removal_version: 9.0.0
warning_text: This module relied on the deprecated package pyrax.
rax_clb_nodes:
tombstone:
removal_version: 9.0.0
warning_text: This module relied on the deprecated package pyrax.
rax_clb_ssl:
tombstone:
removal_version: 9.0.0
warning_text: This module relied on the deprecated package pyrax.
rax_clb:
tombstone:
removal_version: 9.0.0
warning_text: This module relied on the deprecated package pyrax.
rax_dns_record:
tombstone:
removal_version: 9.0.0
warning_text: This module relied on the deprecated package pyrax.
rax_dns:
tombstone:
removal_version: 9.0.0
warning_text: This module relied on the deprecated package pyrax.
rax_facts:
tombstone:
removal_version: 9.0.0
warning_text: This module relied on the deprecated package pyrax.
rax_files_objects:
tombstone:
removal_version: 9.0.0
warning_text: This module relied on the deprecated package pyrax.
rax_files:
tombstone:
removal_version: 9.0.0
warning_text: This module relied on the deprecated package pyrax.
rax_identity:
tombstone:
removal_version: 9.0.0
warning_text: This module relied on the deprecated package pyrax.
rax_keypair:
tombstone:
removal_version: 9.0.0
warning_text: This module relied on the deprecated package pyrax.
rax_meta:
tombstone:
removal_version: 9.0.0
warning_text: This module relied on the deprecated package pyrax.
rax_mon_alarm:
tombstone:
removal_version: 9.0.0
warning_text: This module relied on the deprecated package pyrax.
rax:
tombstone:
removal_version: 9.0.0
warning_text: This module relied on the deprecated package pyrax.
rax_mon_check:
tombstone:
removal_version: 9.0.0
warning_text: This module relied on the deprecated package pyrax.
rax_mon_entity:
tombstone:
removal_version: 9.0.0
warning_text: This module relied on the deprecated package pyrax.
rax_mon_notification_plan:
tombstone:
removal_version: 9.0.0
warning_text: This module relied on the deprecated package pyrax.
rax_mon_notification:
tombstone:
removal_version: 9.0.0
warning_text: This module relied on the deprecated package pyrax.
rax_network:
tombstone:
removal_version: 9.0.0
warning_text: This module relied on the deprecated package pyrax.
rax_queue:
tombstone:
removal_version: 9.0.0
warning_text: This module relied on the deprecated package pyrax.
rax_scaling_group:
tombstone:
removal_version: 9.0.0
warning_text: This module relied on the deprecated package pyrax.
rax_scaling_policy:
tombstone:
removal_version: 9.0.0
warning_text: This module relied on the deprecated package pyrax.
redfish_facts:
tombstone:
removal_version: 3.0.0
warning_text: Use community.general.redfish_info instead.
rhn_channel:
tombstone:
removal_version: 10.0.0
warning_text: RHN is EOL.
rhn_register:
tombstone:
removal_version: 10.0.0
warning_text: RHN is EOL.
sapcar_extract:
redirect: community.sap_libs.sapcar_extract
sap_task_list_execute:
@@ -819,26 +721,6 @@ plugin_routing:
tombstone:
removal_version: 3.0.0
warning_text: Use community.general.scaleway_volume_info instead.
sensu_check:
deprecation:
removal_version: 13.0.0
warning_text: Sensu Core and Sensu Enterprise products have been End of Life since 2019/20.
sensu_client:
deprecation:
removal_version: 13.0.0
warning_text: Sensu Core and Sensu Enterprise products have been End of Life since 2019/20.
sensu_handler:
deprecation:
removal_version: 13.0.0
warning_text: Sensu Core and Sensu Enterprise products have been End of Life since 2019/20.
sensu_silence:
deprecation:
removal_version: 13.0.0
warning_text: Sensu Core and Sensu Enterprise products have been End of Life since 2019/20.
sensu_subscription:
deprecation:
removal_version: 13.0.0
warning_text: Sensu Core and Sensu Enterprise products have been End of Life since 2019/20.
sf_account_manager:
tombstone:
removal_version: 2.0.0
@@ -863,12 +745,6 @@ plugin_routing:
tombstone:
removal_version: 3.0.0
warning_text: Use community.general.smartos_image_info instead.
stackdriver:
tombstone:
removal_version: 9.0.0
warning_text: This module relied on HTTPS APIs that do not exist anymore,
and any new development in the direction of providing an alternative should
happen in the context of the google.cloud collection.
vertica_facts:
tombstone:
removal_version: 3.0.0
@@ -903,6 +779,11 @@ plugin_routing:
removal_version: 3.0.0
warning_text: Use community.general.xenserver_guest_info instead.
doc_fragments:
rackspace:
tombstone:
removal_version: 9.0.0
warning_text: This doc fragment was used by rax modules, that relied on the deprecated
package pyrax.
_gcp:
redirect: community.google._gcp
docker:
@@ -917,16 +798,11 @@ plugin_routing:
redirect: infoblox.nios_modules.nios
postgresql:
redirect: community.postgresql.postgresql
purestorage:
deprecation:
removal_version: 12.0.0
warning_text: The modules for purestorage were removed in community.general 3.0.0, this document fragment was left behind.
rackspace:
module_utils:
rax:
tombstone:
removal_version: 9.0.0
warning_text: This doc fragment was used by rax modules, that relied on the deprecated
package pyrax.
module_utils:
warning_text: This module util relied on the deprecated package pyrax.
docker.common:
redirect: community.docker.common
docker.swarm:
@@ -945,14 +821,6 @@ plugin_routing:
redirect: infoblox.nios_modules.api
postgresql:
redirect: community.postgresql.postgresql
pure:
deprecation:
removal_version: 12.0.0
warning_text: The modules for purestorage were removed in community.general 3.0.0, this module util was left behind.
rax:
tombstone:
removal_version: 9.0.0
warning_text: This module util relied on the deprecated package pyrax.
remote_management.dellemc.dellemc_idrac:
redirect: dellemc.openmanage.dellemc_idrac
remote_management.dellemc.ome:

38
noxfile.py Normal file
View File

@@ -0,0 +1,38 @@
# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
# SPDX-License-Identifier: GPL-3.0-or-later
# SPDX-FileCopyrightText: 2025 Felix Fontein <felix@fontein.de>
# /// script
# dependencies = ["nox>=2025.02.09", "antsibull-nox"]
# ///
import sys
import nox
try:
import antsibull_nox
except ImportError:
print("You need to install antsibull-nox in the same Python environment as nox.")
sys.exit(1)
antsibull_nox.load_antsibull_nox_toml()
@nox.session(name="aliases", python=False, default=True)
def aliases(session: nox.Session) -> None:
session.run("python", "tests/sanity/extra/aliases.py")
@nox.session(name="botmeta", default=True)
def botmeta(session: nox.Session) -> None:
session.install("PyYAML", "voluptuous")
session.run("python", "tests/sanity/extra/botmeta.py")
# Allow to run the noxfile with `python noxfile.py`, `pipx run noxfile.py`, or similar.
# Requires nox >= 2025.02.09
if __name__ == "__main__":
nox.main()

View File

@@ -3,7 +3,8 @@
# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
# SPDX-License-Identifier: GPL-3.0-or-later
from __future__ import annotations
from __future__ import absolute_import, division, print_function
__metaclass__ = type
import time
@@ -21,33 +22,25 @@ class ActionModule(ActionBase):
_VALID_ARGS = frozenset(('path', 'state', 'table', 'noflush', 'counters', 'modprobe', 'ip_version', 'wait'))
DEFAULT_SUDOABLE = True
@staticmethod
def msg_error__async_and_poll_not_zero(task_poll, task_async, max_timeout):
return (
"This module doesn't support async>0 and poll>0 when its 'state' param "
"is set to 'restored'. To enable its rollback feature (that needs the "
"module to run asynchronously on the remote), please set task attribute "
f"'poll' (={task_poll}) to 0, and 'async' (={task_async}) to a value >2 and not greater than "
f"'ansible_timeout' (={max_timeout}) (recommended).")
@staticmethod
def msg_warning__no_async_is_no_rollback(task_poll, task_async, max_timeout):
return (
"Attempts to restore iptables state without rollback in case of mistake "
"may lead the ansible controller to loose access to the hosts and never "
"regain it before fixing firewall rules through a serial console, or any "
f"other way except SSH. Please set task attribute 'poll' (={task_poll}) to 0, and "
f"'async' (={task_async}) to a value >2 and not greater than 'ansible_timeout' (={max_timeout}) "
"(recommended).")
@staticmethod
def msg_warning__async_greater_than_timeout(task_poll, task_async, max_timeout):
return (
"You attempt to restore iptables state with rollback in case of mistake, "
"but with settings that will lead this rollback to happen AFTER that the "
"controller will reach its own timeout. Please set task attribute 'poll' "
f"(={task_poll}) to 0, and 'async' (={task_async}) to a value >2 and not greater than "
f"'ansible_timeout' (={max_timeout}) (recommended).")
MSG_ERROR__ASYNC_AND_POLL_NOT_ZERO = (
"This module doesn't support async>0 and poll>0 when its 'state' param "
"is set to 'restored'. To enable its rollback feature (that needs the "
"module to run asynchronously on the remote), please set task attribute "
"'poll' (=%s) to 0, and 'async' (=%s) to a value >2 and not greater than "
"'ansible_timeout' (=%s) (recommended).")
MSG_WARNING__NO_ASYNC_IS_NO_ROLLBACK = (
"Attempts to restore iptables state without rollback in case of mistake "
"may lead the ansible controller to loose access to the hosts and never "
"regain it before fixing firewall rules through a serial console, or any "
"other way except SSH. Please set task attribute 'poll' (=%s) to 0, and "
"'async' (=%s) to a value >2 and not greater than 'ansible_timeout' (=%s) "
"(recommended).")
MSG_WARNING__ASYNC_GREATER_THAN_TIMEOUT = (
"You attempt to restore iptables state with rollback in case of mistake, "
"but with settings that will lead this rollback to happen AFTER that the "
"controller will reach its own timeout. Please set task attribute 'poll' "
"(=%s) to 0, and 'async' (=%s) to a value >2 and not greater than "
"'ansible_timeout' (=%s) (recommended).")
def _async_result(self, async_status_args, task_vars, timeout):
'''
@@ -102,18 +95,18 @@ class ActionModule(ActionBase):
if module_args.get('state', None) == 'restored':
if not wrap_async:
if not check_mode:
display.warning(self.msg_error__async_and_poll_not_zero(
display.warning(self.MSG_WARNING__NO_ASYNC_IS_NO_ROLLBACK % (
task_poll,
task_async,
max_timeout))
elif task_poll:
raise AnsibleActionFail(self.msg_warning__no_async_is_no_rollback(
raise AnsibleActionFail(self.MSG_ERROR__ASYNC_AND_POLL_NOT_ZERO % (
task_poll,
task_async,
max_timeout))
else:
if task_async > max_timeout and not check_mode:
display.warning(self.msg_warning__async_greater_than_timeout(
display.warning(self.MSG_WARNING__ASYNC_GREATER_THAN_TIMEOUT % (
task_poll,
task_async,
max_timeout))
@@ -126,10 +119,10 @@ class ActionModule(ActionBase):
# remote and local sides (if not the same, make the loop
# longer on the controller); and set a backup file path.
module_args['_timeout'] = task_async
module_args['_back'] = f'{async_dir}/iptables.state'
module_args['_back'] = '%s/iptables.state' % async_dir
async_status_args = dict(mode='status')
confirm_cmd = f"rm -f {module_args['_back']}"
starter_cmd = f"touch {module_args['_back']}.starter"
confirm_cmd = 'rm -f %s' % module_args['_back']
starter_cmd = 'touch %s.starter' % module_args['_back']
remaining_time = max(task_async, max_timeout)
# do work!

View File

@@ -5,8 +5,9 @@
# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
# SPDX-License-Identifier: GPL-3.0-or-later
from __future__ import annotations
from __future__ import (absolute_import, division, print_function)
__metaclass__ = type
from ansible.errors import AnsibleError, AnsibleConnectionFailure
from ansible.module_utils.common.text.converters import to_native, to_text
@@ -17,10 +18,6 @@ from ansible.utils.display import Display
display = Display()
def fmt(mapping, key):
return to_native(mapping[key]).strip()
class TimedOutException(Exception):
pass
@@ -87,26 +84,31 @@ class ActionModule(ActionBase):
def get_distribution(self, task_vars):
# FIXME: only execute the module if we don't already have the facts we need
distribution = {}
display.debug(f'{self._task.action}: running setup module to get distribution')
display.debug('{action}: running setup module to get distribution'.format(action=self._task.action))
module_output = self._execute_module(
task_vars=task_vars,
module_name='ansible.legacy.setup',
module_args={'gather_subset': 'min'})
try:
if module_output.get('failed', False):
raise AnsibleError(f"Failed to determine system distribution. {fmt(module_output, 'module_stdout')}, {fmt(module_output, 'module_stderr')}")
raise AnsibleError('Failed to determine system distribution. {0}, {1}'.format(
to_native(module_output['module_stdout']).strip(),
to_native(module_output['module_stderr']).strip()))
distribution['name'] = module_output['ansible_facts']['ansible_distribution'].lower()
distribution['version'] = to_text(
module_output['ansible_facts']['ansible_distribution_version'].split('.')[0])
distribution['family'] = to_text(module_output['ansible_facts']['ansible_os_family'].lower())
display.debug(f"{self._task.action}: distribution: {distribution}")
display.debug("{action}: distribution: {dist}".format(action=self._task.action, dist=distribution))
return distribution
except KeyError as ke:
raise AnsibleError(f'Failed to get distribution information. Missing "{ke.args[0]}" in output.')
raise AnsibleError('Failed to get distribution information. Missing "{0}" in output.'.format(ke.args[0]))
def get_shutdown_command(self, task_vars, distribution):
def find_command(command, find_search_paths):
display.debug(f'{self._task.action}: running find module looking in {find_search_paths} to get path for "{command}"')
display.debug('{action}: running find module looking in {paths} to get path for "{command}"'.format(
action=self._task.action,
command=command,
paths=find_search_paths))
find_result = self._execute_module(
task_vars=task_vars,
# prevent collection search by calling with ansible.legacy (still allows library/ override of find)
@@ -128,37 +130,42 @@ class ActionModule(ActionBase):
if is_string(search_paths):
search_paths = [search_paths]
# Error if we didn't get a list
err_msg = "'search_paths' must be a string or flat list of strings, got {0}"
try:
incorrect_type = any(not is_string(x) for x in search_paths)
if not isinstance(search_paths, list) or incorrect_type:
raise TypeError
except TypeError:
# Error if we didn't get a list
err_msg = f"'search_paths' must be a string or flat list of strings, got {search_paths}"
raise AnsibleError(err_msg)
raise AnsibleError(err_msg.format(search_paths))
full_path = find_command(shutdown_bin, search_paths) # find the path to the shutdown command
if not full_path: # if we could not find the shutdown command
# tell the user we will try with systemd
display.vvv(f'Unable to find command "{shutdown_bin}" in search paths: {search_paths}, will attempt a shutdown using systemd directly.')
display.vvv('Unable to find command "{0}" in search paths: {1}, will attempt a shutdown using systemd '
'directly.'.format(shutdown_bin, search_paths)) # tell the user we will try with systemd
systemctl_search_paths = ['/bin', '/usr/bin']
full_path = find_command('systemctl', systemctl_search_paths) # find the path to the systemctl command
if not full_path: # if we couldn't find systemctl
raise AnsibleError(
f'Could not find command "{shutdown_bin}" in search paths: {search_paths} or systemctl'
f' command in search paths: {systemctl_search_paths}, unable to shutdown.') # we give up here
'Could not find command "{0}" in search paths: {1} or systemctl command in search paths: {2}, unable to shutdown.'.
format(shutdown_bin, search_paths, systemctl_search_paths)) # we give up here
else:
return f"{full_path[0]} poweroff" # done, since we cannot use args with systemd shutdown
return "{0} poweroff".format(full_path[0]) # done, since we cannot use args with systemd shutdown
# systemd case taken care of, here we add args to the command
args = self._get_value_from_facts('SHUTDOWN_COMMAND_ARGS', distribution, 'DEFAULT_SHUTDOWN_COMMAND_ARGS')
# Convert seconds to minutes. If less that 60, set it to 0.
delay_sec = self.delay
shutdown_message = self._task.args.get('msg', self.DEFAULT_SHUTDOWN_MESSAGE)
af = args.format(delay_sec=delay_sec, delay_min=delay_sec // 60, message=shutdown_message)
return f'{full_path[0]} {af}'
return '{0} {1}'. \
format(
full_path[0],
args.format(
delay_sec=delay_sec,
delay_min=delay_sec // 60,
message=shutdown_message
)
)
def perform_shutdown(self, task_vars, distribution):
result = {}
@@ -167,8 +174,9 @@ class ActionModule(ActionBase):
self.cleanup(force=True)
try:
display.vvv(f"{self._task.action}: shutting down server...")
display.debug(f"{self._task.action}: shutting down server with command '{shutdown_command_exec}'")
display.vvv("{action}: shutting down server...".format(action=self._task.action))
display.debug("{action}: shutting down server with command '{command}'".
format(action=self._task.action, command=shutdown_command_exec))
if self._play_context.check_mode:
shutdown_result['rc'] = 0
else:
@@ -176,13 +184,16 @@ class ActionModule(ActionBase):
except AnsibleConnectionFailure as e:
# If the connection is closed too quickly due to the system being shutdown, carry on
display.debug(
f'{self._task.action}: AnsibleConnectionFailure caught and handled: {e}')
'{action}: AnsibleConnectionFailure caught and handled: {error}'.format(action=self._task.action,
error=to_text(e)))
shutdown_result['rc'] = 0
if shutdown_result['rc'] != 0:
result['failed'] = True
result['shutdown'] = False
result['msg'] = f"Shutdown command failed. Error was {fmt(shutdown_result, 'stdout')}, {fmt(shutdown_result, 'stderr')}"
result['msg'] = "Shutdown command failed. Error was {stdout}, {stderr}".format(
stdout=to_native(shutdown_result['stdout'].strip()),
stderr=to_native(shutdown_result['stderr'].strip()))
return result
result['failed'] = False
@@ -195,7 +206,7 @@ class ActionModule(ActionBase):
# If running with local connection, fail so we don't shutdown ourself
if self._connection.transport == 'local' and (not self._play_context.check_mode):
msg = f'Running {self._task.action} with local connection would shutdown the control node.'
msg = 'Running {0} with local connection would shutdown the control node.'.format(self._task.action)
return {'changed': False, 'elapsed': 0, 'shutdown': False, 'failed': True, 'msg': msg}
if task_vars is None:

View File

@@ -2,88 +2,92 @@
# Copyright (c) 2018, Ansible Project
# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
# SPDX-License-Identifier: GPL-3.0-or-later
from __future__ import annotations
from __future__ import (absolute_import, division, print_function)
__metaclass__ = type
DOCUMENTATION = r"""
name: doas
short_description: Do As user
description:
- This become plugins allows your remote/login user to execute commands as another user using the C(doas) utility.
author: Ansible Core Team
options:
become_user:
description: User you 'become' to execute the task.
type: string
ini:
- section: privilege_escalation
key: become_user
- section: doas_become_plugin
key: user
vars:
- name: ansible_become_user
- name: ansible_doas_user
env:
- name: ANSIBLE_BECOME_USER
- name: ANSIBLE_DOAS_USER
become_exe:
description: C(doas) executable.
type: string
default: doas
ini:
- section: privilege_escalation
key: become_exe
- section: doas_become_plugin
key: executable
vars:
- name: ansible_become_exe
- name: ansible_doas_exe
env:
- name: ANSIBLE_BECOME_EXE
- name: ANSIBLE_DOAS_EXE
become_flags:
description: Options to pass to C(doas).
type: string
default: ''
ini:
- section: privilege_escalation
key: become_flags
- section: doas_become_plugin
key: flags
vars:
- name: ansible_become_flags
- name: ansible_doas_flags
env:
- name: ANSIBLE_BECOME_FLAGS
- name: ANSIBLE_DOAS_FLAGS
become_pass:
description: Password for C(doas) prompt.
type: string
required: false
vars:
- name: ansible_become_password
- name: ansible_become_pass
- name: ansible_doas_pass
env:
- name: ANSIBLE_BECOME_PASS
- name: ANSIBLE_DOAS_PASS
ini:
- section: doas_become_plugin
key: password
prompt_l10n:
DOCUMENTATION = '''
name: doas
short_description: Do As user
description:
- List of localized strings to match for prompt detection.
- If empty we will use the built in one.
type: list
elements: string
default: []
ini:
- section: doas_become_plugin
key: localized_prompts
vars:
- name: ansible_doas_prompt_l10n
env:
- name: ANSIBLE_DOAS_PROMPT_L10N
"""
- This become plugins allows your remote/login user to execute commands as another user via the doas utility.
author: Ansible Core Team
options:
become_user:
description: User you 'become' to execute the task.
type: string
ini:
- section: privilege_escalation
key: become_user
- section: doas_become_plugin
key: user
vars:
- name: ansible_become_user
- name: ansible_doas_user
env:
- name: ANSIBLE_BECOME_USER
- name: ANSIBLE_DOAS_USER
become_exe:
description: Doas executable.
type: string
default: doas
ini:
- section: privilege_escalation
key: become_exe
- section: doas_become_plugin
key: executable
vars:
- name: ansible_become_exe
- name: ansible_doas_exe
env:
- name: ANSIBLE_BECOME_EXE
- name: ANSIBLE_DOAS_EXE
become_flags:
description: Options to pass to doas.
type: string
default: ''
ini:
- section: privilege_escalation
key: become_flags
- section: doas_become_plugin
key: flags
vars:
- name: ansible_become_flags
- name: ansible_doas_flags
env:
- name: ANSIBLE_BECOME_FLAGS
- name: ANSIBLE_DOAS_FLAGS
become_pass:
description: Password for doas prompt.
type: string
required: false
vars:
- name: ansible_become_password
- name: ansible_become_pass
- name: ansible_doas_pass
env:
- name: ANSIBLE_BECOME_PASS
- name: ANSIBLE_DOAS_PASS
ini:
- section: doas_become_plugin
key: password
prompt_l10n:
description:
- List of localized strings to match for prompt detection.
- If empty we will use the built in one.
type: list
elements: string
default: []
ini:
- section: doas_become_plugin
key: localized_prompts
vars:
- name: ansible_doas_prompt_l10n
env:
- name: ANSIBLE_DOAS_PROMPT_L10N
notes:
- This become plugin does not work when connection pipelining is enabled. With ansible-core 2.19+, using it automatically
disables pipelining. On ansible-core 2.18 and before, pipelining must explicitly be disabled by the user.
'''
import re
@@ -99,6 +103,10 @@ class BecomeModule(BecomeBase):
fail = ('Permission denied',)
missing = ('Authorization required',)
# See https://github.com/ansible-collections/community.general/issues/9977,
# https://github.com/ansible/ansible/pull/78111
pipelining = False
def check_password_prompt(self, b_output):
''' checks if the expected password prompt exists in b_output '''
@@ -124,9 +132,9 @@ class BecomeModule(BecomeBase):
flags += ' -n'
become_user = self.get_option('become_user')
user = f'-u {become_user}' if become_user else ''
user = '-u %s' % (become_user) if become_user else ''
success_cmd = self._build_success_command(cmd, shell, noexe=True)
executable = getattr(shell, 'executable', shell.SHELL_FAMILY)
return f'{become_exe} {flags} {user} {executable} -c {success_cmd}'
return '%s %s %s %s -c %s' % (become_exe, flags, user, executable, success_cmd)

View File

@@ -2,74 +2,75 @@
# Copyright (c) 2018, Ansible Project
# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
# SPDX-License-Identifier: GPL-3.0-or-later
from __future__ import annotations
from __future__ import (absolute_import, division, print_function)
__metaclass__ = type
DOCUMENTATION = r"""
name: dzdo
short_description: Centrify's Direct Authorize
description:
- This become plugins allows your remote/login user to execute commands as another user using the C(dzdo) utility.
author: Ansible Core Team
options:
become_user:
description: User you 'become' to execute the task.
type: string
ini:
- section: privilege_escalation
key: become_user
- section: dzdo_become_plugin
key: user
vars:
- name: ansible_become_user
- name: ansible_dzdo_user
env:
- name: ANSIBLE_BECOME_USER
- name: ANSIBLE_DZDO_USER
become_exe:
description: C(dzdo) executable.
type: string
default: dzdo
ini:
- section: privilege_escalation
key: become_exe
- section: dzdo_become_plugin
key: executable
vars:
- name: ansible_become_exe
- name: ansible_dzdo_exe
env:
- name: ANSIBLE_BECOME_EXE
- name: ANSIBLE_DZDO_EXE
become_flags:
description: Options to pass to C(dzdo).
type: string
default: -H -S -n
ini:
- section: privilege_escalation
key: become_flags
- section: dzdo_become_plugin
key: flags
vars:
- name: ansible_become_flags
- name: ansible_dzdo_flags
env:
- name: ANSIBLE_BECOME_FLAGS
- name: ANSIBLE_DZDO_FLAGS
become_pass:
description: Options to pass to C(dzdo).
type: string
required: false
vars:
- name: ansible_become_password
- name: ansible_become_pass
- name: ansible_dzdo_pass
env:
- name: ANSIBLE_BECOME_PASS
- name: ANSIBLE_DZDO_PASS
ini:
- section: dzdo_become_plugin
key: password
"""
DOCUMENTATION = '''
name: dzdo
short_description: Centrify's Direct Authorize
description:
- This become plugins allows your remote/login user to execute commands as another user via the dzdo utility.
author: Ansible Core Team
options:
become_user:
description: User you 'become' to execute the task.
type: string
ini:
- section: privilege_escalation
key: become_user
- section: dzdo_become_plugin
key: user
vars:
- name: ansible_become_user
- name: ansible_dzdo_user
env:
- name: ANSIBLE_BECOME_USER
- name: ANSIBLE_DZDO_USER
become_exe:
description: Dzdo executable.
type: string
default: dzdo
ini:
- section: privilege_escalation
key: become_exe
- section: dzdo_become_plugin
key: executable
vars:
- name: ansible_become_exe
- name: ansible_dzdo_exe
env:
- name: ANSIBLE_BECOME_EXE
- name: ANSIBLE_DZDO_EXE
become_flags:
description: Options to pass to dzdo.
type: string
default: -H -S -n
ini:
- section: privilege_escalation
key: become_flags
- section: dzdo_become_plugin
key: flags
vars:
- name: ansible_become_flags
- name: ansible_dzdo_flags
env:
- name: ANSIBLE_BECOME_FLAGS
- name: ANSIBLE_DZDO_FLAGS
become_pass:
description: Options to pass to dzdo.
type: string
required: false
vars:
- name: ansible_become_password
- name: ansible_become_pass
- name: ansible_dzdo_pass
env:
- name: ANSIBLE_BECOME_PASS
- name: ANSIBLE_DZDO_PASS
ini:
- section: dzdo_become_plugin
key: password
'''
from ansible.plugins.become import BecomeBase
@@ -91,10 +92,10 @@ class BecomeModule(BecomeBase):
flags = self.get_option('become_flags')
if self.get_option('become_pass'):
self.prompt = f'[dzdo via ansible, key={self._id}] password:'
flags = f"{flags.replace('-n', '')} -p \"{self.prompt}\""
self.prompt = '[dzdo via ansible, key=%s] password:' % self._id
flags = '%s -p "%s"' % (flags.replace('-n', ''), self.prompt)
become_user = self.get_option('become_user')
user = f'-u {become_user}' if become_user else ''
user = '-u %s' % (become_user) if become_user else ''
return f"{becomecmd} {flags} {user} {self._build_success_command(cmd, shell)}"
return ' '.join([becomecmd, flags, user, self._build_success_command(cmd, shell)])

View File

@@ -2,89 +2,90 @@
# Copyright (c) 2018, Ansible Project
# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
# SPDX-License-Identifier: GPL-3.0-or-later
from __future__ import annotations
from __future__ import (absolute_import, division, print_function)
__metaclass__ = type
DOCUMENTATION = r"""
name: ksu
short_description: Kerberos substitute user
description:
- This become plugins allows your remote/login user to execute commands as another user using the C(ksu) utility.
author: Ansible Core Team
options:
become_user:
description: User you 'become' to execute the task.
type: string
ini:
- section: privilege_escalation
key: become_user
- section: ksu_become_plugin
key: user
vars:
- name: ansible_become_user
- name: ansible_ksu_user
env:
- name: ANSIBLE_BECOME_USER
- name: ANSIBLE_KSU_USER
required: true
become_exe:
description: C(ksu) executable.
type: string
default: ksu
ini:
- section: privilege_escalation
key: become_exe
- section: ksu_become_plugin
key: executable
vars:
- name: ansible_become_exe
- name: ansible_ksu_exe
env:
- name: ANSIBLE_BECOME_EXE
- name: ANSIBLE_KSU_EXE
become_flags:
description: Options to pass to C(ksu).
type: string
default: ''
ini:
- section: privilege_escalation
key: become_flags
- section: ksu_become_plugin
key: flags
vars:
- name: ansible_become_flags
- name: ansible_ksu_flags
env:
- name: ANSIBLE_BECOME_FLAGS
- name: ANSIBLE_KSU_FLAGS
become_pass:
description: C(ksu) password.
type: string
required: false
vars:
- name: ansible_ksu_pass
- name: ansible_become_pass
- name: ansible_become_password
env:
- name: ANSIBLE_BECOME_PASS
- name: ANSIBLE_KSU_PASS
ini:
- section: ksu_become_plugin
key: password
prompt_l10n:
DOCUMENTATION = '''
name: ksu
short_description: Kerberos substitute user
description:
- List of localized strings to match for prompt detection.
- If empty we will use the built in one.
type: list
elements: string
default: []
ini:
- section: ksu_become_plugin
key: localized_prompts
vars:
- name: ansible_ksu_prompt_l10n
env:
- name: ANSIBLE_KSU_PROMPT_L10N
"""
- This become plugins allows your remote/login user to execute commands as another user via the ksu utility.
author: Ansible Core Team
options:
become_user:
description: User you 'become' to execute the task.
type: string
ini:
- section: privilege_escalation
key: become_user
- section: ksu_become_plugin
key: user
vars:
- name: ansible_become_user
- name: ansible_ksu_user
env:
- name: ANSIBLE_BECOME_USER
- name: ANSIBLE_KSU_USER
required: true
become_exe:
description: Su executable.
type: string
default: ksu
ini:
- section: privilege_escalation
key: become_exe
- section: ksu_become_plugin
key: executable
vars:
- name: ansible_become_exe
- name: ansible_ksu_exe
env:
- name: ANSIBLE_BECOME_EXE
- name: ANSIBLE_KSU_EXE
become_flags:
description: Options to pass to ksu.
type: string
default: ''
ini:
- section: privilege_escalation
key: become_flags
- section: ksu_become_plugin
key: flags
vars:
- name: ansible_become_flags
- name: ansible_ksu_flags
env:
- name: ANSIBLE_BECOME_FLAGS
- name: ANSIBLE_KSU_FLAGS
become_pass:
description: Ksu password.
type: string
required: false
vars:
- name: ansible_ksu_pass
- name: ansible_become_pass
- name: ansible_become_password
env:
- name: ANSIBLE_BECOME_PASS
- name: ANSIBLE_KSU_PASS
ini:
- section: ksu_become_plugin
key: password
prompt_l10n:
description:
- List of localized strings to match for prompt detection.
- If empty we will use the built in one.
type: list
elements: string
default: []
ini:
- section: ksu_become_plugin
key: localized_prompts
vars:
- name: ansible_ksu_prompt_l10n
env:
- name: ANSIBLE_KSU_PROMPT_L10N
'''
import re
@@ -123,4 +124,4 @@ class BecomeModule(BecomeBase):
flags = self.get_option('become_flags')
user = self.get_option('become_user')
return f'{exe} {user} {flags} -e {self._build_success_command(cmd, shell)} '
return '%s %s %s -e %s ' % (exe, user, flags, self._build_success_command(cmd, shell))

View File

@@ -2,92 +2,96 @@
# Copyright (c) 2018, Ansible Project
# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
# SPDX-License-Identifier: GPL-3.0-or-later
from __future__ import annotations
from __future__ import (absolute_import, division, print_function)
__metaclass__ = type
DOCUMENTATION = r"""
name: machinectl
short_description: Systemd's machinectl privilege escalation
description:
- This become plugins allows your remote/login user to execute commands as another user using the C(machinectl) utility.
author: Ansible Core Team
options:
become_user:
description: User you 'become' to execute the task.
type: string
default: ''
ini:
- section: privilege_escalation
key: become_user
- section: machinectl_become_plugin
key: user
vars:
- name: ansible_become_user
- name: ansible_machinectl_user
env:
- name: ANSIBLE_BECOME_USER
- name: ANSIBLE_MACHINECTL_USER
become_exe:
description: C(machinectl) executable.
type: string
default: machinectl
ini:
- section: privilege_escalation
key: become_exe
- section: machinectl_become_plugin
key: executable
vars:
- name: ansible_become_exe
- name: ansible_machinectl_exe
env:
- name: ANSIBLE_BECOME_EXE
- name: ANSIBLE_MACHINECTL_EXE
become_flags:
description: Options to pass to C(machinectl).
type: string
default: ''
ini:
- section: privilege_escalation
key: become_flags
- section: machinectl_become_plugin
key: flags
vars:
- name: ansible_become_flags
- name: ansible_machinectl_flags
env:
- name: ANSIBLE_BECOME_FLAGS
- name: ANSIBLE_MACHINECTL_FLAGS
become_pass:
description: Password for C(machinectl).
type: string
required: false
vars:
- name: ansible_become_password
- name: ansible_become_pass
- name: ansible_machinectl_pass
env:
- name: ANSIBLE_BECOME_PASS
- name: ANSIBLE_MACHINECTL_PASS
ini:
- section: machinectl_become_plugin
key: password
notes:
- When not using this plugin with user V(root), it only works correctly with a polkit rule which will alter the behaviour
of machinectl. This rule must alter the prompt behaviour to ask directly for the user credentials, if the user is allowed
to perform the action (take a look at the examples section). If such a rule is not present the plugin only work if it
is used in context with the root user, because then no further prompt will be shown by machinectl.
"""
DOCUMENTATION = '''
name: machinectl
short_description: Systemd's machinectl privilege escalation
description:
- This become plugins allows your remote/login user to execute commands as another user via the machinectl utility.
author: Ansible Core Team
options:
become_user:
description: User you 'become' to execute the task.
type: string
default: ''
ini:
- section: privilege_escalation
key: become_user
- section: machinectl_become_plugin
key: user
vars:
- name: ansible_become_user
- name: ansible_machinectl_user
env:
- name: ANSIBLE_BECOME_USER
- name: ANSIBLE_MACHINECTL_USER
become_exe:
description: Machinectl executable.
type: string
default: machinectl
ini:
- section: privilege_escalation
key: become_exe
- section: machinectl_become_plugin
key: executable
vars:
- name: ansible_become_exe
- name: ansible_machinectl_exe
env:
- name: ANSIBLE_BECOME_EXE
- name: ANSIBLE_MACHINECTL_EXE
become_flags:
description: Options to pass to machinectl.
type: string
default: ''
ini:
- section: privilege_escalation
key: become_flags
- section: machinectl_become_plugin
key: flags
vars:
- name: ansible_become_flags
- name: ansible_machinectl_flags
env:
- name: ANSIBLE_BECOME_FLAGS
- name: ANSIBLE_MACHINECTL_FLAGS
become_pass:
description: Password for machinectl.
type: string
required: false
vars:
- name: ansible_become_password
- name: ansible_become_pass
- name: ansible_machinectl_pass
env:
- name: ANSIBLE_BECOME_PASS
- name: ANSIBLE_MACHINECTL_PASS
ini:
- section: machinectl_become_plugin
key: password
notes:
- When not using this plugin with user V(root), it only works correctly with a polkit rule which will alter
the behaviour of machinectl. This rule must alter the prompt behaviour to ask directly for the user credentials,
if the user is allowed to perform the action (take a look at the examples section).
If such a rule is not present the plugin only work if it is used in context with the root user,
because then no further prompt will be shown by machinectl.
- This become plugin does not work when connection pipelining is enabled. With ansible-core 2.19+, using it automatically
disables pipelining. On ansible-core 2.18 and before, pipelining must explicitly be disabled by the user.
'''
EXAMPLES = r"""
EXAMPLES = r'''
# A polkit rule needed to use the module with a non-root user.
# See the Notes section for details.
/etc/polkit-1/rules.d/60-machinectl-fast-user-auth.rules: |-
/etc/polkit-1/rules.d/60-machinectl-fast-user-auth.rules: |
polkit.addRule(function(action, subject) {
if(action.id == "org.freedesktop.machine1.host-shell" &&
subject.isInGroup("wheel")) {
return polkit.Result.AUTH_SELF_KEEP;
}
});
"""
'''
from re import compile as re_compile
@@ -107,6 +111,10 @@ class BecomeModule(BecomeBase):
success = ('==== AUTHENTICATION COMPLETE ====',)
require_tty = True # see https://github.com/ansible-collections/community.general/issues/6932
# See https://github.com/ansible/ansible/issues/81254,
# https://github.com/ansible/ansible/pull/78111
pipelining = False
@staticmethod
def remove_ansi_codes(line):
return ansi_color_codes.sub(b"", line)
@@ -121,7 +129,7 @@ class BecomeModule(BecomeBase):
flags = self.get_option('become_flags')
user = self.get_option('become_user')
return f'{become} -q shell {flags} {user}@ {self._build_success_command(cmd, shell)}'
return '%s -q shell %s %s@ %s' % (become, flags, user, self._build_success_command(cmd, shell))
def check_success(self, b_output):
b_output = self.remove_ansi_codes(b_output)

View File

@@ -2,86 +2,87 @@
# Copyright (c) 2018, Ansible Project
# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
# SPDX-License-Identifier: GPL-3.0-or-later
from __future__ import annotations
from __future__ import (absolute_import, division, print_function)
__metaclass__ = type
DOCUMENTATION = r"""
name: pbrun
short_description: PowerBroker run
description:
- This become plugins allows your remote/login user to execute commands as another user using the C(pbrun) utility.
author: Ansible Core Team
options:
become_user:
description: User you 'become' to execute the task.
type: string
default: ''
ini:
- section: privilege_escalation
key: become_user
- section: pbrun_become_plugin
key: user
vars:
- name: ansible_become_user
- name: ansible_pbrun_user
env:
- name: ANSIBLE_BECOME_USER
- name: ANSIBLE_PBRUN_USER
become_exe:
description: C(pbrun) executable.
type: string
default: pbrun
ini:
- section: privilege_escalation
key: become_exe
- section: pbrun_become_plugin
key: executable
vars:
- name: ansible_become_exe
- name: ansible_pbrun_exe
env:
- name: ANSIBLE_BECOME_EXE
- name: ANSIBLE_PBRUN_EXE
become_flags:
description: Options to pass to C(pbrun).
type: string
default: ''
ini:
- section: privilege_escalation
key: become_flags
- section: pbrun_become_plugin
key: flags
vars:
- name: ansible_become_flags
- name: ansible_pbrun_flags
env:
- name: ANSIBLE_BECOME_FLAGS
- name: ANSIBLE_PBRUN_FLAGS
become_pass:
description: Password for C(pbrun).
type: string
required: false
vars:
- name: ansible_become_password
- name: ansible_become_pass
- name: ansible_pbrun_pass
env:
- name: ANSIBLE_BECOME_PASS
- name: ANSIBLE_PBRUN_PASS
ini:
- section: pbrun_become_plugin
key: password
wrap_exe:
description: Toggle to wrap the command C(pbrun) calls in C(shell -c) or not.
default: false
type: bool
ini:
- section: pbrun_become_plugin
key: wrap_execution
vars:
- name: ansible_pbrun_wrap_execution
env:
- name: ANSIBLE_PBRUN_WRAP_EXECUTION
"""
DOCUMENTATION = '''
name: pbrun
short_description: PowerBroker run
description:
- This become plugins allows your remote/login user to execute commands as another user via the pbrun utility.
author: Ansible Core Team
options:
become_user:
description: User you 'become' to execute the task.
type: string
default: ''
ini:
- section: privilege_escalation
key: become_user
- section: pbrun_become_plugin
key: user
vars:
- name: ansible_become_user
- name: ansible_pbrun_user
env:
- name: ANSIBLE_BECOME_USER
- name: ANSIBLE_PBRUN_USER
become_exe:
description: Sudo executable.
type: string
default: pbrun
ini:
- section: privilege_escalation
key: become_exe
- section: pbrun_become_plugin
key: executable
vars:
- name: ansible_become_exe
- name: ansible_pbrun_exe
env:
- name: ANSIBLE_BECOME_EXE
- name: ANSIBLE_PBRUN_EXE
become_flags:
description: Options to pass to pbrun.
type: string
default: ''
ini:
- section: privilege_escalation
key: become_flags
- section: pbrun_become_plugin
key: flags
vars:
- name: ansible_become_flags
- name: ansible_pbrun_flags
env:
- name: ANSIBLE_BECOME_FLAGS
- name: ANSIBLE_PBRUN_FLAGS
become_pass:
description: Password for pbrun.
type: string
required: false
vars:
- name: ansible_become_password
- name: ansible_become_pass
- name: ansible_pbrun_pass
env:
- name: ANSIBLE_BECOME_PASS
- name: ANSIBLE_PBRUN_PASS
ini:
- section: pbrun_become_plugin
key: password
wrap_exe:
description: Toggle to wrap the command pbrun calls in C(shell -c) or not.
default: false
type: bool
ini:
- section: pbrun_become_plugin
key: wrap_execution
vars:
- name: ansible_pbrun_wrap_execution
env:
- name: ANSIBLE_PBRUN_WRAP_EXECUTION
'''
from ansible.plugins.become import BecomeBase
@@ -102,7 +103,7 @@ class BecomeModule(BecomeBase):
flags = self.get_option('become_flags')
become_user = self.get_option('become_user')
user = f'-u {become_user}' if become_user else ''
user = '-u %s' % (become_user) if become_user else ''
noexe = not self.get_option('wrap_exe')
return f"{become_exe} {flags} {user} {self._build_success_command(cmd, shell, noexe=noexe)}"
return ' '.join([become_exe, flags, user, self._build_success_command(cmd, shell, noexe=noexe)])

View File

@@ -2,91 +2,92 @@
# Copyright (c) 2018, Ansible Project
# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
# SPDX-License-Identifier: GPL-3.0-or-later
from __future__ import annotations
from __future__ import (absolute_import, division, print_function)
__metaclass__ = type
DOCUMENTATION = r"""
name: pfexec
short_description: profile based execution
description:
- This become plugins allows your remote/login user to execute commands as another user using the C(pfexec) utility.
author: Ansible Core Team
options:
become_user:
DOCUMENTATION = '''
name: pfexec
short_description: profile based execution
description:
- User you 'become' to execute the task.
- This plugin ignores this setting as pfexec uses its own C(exec_attr) to figure this out, but it is supplied here for
Ansible to make decisions needed for the task execution, like file permissions.
type: string
default: root
ini:
- section: privilege_escalation
key: become_user
- section: pfexec_become_plugin
key: user
vars:
- name: ansible_become_user
- name: ansible_pfexec_user
env:
- name: ANSIBLE_BECOME_USER
- name: ANSIBLE_PFEXEC_USER
become_exe:
description: C(pfexec) executable.
type: string
default: pfexec
ini:
- section: privilege_escalation
key: become_exe
- section: pfexec_become_plugin
key: executable
vars:
- name: ansible_become_exe
- name: ansible_pfexec_exe
env:
- name: ANSIBLE_BECOME_EXE
- name: ANSIBLE_PFEXEC_EXE
become_flags:
description: Options to pass to C(pfexec).
type: string
default: -H -S -n
ini:
- section: privilege_escalation
key: become_flags
- section: pfexec_become_plugin
key: flags
vars:
- name: ansible_become_flags
- name: ansible_pfexec_flags
env:
- name: ANSIBLE_BECOME_FLAGS
- name: ANSIBLE_PFEXEC_FLAGS
become_pass:
description: C(pfexec) password.
type: string
required: false
vars:
- name: ansible_become_password
- name: ansible_become_pass
- name: ansible_pfexec_pass
env:
- name: ANSIBLE_BECOME_PASS
- name: ANSIBLE_PFEXEC_PASS
ini:
- section: pfexec_become_plugin
key: password
wrap_exe:
description: Toggle to wrap the command C(pfexec) calls in C(shell -c) or not.
default: false
type: bool
ini:
- section: pfexec_become_plugin
key: wrap_execution
vars:
- name: ansible_pfexec_wrap_execution
env:
- name: ANSIBLE_PFEXEC_WRAP_EXECUTION
notes:
- This plugin ignores O(become_user) as pfexec uses its own C(exec_attr) to figure this out.
"""
- This become plugins allows your remote/login user to execute commands as another user via the pfexec utility.
author: Ansible Core Team
options:
become_user:
description:
- User you 'become' to execute the task.
- This plugin ignores this setting as pfexec uses it's own C(exec_attr) to figure this out,
but it is supplied here for Ansible to make decisions needed for the task execution, like file permissions.
type: string
default: root
ini:
- section: privilege_escalation
key: become_user
- section: pfexec_become_plugin
key: user
vars:
- name: ansible_become_user
- name: ansible_pfexec_user
env:
- name: ANSIBLE_BECOME_USER
- name: ANSIBLE_PFEXEC_USER
become_exe:
description: Sudo executable.
type: string
default: pfexec
ini:
- section: privilege_escalation
key: become_exe
- section: pfexec_become_plugin
key: executable
vars:
- name: ansible_become_exe
- name: ansible_pfexec_exe
env:
- name: ANSIBLE_BECOME_EXE
- name: ANSIBLE_PFEXEC_EXE
become_flags:
description: Options to pass to pfexec.
type: string
default: -H -S -n
ini:
- section: privilege_escalation
key: become_flags
- section: pfexec_become_plugin
key: flags
vars:
- name: ansible_become_flags
- name: ansible_pfexec_flags
env:
- name: ANSIBLE_BECOME_FLAGS
- name: ANSIBLE_PFEXEC_FLAGS
become_pass:
description: pfexec password.
type: string
required: false
vars:
- name: ansible_become_password
- name: ansible_become_pass
- name: ansible_pfexec_pass
env:
- name: ANSIBLE_BECOME_PASS
- name: ANSIBLE_PFEXEC_PASS
ini:
- section: pfexec_become_plugin
key: password
wrap_exe:
description: Toggle to wrap the command pfexec calls in C(shell -c) or not.
default: false
type: bool
ini:
- section: pfexec_become_plugin
key: wrap_execution
vars:
- name: ansible_pfexec_wrap_execution
env:
- name: ANSIBLE_PFEXEC_WRAP_EXECUTION
notes:
- This plugin ignores O(become_user) as pfexec uses its own C(exec_attr) to figure this out.
'''
from ansible.plugins.become import BecomeBase
@@ -105,4 +106,4 @@ class BecomeModule(BecomeBase):
flags = self.get_option('become_flags')
noexe = not self.get_option('wrap_exe')
return f'{exe} {flags} {self._build_success_command(cmd, shell, noexe=noexe)}'
return '%s %s %s' % (exe, flags, self._build_success_command(cmd, shell, noexe=noexe))

View File

@@ -2,62 +2,63 @@
# Copyright (c) 2018, Ansible Project
# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
# SPDX-License-Identifier: GPL-3.0-or-later
from __future__ import annotations
from __future__ import (absolute_import, division, print_function)
__metaclass__ = type
DOCUMENTATION = r"""
name: pmrun
short_description: Privilege Manager run
description:
- This become plugins allows your remote/login user to execute commands as another user using the C(pmrun) utility.
author: Ansible Core Team
options:
become_exe:
description: C(pmrun) executable.
type: string
default: pmrun
ini:
- section: privilege_escalation
key: become_exe
- section: pmrun_become_plugin
key: executable
vars:
- name: ansible_become_exe
- name: ansible_pmrun_exe
env:
- name: ANSIBLE_BECOME_EXE
- name: ANSIBLE_PMRUN_EXE
become_flags:
description: Options to pass to C(pmrun).
type: string
default: ''
ini:
- section: privilege_escalation
key: become_flags
- section: pmrun_become_plugin
key: flags
vars:
- name: ansible_become_flags
- name: ansible_pmrun_flags
env:
- name: ANSIBLE_BECOME_FLAGS
- name: ANSIBLE_PMRUN_FLAGS
become_pass:
description: C(pmrun) password.
type: string
required: false
vars:
- name: ansible_become_password
- name: ansible_become_pass
- name: ansible_pmrun_pass
env:
- name: ANSIBLE_BECOME_PASS
- name: ANSIBLE_PMRUN_PASS
ini:
- section: pmrun_become_plugin
key: password
notes:
- This plugin ignores the C(become_user) supplied and uses C(pmrun)'s own configuration to select the user.
"""
DOCUMENTATION = '''
name: pmrun
short_description: Privilege Manager run
description:
- This become plugins allows your remote/login user to execute commands as another user via the pmrun utility.
author: Ansible Core Team
options:
become_exe:
description: Sudo executable
type: string
default: pmrun
ini:
- section: privilege_escalation
key: become_exe
- section: pmrun_become_plugin
key: executable
vars:
- name: ansible_become_exe
- name: ansible_pmrun_exe
env:
- name: ANSIBLE_BECOME_EXE
- name: ANSIBLE_PMRUN_EXE
become_flags:
description: Options to pass to pmrun.
type: string
default: ''
ini:
- section: privilege_escalation
key: become_flags
- section: pmrun_become_plugin
key: flags
vars:
- name: ansible_become_flags
- name: ansible_pmrun_flags
env:
- name: ANSIBLE_BECOME_FLAGS
- name: ANSIBLE_PMRUN_FLAGS
become_pass:
description: pmrun password.
type: string
required: false
vars:
- name: ansible_become_password
- name: ansible_become_pass
- name: ansible_pmrun_pass
env:
- name: ANSIBLE_BECOME_PASS
- name: ANSIBLE_PMRUN_PASS
ini:
- section: pmrun_become_plugin
key: password
notes:
- This plugin ignores the become_user supplied and uses pmrun's own configuration to select the user.
'''
from ansible.plugins.become import BecomeBase
from ansible.module_utils.six.moves import shlex_quote
@@ -77,4 +78,4 @@ class BecomeModule(BecomeBase):
become = self.get_option('become_exe')
flags = self.get_option('become_flags')
return f'{become} {flags} {shlex_quote(self._build_success_command(cmd, shell))}'
return '%s %s %s' % (become, flags, shlex_quote(self._build_success_command(cmd, shell)))

View File

@@ -3,71 +3,72 @@
# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
# SPDX-License-Identifier: GPL-3.0-or-later
from __future__ import annotations
from __future__ import absolute_import, division, print_function
__metaclass__ = type
DOCUMENTATION = r"""
name: run0
short_description: Systemd's run0
description:
- This become plugins allows your remote/login user to execute commands as another user using the C(run0) utility.
author:
- Thomas Sjögren (@konstruktoid)
version_added: '9.0.0'
options:
become_user:
description: User you 'become' to execute the task.
default: root
ini:
- section: privilege_escalation
key: become_user
- section: run0_become_plugin
key: user
vars:
- name: ansible_become_user
- name: ansible_run0_user
env:
- name: ANSIBLE_BECOME_USER
- name: ANSIBLE_RUN0_USER
type: string
become_exe:
description: C(run0) executable.
default: run0
ini:
- section: privilege_escalation
key: become_exe
- section: run0_become_plugin
key: executable
vars:
- name: ansible_become_exe
- name: ansible_run0_exe
env:
- name: ANSIBLE_BECOME_EXE
- name: ANSIBLE_RUN0_EXE
type: string
become_flags:
description: Options to pass to C(run0).
default: ''
ini:
- section: privilege_escalation
key: become_flags
- section: run0_become_plugin
key: flags
vars:
- name: ansible_become_flags
- name: ansible_run0_flags
env:
- name: ANSIBLE_BECOME_FLAGS
- name: ANSIBLE_RUN0_FLAGS
type: string
notes:
- This plugin will only work when a C(polkit) rule is in place.
DOCUMENTATION = """
name: run0
short_description: Systemd's run0
description:
- This become plugins allows your remote/login user to execute commands as another user via the C(run0) utility.
author:
- Thomas Sjögren (@konstruktoid)
version_added: '9.0.0'
options:
become_user:
description: User you 'become' to execute the task.
default: root
ini:
- section: privilege_escalation
key: become_user
- section: run0_become_plugin
key: user
vars:
- name: ansible_become_user
- name: ansible_run0_user
env:
- name: ANSIBLE_BECOME_USER
- name: ANSIBLE_RUN0_USER
type: string
become_exe:
description: The C(run0) executable.
default: run0
ini:
- section: privilege_escalation
key: become_exe
- section: run0_become_plugin
key: executable
vars:
- name: ansible_become_exe
- name: ansible_run0_exe
env:
- name: ANSIBLE_BECOME_EXE
- name: ANSIBLE_RUN0_EXE
type: string
become_flags:
description: Options to pass to run0.
default: ''
ini:
- section: privilege_escalation
key: become_flags
- section: run0_become_plugin
key: flags
vars:
- name: ansible_become_flags
- name: ansible_run0_flags
env:
- name: ANSIBLE_BECOME_FLAGS
- name: ANSIBLE_RUN0_FLAGS
type: string
notes:
- This plugin will only work when a polkit rule is in place.
"""
EXAMPLES = r"""
# An example polkit rule that allows the user 'ansible' in the 'wheel' group
# to execute commands using run0 without authentication.
/etc/polkit-1/rules.d/60-run0-fast-user-auth.rules: |-
/etc/polkit-1/rules.d/60-run0-fast-user-auth.rules: |
polkit.addRule(function(action, subject) {
if(action.id == "org.freedesktop.systemd1.manage-units" &&
subject.isInGroup("wheel") &&

View File

@@ -2,75 +2,76 @@
# Copyright (c) 2018, Ansible Project
# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
# SPDX-License-Identifier: GPL-3.0-or-later
from __future__ import annotations
from __future__ import (absolute_import, division, print_function)
__metaclass__ = type
DOCUMENTATION = r"""
name: sesu
short_description: CA Privileged Access Manager
description:
- This become plugins allows your remote/login user to execute commands as another user using the C(sesu) utility.
author: ansible (@nekonyuu)
options:
become_user:
description: User you 'become' to execute the task.
type: string
default: ''
ini:
- section: privilege_escalation
key: become_user
- section: sesu_become_plugin
key: user
vars:
- name: ansible_become_user
- name: ansible_sesu_user
env:
- name: ANSIBLE_BECOME_USER
- name: ANSIBLE_SESU_USER
become_exe:
description: C(sesu) executable.
type: string
default: sesu
ini:
- section: privilege_escalation
key: become_exe
- section: sesu_become_plugin
key: executable
vars:
- name: ansible_become_exe
- name: ansible_sesu_exe
env:
- name: ANSIBLE_BECOME_EXE
- name: ANSIBLE_SESU_EXE
become_flags:
description: Options to pass to C(sesu).
type: string
default: -H -S -n
ini:
- section: privilege_escalation
key: become_flags
- section: sesu_become_plugin
key: flags
vars:
- name: ansible_become_flags
- name: ansible_sesu_flags
env:
- name: ANSIBLE_BECOME_FLAGS
- name: ANSIBLE_SESU_FLAGS
become_pass:
description: Password to pass to C(sesu).
type: string
required: false
vars:
- name: ansible_become_password
- name: ansible_become_pass
- name: ansible_sesu_pass
env:
- name: ANSIBLE_BECOME_PASS
- name: ANSIBLE_SESU_PASS
ini:
- section: sesu_become_plugin
key: password
"""
DOCUMENTATION = '''
name: sesu
short_description: CA Privileged Access Manager
description:
- This become plugins allows your remote/login user to execute commands as another user via the sesu utility.
author: ansible (@nekonyuu)
options:
become_user:
description: User you 'become' to execute the task.
type: string
default: ''
ini:
- section: privilege_escalation
key: become_user
- section: sesu_become_plugin
key: user
vars:
- name: ansible_become_user
- name: ansible_sesu_user
env:
- name: ANSIBLE_BECOME_USER
- name: ANSIBLE_SESU_USER
become_exe:
description: sesu executable.
type: string
default: sesu
ini:
- section: privilege_escalation
key: become_exe
- section: sesu_become_plugin
key: executable
vars:
- name: ansible_become_exe
- name: ansible_sesu_exe
env:
- name: ANSIBLE_BECOME_EXE
- name: ANSIBLE_SESU_EXE
become_flags:
description: Options to pass to sesu.
type: string
default: -H -S -n
ini:
- section: privilege_escalation
key: become_flags
- section: sesu_become_plugin
key: flags
vars:
- name: ansible_become_flags
- name: ansible_sesu_flags
env:
- name: ANSIBLE_BECOME_FLAGS
- name: ANSIBLE_SESU_FLAGS
become_pass:
description: Password to pass to sesu.
type: string
required: false
vars:
- name: ansible_become_password
- name: ansible_become_pass
- name: ansible_sesu_pass
env:
- name: ANSIBLE_BECOME_PASS
- name: ANSIBLE_SESU_PASS
ini:
- section: sesu_become_plugin
key: password
'''
from ansible.plugins.become import BecomeBase
@@ -92,4 +93,4 @@ class BecomeModule(BecomeBase):
flags = self.get_option('become_flags')
user = self.get_option('become_user')
return f'{become} {flags} {user} -c {self._build_success_command(cmd, shell)}'
return '%s %s %s -c %s' % (become, flags, user, self._build_success_command(cmd, shell))

View File

@@ -2,77 +2,77 @@
# Copyright (c) 2021, Ansible Project
# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
# SPDX-License-Identifier: GPL-3.0-or-later
from __future__ import annotations
from __future__ import (absolute_import, division, print_function)
__metaclass__ = type
DOCUMENTATION = r"""
name: sudosu
short_description: Run tasks using sudo su -
description:
- This become plugin allows your remote/login user to execute commands as another user using the C(sudo) and C(su) utilities
combined.
author:
- Dag Wieers (@dagwieers)
version_added: 2.4.0
options:
become_user:
description: User you 'become' to execute the task.
type: string
default: root
ini:
- section: privilege_escalation
key: become_user
- section: sudo_become_plugin
key: user
vars:
- name: ansible_become_user
- name: ansible_sudo_user
env:
- name: ANSIBLE_BECOME_USER
- name: ANSIBLE_SUDO_USER
become_flags:
description: Options to pass to C(sudo).
type: string
default: -H -S -n
ini:
- section: privilege_escalation
key: become_flags
- section: sudo_become_plugin
key: flags
vars:
- name: ansible_become_flags
- name: ansible_sudo_flags
env:
- name: ANSIBLE_BECOME_FLAGS
- name: ANSIBLE_SUDO_FLAGS
become_pass:
description: Password to pass to C(sudo).
type: string
required: false
vars:
- name: ansible_become_password
- name: ansible_become_pass
- name: ansible_sudo_pass
env:
- name: ANSIBLE_BECOME_PASS
- name: ANSIBLE_SUDO_PASS
ini:
- section: sudo_become_plugin
key: password
alt_method:
DOCUMENTATION = """
name: sudosu
short_description: Run tasks using sudo su -
description:
- Whether to use an alternative method to call C(su). Instead of running C(su -l user /path/to/shell -c command), it
runs C(su -l user -c command).
- Use this when the default one is not working on your system.
required: false
type: boolean
ini:
- section: community.general.sudosu
key: alternative_method
vars:
- name: ansible_sudosu_alt_method
env:
- name: ANSIBLE_SUDOSU_ALT_METHOD
version_added: 9.2.0
- This become plugin allows your remote/login user to execute commands as another user via the C(sudo) and C(su) utilities combined.
author:
- Dag Wieers (@dagwieers)
version_added: 2.4.0
options:
become_user:
description: User you 'become' to execute the task.
type: string
default: root
ini:
- section: privilege_escalation
key: become_user
- section: sudo_become_plugin
key: user
vars:
- name: ansible_become_user
- name: ansible_sudo_user
env:
- name: ANSIBLE_BECOME_USER
- name: ANSIBLE_SUDO_USER
become_flags:
description: Options to pass to C(sudo).
type: string
default: -H -S -n
ini:
- section: privilege_escalation
key: become_flags
- section: sudo_become_plugin
key: flags
vars:
- name: ansible_become_flags
- name: ansible_sudo_flags
env:
- name: ANSIBLE_BECOME_FLAGS
- name: ANSIBLE_SUDO_FLAGS
become_pass:
description: Password to pass to C(sudo).
type: string
required: false
vars:
- name: ansible_become_password
- name: ansible_become_pass
- name: ansible_sudo_pass
env:
- name: ANSIBLE_BECOME_PASS
- name: ANSIBLE_SUDO_PASS
ini:
- section: sudo_become_plugin
key: password
alt_method:
description:
- Whether to use an alternative method to call C(su). Instead of running C(su -l user /path/to/shell -c command),
it runs C(su -l user -c command).
- Use this when the default one is not working on your system.
required: false
type: boolean
ini:
- section: community.general.sudosu
key: alternative_method
vars:
- name: ansible_sudosu_alt_method
env:
- name: ANSIBLE_SUDOSU_ALT_METHOD
version_added: 9.2.0
"""
@@ -98,16 +98,16 @@ class BecomeModule(BecomeBase):
flags = self.get_option('become_flags') or ''
prompt = ''
if self.get_option('become_pass'):
self.prompt = f'[sudo via ansible, key={self._id}] password:'
self.prompt = '[sudo via ansible, key=%s] password:' % self._id
if flags: # this could be simplified, but kept as is for now for backwards string matching
flags = flags.replace('-n', '')
prompt = f'-p "{self.prompt}"'
prompt = '-p "%s"' % (self.prompt)
user = self.get_option('become_user') or ''
if user:
user = f'{user}'
user = '%s' % (user)
if self.get_option('alt_method'):
return f"{becomecmd} {flags} {prompt} su -l {user} -c {self._build_success_command(cmd, shell, True)}"
return ' '.join([becomecmd, flags, prompt, "su -l", user, "-c", self._build_success_command(cmd, shell, True)])
else:
return f"{becomecmd} {flags} {prompt} su -l {user} {self._build_success_command(cmd, shell)}"
return ' '.join([becomecmd, flags, prompt, 'su -l', user, self._build_success_command(cmd, shell)])

View File

@@ -4,7 +4,8 @@
# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
# SPDX-License-Identifier: GPL-3.0-or-later
from __future__ import annotations
from __future__ import (absolute_import, division, print_function)
__metaclass__ = type
DOCUMENTATION = r"""
author: Unknown (!UNKNOWN)
@@ -190,7 +191,7 @@ class CacheModule(BaseCacheModule):
self._keys = CacheModuleKeys(self._db, self._db.get(CacheModuleKeys.PREFIX) or [])
def _make_key(self, key):
return f"{self._prefix}{key}"
return "{0}{1}".format(self._prefix, key)
def _expire_keys(self):
if self._timeout > 0:

View File

@@ -5,7 +5,8 @@
# SPDX-License-Identifier: GPL-3.0-or-later
# Make coding more python3-ish
from __future__ import annotations
from __future__ import (absolute_import, division, print_function)
__metaclass__ = type
DOCUMENTATION = r"""
name: pickle
@@ -56,6 +57,7 @@ class CacheModule(BaseFileCacheModule):
"""
A caching module backed by pickle files.
"""
_persistent = False # prevent unnecessary JSON serialization and key munging
def _load(self, filepath):
# Pickle is a binary format

View File

@@ -3,7 +3,8 @@
# Copyright (c) 2017 Ansible Project
# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
# SPDX-License-Identifier: GPL-3.0-or-later
from __future__ import annotations
from __future__ import (absolute_import, division, print_function)
__metaclass__ = type
DOCUMENTATION = r"""
author: Unknown (!UNKNOWN)
@@ -72,6 +73,7 @@ import time
import json
from ansible.errors import AnsibleError
from ansible.module_utils.common.text.converters import to_native
from ansible.parsing.ajson import AnsibleJSONEncoder, AnsibleJSONDecoder
from ansible.plugins.cache import BaseCacheModule
from ansible.utils.display import Display
@@ -129,7 +131,7 @@ class CacheModule(BaseCacheModule):
connection = self._parse_connection(self.re_url_conn, uri)
self._db = StrictRedis(*connection, **kw)
display.vv(f'Redis connection: {self._db}')
display.vv('Redis connection: %s' % self._db)
@staticmethod
def _parse_connection(re_patt, uri):
@@ -162,12 +164,12 @@ class CacheModule(BaseCacheModule):
pass # password is optional
sentinels = [self._parse_connection(self.re_sent_conn, shost) for shost in connections]
display.vv(f'\nUsing redis sentinels: {sentinels}')
display.vv('\nUsing redis sentinels: %s' % sentinels)
scon = Sentinel(sentinels, **kw)
try:
return scon.master_for(self._sentinel_service_name, socket_timeout=0.2)
except Exception as exc:
raise AnsibleError(f'Could not connect to redis sentinel: {exc}')
raise AnsibleError('Could not connect to redis sentinel: %s' % to_native(exc))
def _make_key(self, key):
return self._prefix + key

10
plugins/cache/yaml.py vendored
View File

@@ -5,7 +5,8 @@
# SPDX-License-Identifier: GPL-3.0-or-later
# Make coding more python3-ish
from __future__ import annotations
from __future__ import (absolute_import, division, print_function)
__metaclass__ = type
DOCUMENTATION = r"""
name: yaml
@@ -44,8 +45,7 @@ options:
# TODO: determine whether it is OK to change to: type: float
"""
import codecs
import os
import yaml
@@ -60,9 +60,9 @@ class CacheModule(BaseFileCacheModule):
"""
def _load(self, filepath):
with codecs.open(filepath, 'r', encoding='utf-8') as f:
with open(os.path.abspath(filepath), 'r', encoding='utf-8') as f:
return AnsibleLoader(f).get_single_data()
def _dump(self, value, filepath):
with codecs.open(filepath, 'w', encoding='utf-8') as f:
with open(os.path.abspath(filepath), 'w', encoding='utf-8') as f:
yaml.dump(value, f, Dumper=AnsibleDumper, default_flow_style=False)

View File

@@ -4,7 +4,8 @@
# SPDX-License-Identifier: GPL-3.0-or-later
# Make coding more python3-ish
from __future__ import annotations
from __future__ import (absolute_import, division, print_function)
__metaclass__ = type
DOCUMENTATION = r"""
author: Unknown (!UNKNOWN)
@@ -114,7 +115,7 @@ class CallbackModule(CallbackBase):
max_results = int(f.read().strip()) / 1024 / 1024
self._display.banner('CGROUP MEMORY RECAP')
self._display.display(f'Execution Maximum: {max_results:0.2f}MB\n\n')
self._display.display('Execution Maximum: %0.2fMB\n\n' % max_results)
for task, memory in self.task_results:
self._display.display(f'{task.get_name()} ({task._uuid}): {memory:0.2f}MB')
self._display.display('%s (%s): %0.2fMB' % (task.get_name(), task._uuid, memory))

View File

@@ -4,7 +4,8 @@
# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
# SPDX-License-Identifier: GPL-3.0-or-later
from __future__ import annotations
from __future__ import (absolute_import, division, print_function)
__metaclass__ = type
DOCUMENTATION = r"""
author: Unknown (!UNKNOWN)
@@ -37,15 +38,15 @@ class CallbackModule(CallbackBase):
self.play = None
def v2_on_any(self, *args, **kwargs):
self._display.display(f"--- play: {getattr(self.play, 'name', None)} task: {self.task} ---")
self._display.display("--- play: {0} task: {1} ---".format(getattr(self.play, 'name', None), self.task))
self._display.display(" --- ARGS ")
for i, a in enumerate(args):
self._display.display(f' {i}: {a}')
self._display.display(' %s: %s' % (i, a))
self._display.display(" --- KWARGS ")
for k in kwargs:
self._display.display(f' {k}: {kwargs[k]}')
self._display.display(' %s: %s' % (k, kwargs[k]))
def v2_playbook_on_play_start(self, play):
self.play = play

View File

@@ -6,7 +6,8 @@
Counter enabled Ansible callback plugin (See DOCUMENTATION for more information)
'''
from __future__ import annotations
from __future__ import (absolute_import, division, print_function)
__metaclass__ = type
DOCUMENTATION = r"""
author: Unknown (!UNKNOWN)
@@ -70,7 +71,7 @@ class CallbackModule(CallbackBase):
if not name:
msg = u"play"
else:
msg = f"PLAY [{name}]"
msg = u"PLAY [%s]" % name
self._play = play
@@ -90,17 +91,25 @@ class CallbackModule(CallbackBase):
for host in hosts:
stat = stats.summarize(host)
self._display.display(
f"{hostcolor(host, stat)} : {colorize('ok', stat['ok'], C.COLOR_OK)} {colorize('changed', stat['changed'], C.COLOR_CHANGED)} "
f"{colorize('unreachable', stat['unreachable'], C.COLOR_UNREACHABLE)} {colorize('failed', stat['failures'], C.COLOR_ERROR)} "
f"{colorize('rescued', stat['rescued'], C.COLOR_OK)} {colorize('ignored', stat['ignored'], C.COLOR_WARN)}",
self._display.display(u"%s : %s %s %s %s %s %s" % (
hostcolor(host, stat),
colorize(u'ok', stat['ok'], C.COLOR_OK),
colorize(u'changed', stat['changed'], C.COLOR_CHANGED),
colorize(u'unreachable', stat['unreachable'], C.COLOR_UNREACHABLE),
colorize(u'failed', stat['failures'], C.COLOR_ERROR),
colorize(u'rescued', stat['rescued'], C.COLOR_OK),
colorize(u'ignored', stat['ignored'], C.COLOR_WARN)),
screen_only=True
)
self._display.display(
f"{hostcolor(host, stat, False)} : {colorize('ok', stat['ok'], None)} {colorize('changed', stat['changed'], None)} "
f"{colorize('unreachable', stat['unreachable'], None)} {colorize('failed', stat['failures'], None)} "
f"{colorize('rescued', stat['rescued'], None)} {colorize('ignored', stat['ignored'], None)}",
self._display.display(u"%s : %s %s %s %s %s %s" % (
hostcolor(host, stat, False),
colorize(u'ok', stat['ok'], None),
colorize(u'changed', stat['changed'], None),
colorize(u'unreachable', stat['unreachable'], None),
colorize(u'failed', stat['failures'], None),
colorize(u'rescued', stat['rescued'], None),
colorize(u'ignored', stat['ignored'], None)),
log_only=True
)
@@ -115,14 +124,12 @@ class CallbackModule(CallbackBase):
for k in sorted(stats.custom.keys()):
if k == '_run':
continue
_custom_stats = self._dump_results(stats.custom[k], indent=1).replace('\n', '')
self._display.display(f'\t{k}: {_custom_stats}')
self._display.display('\t%s: %s' % (k, self._dump_results(stats.custom[k], indent=1).replace('\n', '')))
# print per run custom stats
if '_run' in stats.custom:
self._display.display("", screen_only=True)
_custom_stats_run = self._dump_results(stats.custom['_run'], indent=1).replace('\n', '')
self._display.display(f'\tRUN: {_custom_stats_run}')
self._display.display('\tRUN: %s' % self._dump_results(stats.custom['_run'], indent=1).replace('\n', ''))
self._display.display("", screen_only=True)
def v2_playbook_on_task_start(self, task, is_conditional):
@@ -136,13 +143,13 @@ class CallbackModule(CallbackBase):
# that they can secure this if they feel that their stdout is insecure
# (shoulder surfing, logging stdout straight to a file, etc).
if not task.no_log and C.DISPLAY_ARGS_TO_STDOUT:
args = ', '.join(('{k}={v}' for k, v in task.args.items()))
args = f' {args}'
self._display.banner(f"TASK {self._task_counter}/{self._task_total} [{task.get_name().strip()}{args}]")
args = ', '.join(('%s=%s' % a for a in task.args.items()))
args = ' %s' % args
self._display.banner("TASK %d/%d [%s%s]" % (self._task_counter, self._task_total, task.get_name().strip(), args))
if self._display.verbosity >= 2:
path = task.get_path()
if path:
self._display.display(f"task path: {path}", color=C.COLOR_DEBUG)
self._display.display("task path: %s" % path, color=C.COLOR_DEBUG)
self._host_counter = self._previous_batch_total
self._task_counter += 1
@@ -159,15 +166,15 @@ class CallbackModule(CallbackBase):
return
elif result._result.get('changed', False):
if delegated_vars:
msg = f"changed: {self._host_counter}/{self._host_total} [{result._host.get_name()} -> {delegated_vars['ansible_host']}]"
msg = "changed: %d/%d [%s -> %s]" % (self._host_counter, self._host_total, result._host.get_name(), delegated_vars['ansible_host'])
else:
msg = f"changed: {self._host_counter}/{self._host_total} [{result._host.get_name()}]"
msg = "changed: %d/%d [%s]" % (self._host_counter, self._host_total, result._host.get_name())
color = C.COLOR_CHANGED
else:
if delegated_vars:
msg = f"ok: {self._host_counter}/{self._host_total} [{result._host.get_name()} -> {delegated_vars['ansible_host']}]"
msg = "ok: %d/%d [%s -> %s]" % (self._host_counter, self._host_total, result._host.get_name(), delegated_vars['ansible_host'])
else:
msg = f"ok: {self._host_counter}/{self._host_total} [{result._host.get_name()}]"
msg = "ok: %d/%d [%s]" % (self._host_counter, self._host_total, result._host.get_name())
color = C.COLOR_OK
self._handle_warnings(result._result)
@@ -178,7 +185,7 @@ class CallbackModule(CallbackBase):
self._clean_results(result._result, result._task.action)
if self._run_is_verbose(result):
msg += f" => {self._dump_results(result._result)}"
msg += " => %s" % (self._dump_results(result._result),)
self._display.display(msg, color=color)
def v2_runner_on_failed(self, result, ignore_errors=False):
@@ -199,16 +206,14 @@ class CallbackModule(CallbackBase):
else:
if delegated_vars:
self._display.display(
f"fatal: {self._host_counter}/{self._host_total} [{result._host.get_name()} -> "
f"{delegated_vars['ansible_host']}]: FAILED! => {self._dump_results(result._result)}",
color=C.COLOR_ERROR
)
self._display.display("fatal: %d/%d [%s -> %s]: FAILED! => %s" % (self._host_counter, self._host_total,
result._host.get_name(), delegated_vars['ansible_host'],
self._dump_results(result._result)),
color=C.COLOR_ERROR)
else:
self._display.display(
f"fatal: {self._host_counter}/{self._host_total} [{result._host.get_name()}]: FAILED! => {self._dump_results(result._result)}",
color=C.COLOR_ERROR
)
self._display.display("fatal: %d/%d [%s]: FAILED! => %s" % (self._host_counter, self._host_total,
result._host.get_name(), self._dump_results(result._result)),
color=C.COLOR_ERROR)
if ignore_errors:
self._display.display("...ignoring", color=C.COLOR_SKIP)
@@ -226,9 +231,9 @@ class CallbackModule(CallbackBase):
if result._task.loop and 'results' in result._result:
self._process_items(result)
else:
msg = f"skipping: {self._host_counter}/{self._host_total} [{result._host.get_name()}]"
msg = "skipping: %d/%d [%s]" % (self._host_counter, self._host_total, result._host.get_name())
if self._run_is_verbose(result):
msg += f" => {self._dump_results(result._result)}"
msg += " => %s" % self._dump_results(result._result)
self._display.display(msg, color=C.COLOR_SKIP)
def v2_runner_on_unreachable(self, result):
@@ -239,13 +244,11 @@ class CallbackModule(CallbackBase):
delegated_vars = result._result.get('_ansible_delegated_vars', None)
if delegated_vars:
self._display.display(
f"fatal: {self._host_counter}/{self._host_total} [{result._host.get_name()} -> "
f"{delegated_vars['ansible_host']}]: UNREACHABLE! => {self._dump_results(result._result)}",
color=C.COLOR_UNREACHABLE
)
self._display.display("fatal: %d/%d [%s -> %s]: UNREACHABLE! => %s" % (self._host_counter, self._host_total,
result._host.get_name(), delegated_vars['ansible_host'],
self._dump_results(result._result)),
color=C.COLOR_UNREACHABLE)
else:
self._display.display(
f"fatal: {self._host_counter}/{self._host_total} [{result._host.get_name()}]: UNREACHABLE! => {self._dump_results(result._result)}",
color=C.COLOR_UNREACHABLE
)
self._display.display("fatal: %d/%d [%s]: UNREACHABLE! => %s" % (self._host_counter, self._host_total,
result._host.get_name(), self._dump_results(result._result)),
color=C.COLOR_UNREACHABLE)

View File

@@ -4,7 +4,8 @@
# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
# SPDX-License-Identifier: GPL-3.0-or-later
from __future__ import annotations
from __future__ import (absolute_import, division, print_function)
__metaclass__ = type
DOCUMENTATION = r"""
name: default_without_diff
@@ -28,7 +29,7 @@ ansible_config: |
stdout_callback = community.general.default_without_diff
# Enable callback with environment variables:
environment_variable: |-
environment_variable: |
ANSIBLE_STDOUT_CALLBACK=community.general.default_without_diff
"""

View File

@@ -4,7 +4,8 @@
# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
# SPDX-License-Identifier: GPL-3.0-or-later
from __future__ import annotations
from __future__ import (absolute_import, division, print_function)
__metaclass__ = type
DOCUMENTATION = r"""
name: dense
@@ -194,7 +195,7 @@ class CallbackModule(CallbackModule_default):
self.disabled = True
def __del__(self):
sys.stdout.write(f"{vt100.restore}{vt100.reset}\n{vt100.save}{vt100.clearline}")
sys.stdout.write(vt100.restore + vt100.reset + '\n' + vt100.save + vt100.clearline)
def _add_host(self, result, status):
name = result._host.get_name()
@@ -242,7 +243,7 @@ class CallbackModule(CallbackModule_default):
def _handle_exceptions(self, result):
if 'exception' in result:
# Remove the exception from the result so it is not shown every time
# Remove the exception from the result so it's not shown every time
del result['exception']
if self._display.verbosity == 1:
@@ -251,7 +252,7 @@ class CallbackModule(CallbackModule_default):
def _display_progress(self, result=None):
# Always rewrite the complete line
sys.stdout.write(vt100.restore + vt100.reset + vt100.clearline + vt100.nolinewrap + vt100.underline)
sys.stdout.write(f'{self.type} {self.count[self.type]}:')
sys.stdout.write('%s %d:' % (self.type, self.count[self.type]))
sys.stdout.write(vt100.reset)
sys.stdout.flush()
@@ -259,7 +260,7 @@ class CallbackModule(CallbackModule_default):
for name in self.hosts:
sys.stdout.write(' ')
if self.hosts[name].get('delegate', None):
sys.stdout.write(f"{self.hosts[name]['delegate']}>")
sys.stdout.write(self.hosts[name]['delegate'] + '>')
sys.stdout.write(colors[self.hosts[name]['state']] + name + vt100.reset)
sys.stdout.flush()
@@ -273,8 +274,8 @@ class CallbackModule(CallbackModule_default):
if not self.shown_title:
self.shown_title = True
sys.stdout.write(vt100.restore + vt100.reset + vt100.clearline + vt100.underline)
sys.stdout.write(f'{self.type} {self.count[self.type]}: {self.task.get_name().strip()}')
sys.stdout.write(f"{vt100.restore}{vt100.reset}\n{vt100.save}{vt100.clearline}")
sys.stdout.write('%s %d: %s' % (self.type, self.count[self.type], self.task.get_name().strip()))
sys.stdout.write(vt100.restore + vt100.reset + '\n' + vt100.save + vt100.clearline)
sys.stdout.flush()
else:
sys.stdout.write(vt100.restore + vt100.reset + vt100.clearline)
@@ -283,7 +284,7 @@ class CallbackModule(CallbackModule_default):
def _display_results(self, result, status):
# Leave the previous task on screen (as it has changes/errors)
if self._display.verbosity == 0 and self.keep:
sys.stdout.write(f"{vt100.restore}{vt100.reset}\n{vt100.save}{vt100.clearline}")
sys.stdout.write(vt100.restore + vt100.reset + '\n' + vt100.save + vt100.clearline)
else:
sys.stdout.write(vt100.restore + vt100.reset + vt100.clearline)
self.keep = False
@@ -308,15 +309,15 @@ class CallbackModule(CallbackModule_default):
if result._task.loop and 'results' in result._result:
self._process_items(result)
else:
sys.stdout.write(f"{colors[status] + status}: ")
sys.stdout.write(colors[status] + status + ': ')
delegated_vars = result._result.get('_ansible_delegated_vars', None)
if delegated_vars:
sys.stdout.write(f"{vt100.reset + result._host.get_name()}>{colors[status]}{delegated_vars['ansible_host']}")
sys.stdout.write(vt100.reset + result._host.get_name() + '>' + colors[status] + delegated_vars['ansible_host'])
else:
sys.stdout.write(result._host.get_name())
sys.stdout.write(f": {dump}\n")
sys.stdout.write(': ' + dump + '\n')
sys.stdout.write(vt100.reset + vt100.save + vt100.clearline)
sys.stdout.flush()
@@ -326,7 +327,7 @@ class CallbackModule(CallbackModule_default):
def v2_playbook_on_play_start(self, play):
# Leave the previous task on screen (as it has changes/errors)
if self._display.verbosity == 0 and self.keep:
sys.stdout.write(f"{vt100.restore}{vt100.reset}\n{vt100.save}{vt100.clearline}{vt100.bold}")
sys.stdout.write(vt100.restore + vt100.reset + '\n' + vt100.save + vt100.clearline + vt100.bold)
else:
sys.stdout.write(vt100.restore + vt100.reset + vt100.clearline + vt100.bold)
@@ -340,14 +341,14 @@ class CallbackModule(CallbackModule_default):
name = play.get_name().strip()
if not name:
name = 'unnamed'
sys.stdout.write(f"PLAY {self.count['play']}: {name.upper()}")
sys.stdout.write(f"{vt100.restore}{vt100.reset}\n{vt100.save}{vt100.clearline}")
sys.stdout.write('PLAY %d: %s' % (self.count['play'], name.upper()))
sys.stdout.write(vt100.restore + vt100.reset + '\n' + vt100.save + vt100.clearline)
sys.stdout.flush()
def v2_playbook_on_task_start(self, task, is_conditional):
# Leave the previous task on screen (as it has changes/errors)
if self._display.verbosity == 0 and self.keep:
sys.stdout.write(f"{vt100.restore}{vt100.reset}\n{vt100.save}{vt100.clearline}{vt100.underline}")
sys.stdout.write(vt100.restore + vt100.reset + '\n' + vt100.save + vt100.clearline + vt100.underline)
else:
# Do not clear line, since we want to retain the previous output
sys.stdout.write(vt100.restore + vt100.reset + vt100.underline)
@@ -364,14 +365,14 @@ class CallbackModule(CallbackModule_default):
self.count['task'] += 1
# Write the next task on screen (behind the prompt is the previous output)
sys.stdout.write(f'{self.type} {self.count[self.type]}.')
sys.stdout.write('%s %d.' % (self.type, self.count[self.type]))
sys.stdout.write(vt100.reset)
sys.stdout.flush()
def v2_playbook_on_handler_task_start(self, task):
# Leave the previous task on screen (as it has changes/errors)
if self._display.verbosity == 0 and self.keep:
sys.stdout.write(f"{vt100.restore}{vt100.reset}\n{vt100.save}{vt100.clearline}{vt100.underline}")
sys.stdout.write(vt100.restore + vt100.reset + '\n' + vt100.save + vt100.clearline + vt100.underline)
else:
sys.stdout.write(vt100.restore + vt100.reset + vt100.clearline + vt100.underline)
@@ -387,7 +388,7 @@ class CallbackModule(CallbackModule_default):
self.count[self.type] += 1
# Write the next task on screen (behind the prompt is the previous output)
sys.stdout.write(f'{self.type} {self.count[self.type]}.')
sys.stdout.write('%s %d.' % (self.type, self.count[self.type]))
sys.stdout.write(vt100.reset)
sys.stdout.flush()
@@ -450,13 +451,13 @@ class CallbackModule(CallbackModule_default):
def v2_playbook_on_no_hosts_remaining(self):
if self._display.verbosity == 0 and self.keep:
sys.stdout.write(f"{vt100.restore}{vt100.reset}\n{vt100.save}{vt100.clearline}")
sys.stdout.write(vt100.restore + vt100.reset + '\n' + vt100.save + vt100.clearline)
else:
sys.stdout.write(vt100.restore + vt100.reset + vt100.clearline)
self.keep = False
sys.stdout.write(f"{vt100.white + vt100.redbg}NO MORE HOSTS LEFT")
sys.stdout.write(f"{vt100.restore}{vt100.reset}\n{vt100.save}{vt100.clearline}")
sys.stdout.write(vt100.white + vt100.redbg + 'NO MORE HOSTS LEFT')
sys.stdout.write(vt100.restore + vt100.reset + '\n' + vt100.save + vt100.clearline)
sys.stdout.flush()
def v2_playbook_on_include(self, included_file):
@@ -464,7 +465,7 @@ class CallbackModule(CallbackModule_default):
def v2_playbook_on_stats(self, stats):
if self._display.verbosity == 0 and self.keep:
sys.stdout.write(f"{vt100.restore}{vt100.reset}\n{vt100.save}{vt100.clearline}")
sys.stdout.write(vt100.restore + vt100.reset + '\n' + vt100.save + vt100.clearline)
else:
sys.stdout.write(vt100.restore + vt100.reset + vt100.clearline)
@@ -475,16 +476,22 @@ class CallbackModule(CallbackModule_default):
sys.stdout.write(vt100.bold + vt100.underline)
sys.stdout.write('SUMMARY')
sys.stdout.write(f"{vt100.restore}{vt100.reset}\n{vt100.save}{vt100.clearline}")
sys.stdout.write(vt100.restore + vt100.reset + '\n' + vt100.save + vt100.clearline)
sys.stdout.flush()
hosts = sorted(stats.processed.keys())
for h in hosts:
t = stats.summarize(h)
self._display.display(
f"{hostcolor(h, t)} : {colorize('ok', t['ok'], C.COLOR_OK)} {colorize('changed', t['changed'], C.COLOR_CHANGED)} "
f"{colorize('unreachable', t['unreachable'], C.COLOR_UNREACHABLE)} {colorize('failed', t['failures'], C.COLOR_ERROR)} "
f"{colorize('rescued', t['rescued'], C.COLOR_OK)} {colorize('ignored', t['ignored'], C.COLOR_WARN)}",
u"%s : %s %s %s %s %s %s" % (
hostcolor(h, t),
colorize(u'ok', t['ok'], C.COLOR_OK),
colorize(u'changed', t['changed'], C.COLOR_CHANGED),
colorize(u'unreachable', t['unreachable'], C.COLOR_UNREACHABLE),
colorize(u'failed', t['failures'], C.COLOR_ERROR),
colorize(u'rescued', t['rescued'], C.COLOR_OK),
colorize(u'ignored', t['ignored'], C.COLOR_WARN),
),
screen_only=True
)

View File

@@ -4,7 +4,8 @@
# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
# SPDX-License-Identifier: GPL-3.0-or-later
from __future__ import annotations
from __future__ import (absolute_import, division, print_function)
__metaclass__ = type
DOCUMENTATION = r"""
name: diy
@@ -785,6 +786,12 @@ from ansible.vars.manager import VariableManager
from ansible.plugins.callback.default import CallbackModule as Default
from ansible.module_utils.common.text.converters import to_text
try:
from ansible.template import trust_as_template # noqa: F401, pylint: disable=unused-import
SUPPORTS_DATA_TAGGING = True
except ImportError:
SUPPORTS_DATA_TAGGING = False
class DummyStdout(object):
def flush(self):
@@ -822,9 +829,9 @@ class CallbackModule(Default):
_callback_options = ['msg', 'msg_color']
for option in _callback_options:
_option_name = f'{_callback_type}_{option}'
_option_name = '%s_%s' % (_callback_type, option)
_option_template = variables.get(
f"{self.DIY_NS}_{_option_name}",
self.DIY_NS + "_" + _option_name,
self.get_option(_option_name)
)
_ret.update({option: self._template(
@@ -838,7 +845,10 @@ class CallbackModule(Default):
return _ret
def _using_diy(self, spec):
return (spec['msg'] is not None) and (spec['msg'] != spec['vars']['omit'])
sentinel = object()
omit = spec['vars'].get('omit', sentinel)
# With Data Tagging, omit is sentinel
return (spec['msg'] is not None) and (spec['msg'] != omit or omit is sentinel)
def _parent_has_callback(self):
return hasattr(super(CallbackModule, self), sys._getframe(1).f_code.co_name)
@@ -861,7 +871,7 @@ class CallbackModule(Default):
handler=None, result=None, stats=None, remove_attr_ref_loop=True):
def _get_value(obj, attr=None, method=None):
if attr:
return getattr(obj, attr, getattr(obj, f"_{attr}", None))
return getattr(obj, attr, getattr(obj, "_" + attr, None))
if method:
_method = getattr(obj, method)
@@ -894,7 +904,7 @@ class CallbackModule(Default):
)
_ret.update(_all)
_ret.update(_ret.get(self.DIY_NS, {self.DIY_NS: CallbackDIYDict()}))
_ret.update(_ret.get(self.DIY_NS, {self.DIY_NS: {} if SUPPORTS_DATA_TAGGING else CallbackDIYDict()}))
_ret[self.DIY_NS].update({'playbook': {}})
_playbook_attributes = ['entries', 'file_name', 'basedir']

View File

@@ -2,7 +2,8 @@
# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
# SPDX-License-Identifier: GPL-3.0-or-later
from __future__ import annotations
from __future__ import (absolute_import, division, print_function)
__metaclass__ = type
DOCUMENTATION = r"""
author: Victor Martinez (@v1v) <VictorMartinezRubio@gmail.com>
@@ -117,7 +118,7 @@ class TaskData:
if host.uuid in self.host_data:
if host.status == 'included':
# concatenate task include output from multiple items
host.result = f'{self.host_data[host.uuid].result}\n{host.result}'
host.result = '%s\n%s' % (self.host_data[host.uuid].result, host.result)
else:
return
@@ -165,7 +166,7 @@ class ElasticSource(object):
args = None
if not task.no_log and not hide_task_arguments:
args = ', '.join((f'{k}={v}' for k, v in task.args.items()))
args = ', '.join(('%s=%s' % a for a in task.args.items()))
tasks_data[uuid] = TaskData(uuid, name, path, play_name, action, args)
@@ -224,7 +225,7 @@ class ElasticSource(object):
def create_span_data(self, apm_cli, task_data, host_data):
""" create the span with the given TaskData and HostData """
name = f'[{host_data.name}] {task_data.play}: {task_data.name}'
name = '[%s] %s: %s' % (host_data.name, task_data.play, task_data.name)
message = "success"
status = "success"
@@ -258,7 +259,7 @@ class ElasticSource(object):
"ansible.task.host.status": host_data.status}) as span:
span.outcome = status
if 'failure' in status:
exception = AnsibleRuntimeError(message=f"{task_data.action}: {name} failed with error message {enriched_error_message}")
exception = AnsibleRuntimeError(message="{0}: {1} failed with error message {2}".format(task_data.action, name, enriched_error_message))
apm_cli.capture_exception(exc_info=(type(exception), exception, exception.__traceback__), handled=True)
def init_apm_client(self, apm_server_url, apm_service_name, apm_verify_server_cert, apm_secret_token, apm_api_key):
@@ -287,7 +288,7 @@ class ElasticSource(object):
message = result.get('msg', 'failed')
exception = result.get('exception')
stderr = result.get('stderr')
return f"message: \"{message}\"\nexception: \"{exception}\"\nstderr: \"{stderr}\""
return ('message: "{0}"\nexception: "{1}"\nstderr: "{2}"').format(message, exception, stderr)
class CallbackModule(CallbackBase):

240
plugins/callback/hipchat.py Normal file
View File

@@ -0,0 +1,240 @@
# -*- coding: utf-8 -*-
# Copyright (c) 2014, Matt Martz <matt@sivel.net>
# Copyright (c) 2017 Ansible Project
# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
# SPDX-License-Identifier: GPL-3.0-or-later
from __future__ import (absolute_import, division, print_function)
__metaclass__ = type
DOCUMENTATION = '''
author: Unknown (!UNKNOWN)
name: hipchat
type: notification
requirements:
- whitelist in configuration.
- prettytable (python lib)
short_description: post task events to hipchat
description:
- This callback plugin sends status updates to a HipChat channel during playbook execution.
- Before 2.4 only environment variables were available for configuring this plugin.
deprecated:
removed_in: 10.0.0
why: The hipchat service has been discontinued and the self-hosted variant has been End of Life since 2020.
alternative: There is none.
options:
token:
description: HipChat API token for v1 or v2 API.
type: str
required: true
env:
- name: HIPCHAT_TOKEN
ini:
- section: callback_hipchat
key: token
api_version:
description: HipChat API version, v1 or v2.
type: str
choices:
- v1
- v2
required: false
default: v1
env:
- name: HIPCHAT_API_VERSION
ini:
- section: callback_hipchat
key: api_version
room:
description: HipChat room to post in.
type: str
default: ansible
env:
- name: HIPCHAT_ROOM
ini:
- section: callback_hipchat
key: room
from:
description: Name to post as
type: str
default: ansible
env:
- name: HIPCHAT_FROM
ini:
- section: callback_hipchat
key: from
notify:
description: Add notify flag to important messages
type: bool
default: true
env:
- name: HIPCHAT_NOTIFY
ini:
- section: callback_hipchat
key: notify
'''
import os
import json
try:
import prettytable
HAS_PRETTYTABLE = True
except ImportError:
HAS_PRETTYTABLE = False
from ansible.plugins.callback import CallbackBase
from ansible.module_utils.six.moves.urllib.parse import urlencode
from ansible.module_utils.urls import open_url
class CallbackModule(CallbackBase):
"""This is an example ansible callback plugin that sends status
updates to a HipChat channel during playbook execution.
"""
CALLBACK_VERSION = 2.0
CALLBACK_TYPE = 'notification'
CALLBACK_NAME = 'community.general.hipchat'
CALLBACK_NEEDS_WHITELIST = True
API_V1_URL = 'https://api.hipchat.com/v1/rooms/message'
API_V2_URL = 'https://api.hipchat.com/v2/'
def __init__(self):
super(CallbackModule, self).__init__()
if not HAS_PRETTYTABLE:
self.disabled = True
self._display.warning('The `prettytable` python module is not installed. '
'Disabling the HipChat callback plugin.')
self.printed_playbook = False
self.playbook_name = None
self.play = None
def set_options(self, task_keys=None, var_options=None, direct=None):
super(CallbackModule, self).set_options(task_keys=task_keys, var_options=var_options, direct=direct)
self.token = self.get_option('token')
self.api_version = self.get_option('api_version')
self.from_name = self.get_option('from')
self.allow_notify = self.get_option('notify')
self.room = self.get_option('room')
if self.token is None:
self.disabled = True
self._display.warning('HipChat token could not be loaded. The HipChat '
'token can be provided using the `HIPCHAT_TOKEN` '
'environment variable.')
# Pick the request handler.
if self.api_version == 'v2':
self.send_msg = self.send_msg_v2
else:
self.send_msg = self.send_msg_v1
def send_msg_v2(self, msg, msg_format='text', color='yellow', notify=False):
"""Method for sending a message to HipChat"""
headers = {'Authorization': 'Bearer %s' % self.token, 'Content-Type': 'application/json'}
body = {}
body['room_id'] = self.room
body['from'] = self.from_name[:15] # max length is 15
body['message'] = msg
body['message_format'] = msg_format
body['color'] = color
body['notify'] = self.allow_notify and notify
data = json.dumps(body)
url = self.API_V2_URL + "room/{room_id}/notification".format(room_id=self.room)
try:
response = open_url(url, data=data, headers=headers, method='POST')
return response.read()
except Exception as ex:
self._display.warning('Could not submit message to hipchat: {0}'.format(ex))
def send_msg_v1(self, msg, msg_format='text', color='yellow', notify=False):
"""Method for sending a message to HipChat"""
params = {}
params['room_id'] = self.room
params['from'] = self.from_name[:15] # max length is 15
params['message'] = msg
params['message_format'] = msg_format
params['color'] = color
params['notify'] = int(self.allow_notify and notify)
url = ('%s?auth_token=%s' % (self.API_V1_URL, self.token))
try:
response = open_url(url, data=urlencode(params))
return response.read()
except Exception as ex:
self._display.warning('Could not submit message to hipchat: {0}'.format(ex))
def v2_playbook_on_play_start(self, play):
"""Display Playbook and play start messages"""
self.play = play
name = play.name
# This block sends information about a playbook when it starts
# The playbook object is not immediately available at
# playbook_on_start so we grab it via the play
#
# Displays info about playbook being started by a person on an
# inventory, as well as Tags, Skip Tags and Limits
if not self.printed_playbook:
self.playbook_name, dummy = os.path.splitext(os.path.basename(self.play.playbook.filename))
host_list = self.play.playbook.inventory.host_list
inventory = os.path.basename(os.path.realpath(host_list))
self.send_msg("%s: Playbook initiated by %s against %s" %
(self.playbook_name,
self.play.playbook.remote_user,
inventory), notify=True)
self.printed_playbook = True
subset = self.play.playbook.inventory._subset
skip_tags = self.play.playbook.skip_tags
self.send_msg("%s:\nTags: %s\nSkip Tags: %s\nLimit: %s" %
(self.playbook_name,
', '.join(self.play.playbook.only_tags),
', '.join(skip_tags) if skip_tags else None,
', '.join(subset) if subset else subset))
# This is where we actually say we are starting a play
self.send_msg("%s: Starting play: %s" %
(self.playbook_name, name))
def playbook_on_stats(self, stats):
"""Display info about playbook statistics"""
hosts = sorted(stats.processed.keys())
t = prettytable.PrettyTable(['Host', 'Ok', 'Changed', 'Unreachable',
'Failures'])
failures = False
unreachable = False
for h in hosts:
s = stats.summarize(h)
if s['failures'] > 0:
failures = True
if s['unreachable'] > 0:
unreachable = True
t.add_row([h] + [s[k] for k in ['ok', 'changed', 'unreachable',
'failures']])
self.send_msg("%s: Playbook complete" % self.playbook_name,
notify=True)
if failures or unreachable:
color = 'red'
self.send_msg("%s: Failures detected" % self.playbook_name,
color=color, notify=True)
else:
color = 'green'
self.send_msg("/code %s:\n%s" % (self.playbook_name, t), color=color)

View File

@@ -4,7 +4,8 @@
# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
# SPDX-License-Identifier: GPL-3.0-or-later
from __future__ import annotations
from __future__ import (absolute_import, division, print_function)
__metaclass__ = type
DOCUMENTATION = r"""
author: Unknown (!UNKNOWN)
@@ -101,7 +102,7 @@ class CallbackModule(CallbackBase):
"""Display Playbook and play start messages"""
self.play = play
name = play.name
self.send_msg(f"Ansible starting play: {name}")
self.send_msg("Ansible starting play: %s" % (name))
def playbook_on_stats(self, stats):
name = self.play
@@ -117,7 +118,7 @@ class CallbackModule(CallbackBase):
if failures or unreachable:
out = self.debug
self.send_msg(f"{name}: Failures detected \n{self.task} \nHost: {h}\n Failed at:\n{out}")
self.send_msg("%s: Failures detected \n%s \nHost: %s\n Failed at:\n%s" % (name, self.task, h, out))
else:
out = self.debug
self.send_msg(f"Great! \n Playbook {name} completed:\n{s} \n Last task debug:\n {out}")
self.send_msg("Great! \n Playbook %s completed:\n%s \n Last task debug:\n %s" % (name, s, out))

View File

@@ -4,7 +4,8 @@
# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
# SPDX-License-Identifier: GPL-3.0-or-later
from __future__ import annotations
from __future__ import (absolute_import, division, print_function)
__metaclass__ = type
DOCUMENTATION = r"""
author: Unknown (!UNKNOWN)
@@ -56,10 +57,7 @@ class CallbackModule(CallbackBase):
CALLBACK_NEEDS_WHITELIST = True
TIME_FORMAT = "%b %d %Y %H:%M:%S"
@staticmethod
def _make_msg(now, playbook, task_name, task_action, category, data):
return f"{now} - {playbook} - {task_name} - {task_action} - {category} - {data}\n\n"
MSG_FORMAT = "%(now)s - %(playbook)s - %(task_name)s - %(task_action)s - %(category)s - %(data)s\n\n"
def __init__(self):
@@ -84,12 +82,22 @@ class CallbackModule(CallbackBase):
invocation = data.pop('invocation', None)
data = json.dumps(data, cls=AnsibleJSONEncoder)
if invocation is not None:
data = f"{json.dumps(invocation)} => {data} "
data = json.dumps(invocation) + " => %s " % data
path = os.path.join(self.log_folder, result._host.get_name())
now = time.strftime(self.TIME_FORMAT, time.localtime())
msg = to_bytes(self._make_msg(now, self.playbook, result._task.name, result._task.action, category, data))
msg = to_bytes(
self.MSG_FORMAT
% dict(
now=now,
playbook=self.playbook,
task_name=result._task.name,
task_action=result._task.action,
category=category,
data=data,
)
)
with open(path, "ab") as fd:
fd.write(msg)

View File

@@ -3,7 +3,8 @@
# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
# SPDX-License-Identifier: GPL-3.0-or-later
from __future__ import annotations
from __future__ import (absolute_import, division, print_function)
__metaclass__ = type
DOCUMENTATION = r"""
name: loganalytics
@@ -83,17 +84,18 @@ class AzureLogAnalyticsSource(object):
def __build_signature(self, date, workspace_id, shared_key, content_length):
# Build authorisation signature for Azure log analytics API call
sigs = f"POST\n{content_length}\napplication/json\nx-ms-date:{date}\n/api/logs"
sigs = "POST\n{0}\napplication/json\nx-ms-date:{1}\n/api/logs".format(
str(content_length), date)
utf8_sigs = sigs.encode('utf-8')
decoded_shared_key = base64.b64decode(shared_key)
hmac_sha256_sigs = hmac.new(
decoded_shared_key, utf8_sigs, digestmod=hashlib.sha256).digest()
encoded_hash = base64.b64encode(hmac_sha256_sigs).decode('utf-8')
signature = f"SharedKey {workspace_id}:{encoded_hash}"
signature = "SharedKey {0}:{1}".format(workspace_id, encoded_hash)
return signature
def __build_workspace_url(self, workspace_id):
return f"https://{workspace_id}.ods.opinsights.azure.com/api/logs?api-version=2016-04-01"
return "https://{0}.ods.opinsights.azure.com/api/logs?api-version=2016-04-01".format(workspace_id)
def __rfc1123date(self):
return now().strftime('%a, %d %b %Y %H:%M:%S GMT')

View File

@@ -3,7 +3,8 @@
# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
# SPDX-License-Identifier: GPL-3.0-or-later
from __future__ import annotations
from __future__ import (absolute_import, division, print_function)
__metaclass__ = type
DOCUMENTATION = r"""
author: Unknown (!UNKNOWN)
@@ -72,7 +73,7 @@ except ImportError:
# Getting MAC Address of system:
def get_mac():
mac = f"{getnode():012x}"
mac = "%012x" % getnode()
return ":".join(map(lambda index: mac[index:index + 2], range(int(len(mac) / 2))))
@@ -160,7 +161,7 @@ class CallbackModule(CallbackBase):
if ninvalidKeys > 0:
for key in invalidKeys:
del meta[key]
meta['__errors'] = f"These keys have been sanitized: {', '.join(invalidKeys)}"
meta['__errors'] = 'These keys have been sanitized: ' + ', '.join(invalidKeys)
return meta
def sanitizeJSON(self, data):

View File

@@ -3,7 +3,8 @@
# Copyright (c) 2017 Ansible Project
# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
# SPDX-License-Identifier: GPL-3.0-or-later
from __future__ import annotations
from __future__ import (absolute_import, division, print_function)
__metaclass__ = type
DOCUMENTATION = r"""
author: Unknown (!UNKNOWN)
@@ -132,7 +133,7 @@ class PlainTextSocketAppender(object):
# Error message displayed when an incorrect Token has been detected
self.INVALID_TOKEN = "\n\nIt appears the LOGENTRIES_TOKEN parameter you entered is incorrect!\n\n"
# Unicode Line separator character \u2028
self.LINE_SEP = '\u2028'
self.LINE_SEP = u'\u2028'
self._display = display
self._conn = None
@@ -150,7 +151,7 @@ class PlainTextSocketAppender(object):
self.open_connection()
return
except Exception as e:
self._display.vvvv(f"Unable to connect to Logentries: {e}")
self._display.vvvv(u"Unable to connect to Logentries: %s" % to_text(e))
root_delay *= 2
if root_delay > self.MAX_DELAY:
@@ -159,7 +160,7 @@ class PlainTextSocketAppender(object):
wait_for = root_delay + random.uniform(0, root_delay)
try:
self._display.vvvv(f"sleeping {wait_for} before retry")
self._display.vvvv("sleeping %s before retry" % wait_for)
time.sleep(wait_for)
except KeyboardInterrupt:
raise
@@ -172,8 +173,8 @@ class PlainTextSocketAppender(object):
# Replace newlines with Unicode line separator
# for multi-line events
data = to_text(data, errors='surrogate_or_strict')
multiline = data.replace('\n', self.LINE_SEP)
multiline += "\n"
multiline = data.replace(u'\n', self.LINE_SEP)
multiline += u"\n"
# Send data, reconnect if needed
while True:
try:
@@ -246,7 +247,7 @@ class CallbackModule(CallbackBase):
self.use_tls = self.get_option('use_tls')
self.flatten = self.get_option('flatten')
except KeyError as e:
self._display.warning(f"Missing option for Logentries callback plugin: {e}")
self._display.warning(u"Missing option for Logentries callback plugin: %s" % to_text(e))
self.disabled = True
try:
@@ -265,10 +266,10 @@ class CallbackModule(CallbackBase):
if not self.disabled:
if self.use_tls:
self._display.vvvv(f"Connecting to {self.api_url}:{self.api_tls_port} with TLS")
self._display.vvvv("Connecting to %s:%s with TLS" % (self.api_url, self.api_tls_port))
self._appender = TLSSocketAppender(display=self._display, LE_API=self.api_url, LE_TLS_PORT=self.api_tls_port)
else:
self._display.vvvv(f"Connecting to {self.api_url}:{self.api_port}")
self._display.vvvv("Connecting to %s:%s" % (self.api_url, self.api_port))
self._appender = PlainTextSocketAppender(display=self._display, LE_API=self.api_url, LE_PORT=self.api_port)
self._appender.reopen_connection()
@@ -281,7 +282,7 @@ class CallbackModule(CallbackBase):
def emit(self, record):
msg = record.rstrip('\n')
msg = f"{self.token} {msg}"
msg = "{0} {1}".format(self.token, msg)
self._appender.put(msg)
self._display.vvvv("Sent event to logentries")

View File

@@ -4,7 +4,8 @@
# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
# SPDX-License-Identifier: GPL-3.0-or-later
from __future__ import annotations
from __future__ import (absolute_import, division, print_function)
__metaclass__ = type
DOCUMENTATION = r"""
author: Yevhen Khmelenko (@ujenmr)

View File

@@ -4,7 +4,8 @@
# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
# SPDX-License-Identifier: GPL-3.0-or-later
from __future__ import annotations
from __future__ import (absolute_import, division, print_function)
__metaclass__ = type
DOCUMENTATION = r"""
name: mail
@@ -133,14 +134,14 @@ class CallbackModule(CallbackBase):
if self.bcc:
bcc_addresses = email.utils.getaddresses(self.bcc)
content = f'Date: {email.utils.formatdate()}\n'
content += f'From: {email.utils.formataddr(sender_address)}\n'
content = 'Date: %s\n' % email.utils.formatdate()
content += 'From: %s\n' % email.utils.formataddr(sender_address)
if self.to:
content += f"To: {', '.join([email.utils.formataddr(pair) for pair in to_addresses])}\n"
content += 'To: %s\n' % ', '.join([email.utils.formataddr(pair) for pair in to_addresses])
if self.cc:
content += f"Cc: {', '.join([email.utils.formataddr(pair) for pair in cc_addresses])}\n"
content += f"Message-ID: {email.utils.make_msgid(domain=self.get_option('message_id_domain'))}\n"
content += f'Subject: {subject.strip()}\n\n'
content += 'Cc: %s\n' % ', '.join([email.utils.formataddr(pair) for pair in cc_addresses])
content += 'Message-ID: %s\n' % email.utils.make_msgid(domain=self.get_option('message_id_domain'))
content += 'Subject: %s\n\n' % subject.strip()
content += body
addresses = to_addresses
@@ -157,22 +158,23 @@ class CallbackModule(CallbackBase):
smtp.quit()
def subject_msg(self, multiline, failtype, linenr):
msg = multiline.strip('\r\n').splitlines()[linenr]
return f'{failtype}: {msg}'
return '%s: %s' % (failtype, multiline.strip('\r\n').splitlines()[linenr])
def indent(self, multiline, indent=8):
return re.sub('^', ' ' * indent, multiline, flags=re.MULTILINE)
def body_blob(self, multiline, texttype):
''' Turn some text output in a well-indented block for sending in a mail body '''
intro = f'with the following {texttype}:\n\n'
blob = "\n".join(multiline.strip('\r\n').splitlines())
return f"{intro}{self.indent(blob)}\n"
intro = 'with the following %s:\n\n' % texttype
blob = ''
for line in multiline.strip('\r\n').splitlines():
blob += '%s\n' % line
return intro + self.indent(blob) + '\n'
def mail_result(self, result, failtype):
host = result._host.get_name()
if not self.sender:
self.sender = f'"Ansible: {host}" <root>'
self.sender = '"Ansible: %s" <root>' % host
# Add subject
if self.itembody:
@@ -188,32 +190,31 @@ class CallbackModule(CallbackBase):
elif result._result.get('exception'): # Unrelated exceptions are added to output :-/
subject = self.subject_msg(result._result['exception'], failtype, -1)
else:
subject = f'{failtype}: {result._task.name or result._task.action}'
subject = '%s: %s' % (failtype, result._task.name or result._task.action)
# Make playbook name visible (e.g. in Outlook/Gmail condensed view)
body = f'Playbook: {os.path.basename(self.playbook._file_name)}\n'
body = 'Playbook: %s\n' % os.path.basename(self.playbook._file_name)
if result._task.name:
body += f'Task: {result._task.name}\n'
body += f'Module: {result._task.action}\n'
body += f'Host: {host}\n'
body += 'Task: %s\n' % result._task.name
body += 'Module: %s\n' % result._task.action
body += 'Host: %s\n' % host
body += '\n'
# Add task information (as much as possible)
body += 'The following task failed:\n\n'
if 'invocation' in result._result:
body += self.indent(f"{result._task.action}: {json.dumps(result._result['invocation']['module_args'], indent=4)}\n")
body += self.indent('%s: %s\n' % (result._task.action, json.dumps(result._result['invocation']['module_args'], indent=4)))
elif result._task.name:
body += self.indent(f'{result._task.name} ({result._task.action})\n')
body += self.indent('%s (%s)\n' % (result._task.name, result._task.action))
else:
body += self.indent(f'{result._task.action}\n')
body += self.indent('%s\n' % result._task.action)
body += '\n'
# Add item / message
if self.itembody:
body += self.itembody
elif result._result.get('failed_when_result') is True:
fail_cond = self.indent('failed_when:\n- ' + '\n- '.join(result._task.failed_when))
body += f"due to the following condition:\n\n{fail_cond}\n\n"
body += "due to the following condition:\n\n" + self.indent('failed_when:\n- ' + '\n- '.join(result._task.failed_when)) + '\n\n'
elif result._result.get('msg'):
body += self.body_blob(result._result['msg'], 'message')
@@ -226,13 +227,13 @@ class CallbackModule(CallbackBase):
body += self.body_blob(result._result['exception'], 'exception')
if result._result.get('warnings'):
for i in range(len(result._result.get('warnings'))):
body += self.body_blob(result._result['warnings'][i], f'exception {i + 1}')
body += self.body_blob(result._result['warnings'][i], 'exception %d' % (i + 1))
if result._result.get('deprecations'):
for i in range(len(result._result.get('deprecations'))):
body += self.body_blob(result._result['deprecations'][i], f'exception {i + 1}')
body += self.body_blob(result._result['deprecations'][i], 'exception %d' % (i + 1))
body += 'and a complete dump of the error:\n\n'
body += self.indent(f'{failtype}: {json.dumps(result._result, cls=AnsibleJSONEncoder, indent=4)}')
body += self.indent('%s: %s' % (failtype, json.dumps(result._result, cls=AnsibleJSONEncoder, indent=4)))
self.mail(subject=subject, body=body)
@@ -255,4 +256,4 @@ class CallbackModule(CallbackBase):
def v2_runner_item_on_failed(self, result):
# Pass item information to task failure
self.itemsubject = result._result['msg']
self.itembody += self.body_blob(json.dumps(result._result, cls=AnsibleJSONEncoder, indent=4), f"failed item dump '{result._result['item']}'")
self.itembody += self.body_blob(json.dumps(result._result, cls=AnsibleJSONEncoder, indent=4), "failed item dump '%(item)s'" % result._result)

View File

@@ -4,7 +4,8 @@
# SPDX-License-Identifier: GPL-3.0-or-later
# Make coding more python3-ish
from __future__ import annotations
from __future__ import (absolute_import, division, print_function)
__metaclass__ = type
DOCUMENTATION = r"""
name: nrdp
@@ -131,10 +132,10 @@ class CallbackModule(CallbackBase):
xmldata = "<?xml version='1.0'?>\n"
xmldata += "<checkresults>\n"
xmldata += "<checkresult type='service'>\n"
xmldata += f"<hostname>{self.hostname}</hostname>\n"
xmldata += f"<servicename>{self.servicename}</servicename>\n"
xmldata += f"<state>{state}</state>\n"
xmldata += f"<output>{msg}</output>\n"
xmldata += "<hostname>%s</hostname>\n" % self.hostname
xmldata += "<servicename>%s</servicename>\n" % self.servicename
xmldata += "<state>%d</state>\n" % state
xmldata += "<output>%s</output>\n" % msg
xmldata += "</checkresult>\n"
xmldata += "</checkresults>\n"
@@ -151,7 +152,7 @@ class CallbackModule(CallbackBase):
validate_certs=self.validate_nrdp_certs)
return response.read()
except Exception as ex:
self._display.warning(f"NRDP callback cannot send result {ex}")
self._display.warning("NRDP callback cannot send result {0}".format(ex))
def v2_playbook_on_play_start(self, play):
'''
@@ -169,16 +170,17 @@ class CallbackModule(CallbackBase):
critical = warning = 0
for host in hosts:
stat = stats.summarize(host)
gstats += (
f"'{host}_ok'={stat['ok']} '{host}_changed'={stat['changed']} '{host}_unreachable'={stat['unreachable']} '{host}_failed'={stat['failures']} "
)
gstats += "'%s_ok'=%d '%s_changed'=%d \
'%s_unreachable'=%d '%s_failed'=%d " % \
(host, stat['ok'], host, stat['changed'],
host, stat['unreachable'], host, stat['failures'])
# Critical when failed tasks or unreachable host
critical += stat['failures']
critical += stat['unreachable']
# Warning when changed tasks
warning += stat['changed']
msg = f"{name} | {gstats}"
msg = "%s | %s" % (name, gstats)
if critical:
# Send Critical
self._send_nrdp(self.CRITICAL, msg)

View File

@@ -4,7 +4,8 @@
# SPDX-License-Identifier: GPL-3.0-or-later
# Make coding more python3-ish
from __future__ import annotations
from __future__ import (absolute_import, division, print_function)
__metaclass__ = type
DOCUMENTATION = r"""
author: Unknown (!UNKNOWN)

View File

@@ -3,7 +3,8 @@
# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
# SPDX-License-Identifier: GPL-3.0-or-later
from __future__ import annotations
from __future__ import (absolute_import, division, print_function)
__metaclass__ = type
DOCUMENTATION = r"""
author: Victor Martinez (@v1v) <VictorMartinezRubio@gmail.com>
@@ -136,8 +137,9 @@ import getpass
import json
import os
import socket
import sys
import time
import uuid
from time import time_ns
from collections import OrderedDict
from os.path import basename
@@ -163,12 +165,31 @@ try:
from opentelemetry.sdk.trace.export.in_memory_span_exporter import (
InMemorySpanExporter
)
# Support for opentelemetry-api <= 1.12
try:
from opentelemetry.util._time import _time_ns
except ImportError as imp_exc:
OTEL_LIBRARY_TIME_NS_ERROR = imp_exc
else:
OTEL_LIBRARY_TIME_NS_ERROR = None
except ImportError as imp_exc:
OTEL_LIBRARY_IMPORT_ERROR = imp_exc
OTEL_LIBRARY_TIME_NS_ERROR = imp_exc
else:
OTEL_LIBRARY_IMPORT_ERROR = None
if sys.version_info >= (3, 7):
time_ns = time.time_ns
elif not OTEL_LIBRARY_TIME_NS_ERROR:
time_ns = _time_ns
else:
def time_ns():
# Support versions older than 3.7 with opentelemetry-api > 1.12
return int(time.time() * 1e9)
class TaskData:
"""
Data about an individual task.
@@ -189,7 +210,7 @@ class TaskData:
if host.uuid in self.host_data:
if host.status == 'included':
# concatenate task include output from multiple items
host.result = f'{self.host_data[host.uuid].result}\n{host.result}'
host.result = '%s\n%s' % (self.host_data[host.uuid].result, host.result)
else:
return
@@ -327,7 +348,7 @@ class OpenTelemetrySource(object):
def update_span_data(self, task_data, host_data, span, disable_logs, disable_attributes_in_logs):
""" update the span with the given TaskData and HostData """
name = f'[{host_data.name}] {task_data.play}: {task_data.name}'
name = '[%s] %s: %s' % (host_data.name, task_data.play, task_data.name)
message = 'success'
res = {}
@@ -450,7 +471,7 @@ class OpenTelemetrySource(object):
def get_error_message_from_results(results, action):
for result in results:
if result.get('failed', False):
return f"{action}({result.get('item', 'none')}) - {OpenTelemetrySource.get_error_message(result)}"
return ('{0}({1}) - {2}').format(action, result.get('item', 'none'), OpenTelemetrySource.get_error_message(result))
@staticmethod
def _last_line(text):
@@ -462,14 +483,14 @@ class OpenTelemetrySource(object):
message = result.get('msg', 'failed')
exception = result.get('exception')
stderr = result.get('stderr')
return f"message: \"{message}\"\nexception: \"{exception}\"\nstderr: \"{stderr}\""
return ('message: "{0}"\nexception: "{1}"\nstderr: "{2}"').format(message, exception, stderr)
@staticmethod
def enrich_error_message_from_results(results, action):
message = ""
for result in results:
if result.get('failed', False):
message = f"{action}({result.get('item', 'none')}) - {OpenTelemetrySource.enrich_error_message(result)}\n{message}"
message = ('{0}({1}) - {2}\n{3}').format(action, result.get('item', 'none'), OpenTelemetrySource.enrich_error_message(result), message)
return message
@@ -515,9 +536,8 @@ class CallbackModule(CallbackBase):
environment_variable = self.get_option('enable_from_environment')
if environment_variable is not None and os.environ.get(environment_variable, 'false').lower() != 'true':
self.disabled = True
self._display.warning(
f"The `enable_from_environment` option has been set and {environment_variable} is not enabled. Disabling the `opentelemetry` callback plugin."
)
self._display.warning("The `enable_from_environment` option has been set and {0} is not enabled. "
"Disabling the `opentelemetry` callback plugin.".format(environment_variable))
self.hide_task_arguments = self.get_option('hide_task_arguments')

View File

@@ -5,7 +5,8 @@
# SPDX-License-Identifier: GPL-3.0-or-later
# Make coding more python3-ish
from __future__ import annotations
from __future__ import (absolute_import, division, print_function)
__metaclass__ = type
DOCUMENTATION = r"""
author: Unknown (!UNKNOWN)
@@ -49,7 +50,7 @@ class CallbackModule(CallbackBase):
self.synthesizer = get_bin_path('say')
if platform.system() != 'Darwin':
# 'say' binary available, it might be GNUstep tool which doesn't support 'voice' parameter
self._display.warning(f"'say' executable found but system is '{platform.system()}': ignoring voice parameter")
self._display.warning("'say' executable found but system is '%s': ignoring voice parameter" % platform.system())
else:
self.FAILED_VOICE = 'Zarvox'
self.REGULAR_VOICE = 'Trinoids'
@@ -68,7 +69,7 @@ class CallbackModule(CallbackBase):
# ansible will not call any callback if disabled is set to True
if not self.synthesizer:
self.disabled = True
self._display.warning(f"Unable to find either 'say' or 'espeak' executable, plugin {os.path.basename(__file__)} disabled")
self._display.warning("Unable to find either 'say' or 'espeak' executable, plugin %s disabled" % os.path.basename(__file__))
def say(self, msg, voice):
cmd = [self.synthesizer, msg]
@@ -77,7 +78,7 @@ class CallbackModule(CallbackBase):
subprocess.call(cmd)
def runner_on_failed(self, host, res, ignore_errors=False):
self.say(f"Failure on host {host}", self.FAILED_VOICE)
self.say("Failure on host %s" % host, self.FAILED_VOICE)
def runner_on_ok(self, host, res):
self.say("pew", self.LASER_VOICE)
@@ -86,13 +87,13 @@ class CallbackModule(CallbackBase):
self.say("pew", self.LASER_VOICE)
def runner_on_unreachable(self, host, res):
self.say(f"Failure on host {host}", self.FAILED_VOICE)
self.say("Failure on host %s" % host, self.FAILED_VOICE)
def runner_on_async_ok(self, host, res, jid):
self.say("pew", self.LASER_VOICE)
def runner_on_async_failed(self, host, res, jid):
self.say(f"Failure on host {host}", self.FAILED_VOICE)
self.say("Failure on host %s" % host, self.FAILED_VOICE)
def playbook_on_start(self):
self.say("Running Playbook", self.REGULAR_VOICE)
@@ -102,15 +103,15 @@ class CallbackModule(CallbackBase):
def playbook_on_task_start(self, name, is_conditional):
if not is_conditional:
self.say(f"Starting task: {name}", self.REGULAR_VOICE)
self.say("Starting task: %s" % name, self.REGULAR_VOICE)
else:
self.say(f"Notifying task: {name}", self.REGULAR_VOICE)
self.say("Notifying task: %s" % name, self.REGULAR_VOICE)
def playbook_on_setup(self):
self.say("Gathering facts", self.REGULAR_VOICE)
def playbook_on_play_start(self, name):
self.say(f"Starting play: {name}", self.HAPPY_VOICE)
self.say("Starting play: %s" % name, self.HAPPY_VOICE)
def playbook_on_stats(self, stats):
self.say("Play complete", self.HAPPY_VOICE)

View File

@@ -4,7 +4,8 @@
# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
# SPDX-License-Identifier: GPL-3.0-or-later
from __future__ import annotations
from __future__ import (absolute_import, division, print_function)
__metaclass__ = type
DOCUMENTATION = r"""
author: Unknown (!UNKNOWN)
@@ -47,13 +48,13 @@ from ansible.module_utils.common.text.converters import to_text
DONT_COLORIZE = False
COLORS = {
'normal': '\033[0m',
'ok': f'\x1b[{C.COLOR_CODES[C.COLOR_OK]}m',
'ok': '\033[{0}m'.format(C.COLOR_CODES[C.COLOR_OK]),
'bold': '\033[1m',
'not_so_bold': '\033[1m\033[34m',
'changed': f'\x1b[{C.COLOR_CODES[C.COLOR_CHANGED]}m',
'failed': f'\x1b[{C.COLOR_CODES[C.COLOR_ERROR]}m',
'changed': '\033[{0}m'.format(C.COLOR_CODES[C.COLOR_CHANGED]),
'failed': '\033[{0}m'.format(C.COLOR_CODES[C.COLOR_ERROR]),
'endc': '\033[0m',
'skipped': f'\x1b[{C.COLOR_CODES[C.COLOR_SKIP]}m',
'skipped': '\033[{0}m'.format(C.COLOR_CODES[C.COLOR_SKIP]),
}
@@ -72,7 +73,7 @@ def colorize(msg, color):
if DONT_COLORIZE:
return msg
else:
return f"{COLORS[color]}{msg}{COLORS['endc']}"
return '{0}{1}{2}'.format(COLORS[color], msg, COLORS['endc'])
class CallbackModule(CallbackBase):
@@ -105,15 +106,15 @@ class CallbackModule(CallbackBase):
line_length = 120
if self.last_skipped:
print()
line = f"# {task_name} "
msg = colorize(f"{line}{'*' * (line_length - len(line))}", 'bold')
line = "# {0} ".format(task_name)
msg = colorize("{0}{1}".format(line, '*' * (line_length - len(line))), 'bold')
print(msg)
def _indent_text(self, text, indent_level):
lines = text.splitlines()
result_lines = []
for l in lines:
result_lines.append(f"{' ' * indent_level}{l}")
result_lines.append("{0}{1}".format(' ' * indent_level, l))
return '\n'.join(result_lines)
def _print_diff(self, diff, indent_level):
@@ -146,19 +147,19 @@ class CallbackModule(CallbackBase):
change_string = colorize('FAILED!!!', color)
else:
color = 'changed' if changed else 'ok'
change_string = colorize(f"changed={changed}", color)
change_string = colorize("changed={0}".format(changed), color)
msg = colorize(msg, color)
line_length = 120
spaces = ' ' * (40 - len(name) - indent_level)
line = f"{' ' * indent_level} * {name}{spaces}- {change_string}"
line = "{0} * {1}{2}- {3}".format(' ' * indent_level, name, spaces, change_string)
if len(msg) < 50:
line += f' -- {msg}'
print(f"{line} {'-' * (line_length - len(line))}---------")
line += ' -- {0}'.format(msg)
print("{0} {1}---------".format(line, '-' * (line_length - len(line))))
else:
print(f"{line} {'-' * (line_length - len(line))}")
print("{0} {1}".format(line, '-' * (line_length - len(line))))
print(self._indent_text(msg, indent_level + 4))
if diff:
@@ -238,10 +239,8 @@ class CallbackModule(CallbackBase):
else:
color = 'ok'
msg = (
f"{host} : ok={s['ok']}\tchanged={s['changed']}\tfailed={s['failures']}\tunreachable="
f"{s['unreachable']}\trescued={s['rescued']}\tignored={s['ignored']}"
)
msg = '{0} : ok={1}\tchanged={2}\tfailed={3}\tunreachable={4}\trescued={5}\tignored={6}'.format(
host, s['ok'], s['changed'], s['failures'], s['unreachable'], s['rescued'], s['ignored'])
print(colorize(msg, color))
def v2_runner_on_skipped(self, result, **kwargs):
@@ -253,15 +252,17 @@ class CallbackModule(CallbackBase):
line_length = 120
spaces = ' ' * (31 - len(result._host.name) - 4)
line = f" * {colorize(result._host.name, 'not_so_bold')}{spaces}- {colorize('skipped', 'skipped')}"
line = " * {0}{1}- {2}".format(colorize(result._host.name, 'not_so_bold'),
spaces,
colorize("skipped", 'skipped'),)
reason = result._result.get('skipped_reason', '') or \
result._result.get('skip_reason', '')
if len(reason) < 50:
line += f' -- {reason}'
print(f"{line} {'-' * (line_length - len(line))}---------")
line += ' -- {0}'.format(reason)
print("{0} {1}---------".format(line, '-' * (line_length - len(line))))
else:
print(f"{line} {'-' * (line_length - len(line))}")
print("{0} {1}".format(line, '-' * (line_length - len(line))))
print(self._indent_text(reason, 8))
print(reason)

View File

@@ -5,7 +5,8 @@
# SPDX-License-Identifier: GPL-3.0-or-later
# Make coding more python3-ish
from __future__ import annotations
from __future__ import (absolute_import, division, print_function)
__metaclass__ = type
DOCUMENTATION = r"""
author: Unknown (!UNKNOWN)
@@ -18,11 +19,6 @@ short_description: Sends play events to a Slack channel
description:
- This is an ansible callback plugin that sends status updates to a Slack channel during playbook execution.
options:
http_agent:
description:
- HTTP user agent to use for requests to Slack.
type: string
version_added: "10.5.0"
webhook_url:
required: true
description: Slack Webhook URL.
@@ -66,6 +62,7 @@ import os
import uuid
from ansible import context
from ansible.module_utils.common.text.converters import to_text
from ansible.module_utils.urls import open_url
from ansible.plugins.callback import CallbackBase
@@ -111,7 +108,7 @@ class CallbackModule(CallbackBase):
self.username = self.get_option('username')
self.show_invocation = (self._display.verbosity > 1)
self.validate_certs = self.get_option('validate_certs')
self.http_agent = self.get_option('http_agent')
if self.webhook_url is None:
self.disabled = True
self._display.warning('Slack Webhook URL was not provided. The '
@@ -137,22 +134,18 @@ class CallbackModule(CallbackBase):
self._display.debug(data)
self._display.debug(self.webhook_url)
try:
response = open_url(
self.webhook_url,
data=data,
validate_certs=self.validate_certs,
headers=headers,
http_agent=self.http_agent,
)
response = open_url(self.webhook_url, data=data, validate_certs=self.validate_certs,
headers=headers)
return response.read()
except Exception as e:
self._display.warning(f'Could not submit message to Slack: {e}')
self._display.warning(u'Could not submit message to Slack: %s' %
to_text(e))
def v2_playbook_on_start(self, playbook):
self.playbook_name = os.path.basename(playbook._file_name)
title = [
f'*Playbook initiated* (_{self.guid}_)'
'*Playbook initiated* (_%s_)' % self.guid
]
invocation_items = []
@@ -163,23 +156,23 @@ class CallbackModule(CallbackBase):
subset = context.CLIARGS['subset']
inventory = [os.path.abspath(i) for i in context.CLIARGS['inventory']]
invocation_items.append(f"Inventory: {', '.join(inventory)}")
invocation_items.append('Inventory: %s' % ', '.join(inventory))
if tags and tags != ['all']:
invocation_items.append(f"Tags: {', '.join(tags)}")
invocation_items.append('Tags: %s' % ', '.join(tags))
if skip_tags:
invocation_items.append(f"Skip Tags: {', '.join(skip_tags)}")
invocation_items.append('Skip Tags: %s' % ', '.join(skip_tags))
if subset:
invocation_items.append(f'Limit: {subset}')
invocation_items.append('Limit: %s' % subset)
if extra_vars:
invocation_items.append(f"Extra Vars: {' '.join(extra_vars)}")
invocation_items.append('Extra Vars: %s' %
' '.join(extra_vars))
title.append(f"by *{context.CLIARGS['remote_user']}*")
title.append('by *%s*' % context.CLIARGS['remote_user'])
title.append(f'\n\n*{self.playbook_name}*')
title.append('\n\n*%s*' % self.playbook_name)
msg_items = [' '.join(title)]
if invocation_items:
_inv_item = '\n'.join(invocation_items)
msg_items.append(f'```\n{_inv_item}\n```')
msg_items.append('```\n%s\n```' % '\n'.join(invocation_items))
msg = '\n'.join(msg_items)
@@ -199,8 +192,8 @@ class CallbackModule(CallbackBase):
def v2_playbook_on_play_start(self, play):
"""Display Play start messages"""
name = play.name or f'Play name not specified ({play._uuid})'
msg = f'*Starting play* (_{self.guid}_)\n\n*{name}*'
name = play.name or 'Play name not specified (%s)' % play._uuid
msg = '*Starting play* (_%s_)\n\n*%s*' % (self.guid, name)
attachments = [
{
'fallback': msg,
@@ -235,7 +228,7 @@ class CallbackModule(CallbackBase):
attachments = []
msg_items = [
f'*Playbook Complete* (_{self.guid}_)'
'*Playbook Complete* (_%s_)' % self.guid
]
if failures or unreachable:
color = 'danger'
@@ -244,7 +237,7 @@ class CallbackModule(CallbackBase):
color = 'good'
msg_items.append('\n*Success!*')
msg_items.append(f'```\n{t}\n```')
msg_items.append('```\n%s\n```' % t)
msg = '\n'.join(msg_items)

View File

@@ -3,7 +3,8 @@
# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
# SPDX-License-Identifier: GPL-3.0-or-later
from __future__ import annotations
from __future__ import (absolute_import, division, print_function)
__metaclass__ = type
DOCUMENTATION = r"""
name: splunk
@@ -152,14 +153,15 @@ class SplunkHTTPCollectorSource(object):
data['ansible_result'] = result._result
# This wraps the json payload in and outer json event needed by Splunk
jsondata = json.dumps({"event": data}, cls=AnsibleJSONEncoder, sort_keys=True)
jsondata = json.dumps(data, cls=AnsibleJSONEncoder, sort_keys=True)
jsondata = '{"event":' + jsondata + "}"
open_url(
url,
jsondata,
headers={
'Content-type': 'application/json',
'Authorization': f"Splunk {authtoken}"
'Authorization': 'Splunk ' + authtoken
},
method='POST',
validate_certs=validate_certs

View File

@@ -3,7 +3,8 @@
# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
# SPDX-License-Identifier: GPL-3.0-or-later
from __future__ import annotations
from __future__ import (absolute_import, division, print_function)
__metaclass__ = type
DOCUMENTATION = r"""
name: sumologic

View File

@@ -4,7 +4,8 @@
# SPDX-License-Identifier: GPL-3.0-or-later
# Make coding more python3-ish
from __future__ import annotations
from __future__ import (absolute_import, division, print_function)
__metaclass__ = type
DOCUMENTATION = r"""
author: Unknown (!UNKNOWN)

View File

@@ -5,8 +5,9 @@
# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
# SPDX-License-Identifier: GPL-3.0-or-later
from __future__ import annotations
from __future__ import absolute_import, division, print_function
__metaclass__ = type
DOCUMENTATION = r"""
name: timestamp
@@ -83,7 +84,7 @@ def banner(self, msg, color=None, cows=True):
msg = to_text(msg)
if self.b_cowsay and cows:
try:
self.banner_cowsay(f"{msg} @ {timestamp}")
self.banner_cowsay("%s @ %s" % (msg, timestamp))
return
except OSError:
self.warning("somebody cleverly deleted cowsay or something during the PB run. heh.")
@@ -96,7 +97,7 @@ def banner(self, msg, color=None, cows=True):
if star_len <= 3:
star_len = 3
stars = "*" * star_len
self.display(f"\n{msg} {stars} {timestamp}", color=color)
self.display("\n%s %s %s" % (msg, stars, timestamp), color=color)
class CallbackModule(Default):

View File

@@ -5,7 +5,8 @@
# SPDX-License-Identifier: GPL-3.0-or-later
# Make coding more python3-ish
from __future__ import annotations
from __future__ import (absolute_import, division, print_function)
__metaclass__ = type
DOCUMENTATION = r"""
name: unixy
@@ -66,24 +67,24 @@ class CallbackModule(CallbackModule_default):
def _process_result_output(self, result, msg):
task_host = result._host.get_name()
task_result = f"{task_host} {msg}"
task_result = "%s %s" % (task_host, msg)
if self._run_is_verbose(result):
task_result = f"{task_host} {msg}: {self._dump_results(result._result, indent=4)}"
task_result = "%s %s: %s" % (task_host, msg, self._dump_results(result._result, indent=4))
return task_result
if self.delegated_vars:
task_delegate_host = self.delegated_vars['ansible_host']
task_result = f"{task_host} -> {task_delegate_host} {msg}"
task_result = "%s -> %s %s" % (task_host, task_delegate_host, msg)
if result._result.get('msg') and result._result.get('msg') != "All items completed":
task_result += f" | msg: {to_text(result._result.get('msg'))}"
task_result += " | msg: " + to_text(result._result.get('msg'))
if result._result.get('stdout'):
task_result += f" | stdout: {result._result.get('stdout')}"
task_result += " | stdout: " + result._result.get('stdout')
if result._result.get('stderr'):
task_result += f" | stderr: {result._result.get('stderr')}"
task_result += " | stderr: " + result._result.get('stderr')
return task_result
@@ -91,30 +92,30 @@ class CallbackModule(CallbackModule_default):
self._get_task_display_name(task)
if self.task_display_name is not None:
if task.check_mode and self.get_option('check_mode_markers'):
self._display.display(f"{self.task_display_name} (check mode)...")
self._display.display("%s (check mode)..." % self.task_display_name)
else:
self._display.display(f"{self.task_display_name}...")
self._display.display("%s..." % self.task_display_name)
def v2_playbook_on_handler_task_start(self, task):
self._get_task_display_name(task)
if self.task_display_name is not None:
if task.check_mode and self.get_option('check_mode_markers'):
self._display.display(f"{self.task_display_name} (via handler in check mode)... ")
self._display.display("%s (via handler in check mode)... " % self.task_display_name)
else:
self._display.display(f"{self.task_display_name} (via handler)... ")
self._display.display("%s (via handler)... " % self.task_display_name)
def v2_playbook_on_play_start(self, play):
name = play.get_name().strip()
if play.check_mode and self.get_option('check_mode_markers'):
if name and play.hosts:
msg = f"\n- {name} (in check mode) on hosts: {','.join(play.hosts)} -"
msg = u"\n- %s (in check mode) on hosts: %s -" % (name, ",".join(play.hosts))
else:
msg = "- check mode -"
msg = u"- check mode -"
else:
if name and play.hosts:
msg = f"\n- {name} on hosts: {','.join(play.hosts)} -"
msg = u"\n- %s on hosts: %s -" % (name, ",".join(play.hosts))
else:
msg = "---"
msg = u"---"
self._display.display(msg)
@@ -125,7 +126,7 @@ class CallbackModule(CallbackModule_default):
msg = "skipped"
task_result = self._process_result_output(result, msg)
self._display.display(f" {task_result}", display_color)
self._display.display(" " + task_result, display_color)
else:
return
@@ -135,10 +136,10 @@ class CallbackModule(CallbackModule_default):
msg = "failed"
item_value = self._get_item_label(result._result)
if item_value:
msg += f" | item: {item_value}"
msg += " | item: %s" % (item_value,)
task_result = self._process_result_output(result, msg)
self._display.display(f" {task_result}", display_color, stderr=self.get_option('display_failed_stderr'))
self._display.display(" " + task_result, display_color, stderr=self.get_option('display_failed_stderr'))
def v2_runner_on_ok(self, result, msg="ok", display_color=C.COLOR_OK):
self._preprocess_result(result)
@@ -148,13 +149,13 @@ class CallbackModule(CallbackModule_default):
msg = "done"
item_value = self._get_item_label(result._result)
if item_value:
msg += f" | item: {item_value}"
msg += " | item: %s" % (item_value,)
display_color = C.COLOR_CHANGED
task_result = self._process_result_output(result, msg)
self._display.display(f" {task_result}", display_color)
self._display.display(" " + task_result, display_color)
elif self.get_option('display_ok_hosts'):
task_result = self._process_result_output(result, msg)
self._display.display(f" {task_result}", display_color)
self._display.display(" " + task_result, display_color)
def v2_runner_item_on_skipped(self, result):
self.v2_runner_on_skipped(result)
@@ -172,7 +173,7 @@ class CallbackModule(CallbackModule_default):
display_color = C.COLOR_UNREACHABLE
task_result = self._process_result_output(result, msg)
self._display.display(f" {task_result}", display_color, stderr=self.get_option('display_failed_stderr'))
self._display.display(" " + task_result, display_color, stderr=self.get_option('display_failed_stderr'))
def v2_on_file_diff(self, result):
if result._task.loop and 'results' in result._result:
@@ -194,17 +195,25 @@ class CallbackModule(CallbackModule_default):
# TODO how else can we display these?
t = stats.summarize(h)
self._display.display(
f" {hostcolor(h, t)} : {colorize('ok', t['ok'], C.COLOR_OK)} {colorize('changed', t['changed'], C.COLOR_CHANGED)} "
f"{colorize('unreachable', t['unreachable'], C.COLOR_UNREACHABLE)} {colorize('failed', t['failures'], C.COLOR_ERROR)} "
f"{colorize('rescued', t['rescued'], C.COLOR_OK)} {colorize('ignored', t['ignored'], C.COLOR_WARN)}",
self._display.display(u" %s : %s %s %s %s %s %s" % (
hostcolor(h, t),
colorize(u'ok', t['ok'], C.COLOR_OK),
colorize(u'changed', t['changed'], C.COLOR_CHANGED),
colorize(u'unreachable', t['unreachable'], C.COLOR_UNREACHABLE),
colorize(u'failed', t['failures'], C.COLOR_ERROR),
colorize(u'rescued', t['rescued'], C.COLOR_OK),
colorize(u'ignored', t['ignored'], C.COLOR_WARN)),
screen_only=True
)
self._display.display(
f" {hostcolor(h, t, False)} : {colorize('ok', t['ok'], None)} {colorize('changed', t['changed'], None)} "
f"{colorize('unreachable', t['unreachable'], None)} {colorize('failed', t['failures'], None)} {colorize('rescued', t['rescued'], None)} "
f"{colorize('ignored', t['ignored'], None)}",
self._display.display(u" %s : %s %s %s %s %s %s" % (
hostcolor(h, t, False),
colorize(u'ok', t['ok'], None),
colorize(u'changed', t['changed'], None),
colorize(u'unreachable', t['unreachable'], None),
colorize(u'failed', t['failures'], None),
colorize(u'rescued', t['rescued'], None),
colorize(u'ignored', t['ignored'], None)),
log_only=True
)
if stats.custom and self.get_option('show_custom_stats'):
@@ -214,14 +223,12 @@ class CallbackModule(CallbackModule_default):
for k in sorted(stats.custom.keys()):
if k == '_run':
continue
stat_val = self._dump_results(stats.custom[k], indent=1).replace('\n', '')
self._display.display(f'\t{k}: {stat_val}')
self._display.display('\t%s: %s' % (k, self._dump_results(stats.custom[k], indent=1).replace('\n', '')))
# print per run custom stats
if '_run' in stats.custom:
self._display.display("", screen_only=True)
stat_val_run = self._dump_results(stats.custom['_run'], indent=1).replace('\n', '')
self._display.display(f'\tRUN: {stat_val_run}')
self._display.display('\tRUN: %s' % self._dump_results(stats.custom['_run'], indent=1).replace('\n', ''))
self._display.display("", screen_only=True)
def v2_playbook_on_no_hosts_matched(self):
@@ -232,23 +239,23 @@ class CallbackModule(CallbackModule_default):
def v2_playbook_on_start(self, playbook):
if context.CLIARGS['check'] and self.get_option('check_mode_markers'):
self._display.display(f"Executing playbook {basename(playbook._file_name)} in check mode")
self._display.display("Executing playbook %s in check mode" % basename(playbook._file_name))
else:
self._display.display(f"Executing playbook {basename(playbook._file_name)}")
self._display.display("Executing playbook %s" % basename(playbook._file_name))
# show CLI arguments
if self._display.verbosity > 3:
if context.CLIARGS.get('args'):
self._display.display(f"Positional arguments: {' '.join(context.CLIARGS['args'])}",
self._display.display('Positional arguments: %s' % ' '.join(context.CLIARGS['args']),
color=C.COLOR_VERBOSE, screen_only=True)
for argument in (a for a in context.CLIARGS if a != 'args'):
val = context.CLIARGS[argument]
if val:
self._display.vvvv(f'{argument}: {val}')
self._display.vvvv('%s: %s' % (argument, val))
def v2_runner_retry(self, result):
msg = f" Retrying... ({result._result['attempts']} of {result._result['retries']})"
msg = " Retrying... (%d of %d)" % (result._result['attempts'], result._result['retries'])
if self._run_is_verbose(result):
msg += f"Result was: {self._dump_results(result._result)}"
msg += "Result was: %s" % self._dump_results(result._result)
self._display.display(msg, color=C.COLOR_DEBUG)

View File

@@ -4,18 +4,14 @@
# SPDX-License-Identifier: GPL-3.0-or-later
# Make coding more python3-ish
from __future__ import annotations
from __future__ import (absolute_import, division, print_function)
__metaclass__ = type
DOCUMENTATION = r"""
author: Unknown (!UNKNOWN)
name: yaml
type: stdout
short_description: YAML-ized Ansible screen output
deprecated:
removed_in: 13.0.0
why: Starting in ansible-core 2.13, the P(ansible.builtin.default#callback) callback has support for printing output in
YAML format.
alternative: Use O(ansible.builtin.default#callback:result_format=yaml).
description:
- Ansible output that can be quite a bit easier to read than the default JSON formatting.
extends_documentation_fragment:
@@ -37,9 +33,9 @@ import yaml
import json
import re
import string
from collections.abc import Mapping, Sequence
from ansible.module_utils.common.text.converters import to_text
from ansible.parsing.yaml.dumper import AnsibleDumper
from ansible.plugins.callback import strip_internal_keys, module_response_deepcopy
from ansible.plugins.callback.default import CallbackModule as Default
@@ -47,35 +43,83 @@ from ansible.plugins.callback.default import CallbackModule as Default
# from http://stackoverflow.com/a/15423007/115478
def should_use_block(value):
"""Returns true if string should be in block format"""
for c in "\u000a\u000d\u001c\u001d\u001e\u0085\u2028\u2029":
for c in u"\u000a\u000d\u001c\u001d\u001e\u0085\u2028\u2029":
if c in value:
return True
return False
class MyDumper(AnsibleDumper):
def represent_scalar(self, tag, value, style=None):
"""Uses block style for multi-line strings"""
if style is None:
if should_use_block(value):
style = '|'
# we care more about readable than accuracy, so...
# ...no trailing space
value = value.rstrip()
# ...and non-printable characters
value = ''.join(x for x in value if x in string.printable or ord(x) >= 0xA0)
# ...tabs prevent blocks from expanding
value = value.expandtabs()
# ...and odd bits of whitespace
value = re.sub(r'[\x0b\x0c\r]', '', value)
# ...as does trailing space
value = re.sub(r' +\n', '\n', value)
else:
style = self.default_style
node = yaml.representer.ScalarNode(tag, value, style=style)
if self.alias_key is not None:
self.represented_objects[self.alias_key] = node
return node
def adjust_str_value_for_block(value):
# we care more about readable than accuracy, so...
# ...no trailing space
value = value.rstrip()
# ...and non-printable characters
value = ''.join(x for x in value if x in string.printable or ord(x) >= 0xA0)
# ...tabs prevent blocks from expanding
value = value.expandtabs()
# ...and odd bits of whitespace
value = re.sub(r'[\x0b\x0c\r]', '', value)
# ...as does trailing space
value = re.sub(r' +\n', '\n', value)
return value
def create_string_node(tag, value, style, default_style):
if style is None:
if should_use_block(value):
style = '|'
value = adjust_str_value_for_block(value)
else:
style = default_style
return yaml.representer.ScalarNode(tag, value, style=style)
try:
from ansible.module_utils.common.yaml import HAS_LIBYAML
# import below was added in https://github.com/ansible/ansible/pull/85039,
# first contained in ansible-core 2.19.0b2:
from ansible.utils.vars import transform_to_native_types
if HAS_LIBYAML:
from yaml.cyaml import CSafeDumper as SafeDumper
else:
from yaml import SafeDumper
class MyDumper(SafeDumper):
def represent_scalar(self, tag, value, style=None):
"""Uses block style for multi-line strings"""
node = create_string_node(tag, value, style, self.default_style)
if self.alias_key is not None:
self.represented_objects[self.alias_key] = node
return node
except ImportError:
# In case transform_to_native_types cannot be imported, we either have ansible-core 2.19.0b1
# (or some random commit from the devel or stable-2.19 branch after merging the DT changes
# and before transform_to_native_types was added), or we have a version without the DT changes.
# Here we simply assume we have a version without the DT changes, and thus can continue as
# with ansible-core 2.18 and before.
transform_to_native_types = None
from ansible.parsing.yaml.dumper import AnsibleDumper
class MyDumper(AnsibleDumper): # pylint: disable=inherit-non-class
def represent_scalar(self, tag, value, style=None):
"""Uses block style for multi-line strings"""
node = create_string_node(tag, value, style, self.default_style)
if self.alias_key is not None:
self.represented_objects[self.alias_key] = node
return node
def transform_recursively(value, transform):
if isinstance(value, Mapping):
return {transform(k): transform(v) for k, v in value.items()}
if isinstance(value, Sequence) and not isinstance(value, (str, bytes)):
return [transform(e) for e in value]
return transform(value)
class CallbackModule(Default):
@@ -115,11 +159,11 @@ class CallbackModule(Default):
# put changed and skipped into a header line
if 'changed' in abridged_result:
dumped += f"changed={str(abridged_result['changed']).lower()} "
dumped += 'changed=' + str(abridged_result['changed']).lower() + ' '
del abridged_result['changed']
if 'skipped' in abridged_result:
dumped += f"skipped={str(abridged_result['skipped']).lower()} "
dumped += 'skipped=' + str(abridged_result['skipped']).lower() + ' '
del abridged_result['skipped']
# if we already have stdout, we don't need stdout_lines
@@ -132,6 +176,8 @@ class CallbackModule(Default):
if abridged_result:
dumped += '\n'
if transform_to_native_types is not None:
abridged_result = transform_recursively(abridged_result, lambda v: transform_to_native_types(v, redact=False))
dumped += to_text(yaml.dump(abridged_result, allow_unicode=True, width=1000, Dumper=MyDumper, default_flow_style=False))
# indent by a couple of spaces

View File

@@ -7,7 +7,8 @@
# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
# SPDX-License-Identifier: GPL-3.0-or-later
from __future__ import annotations
from __future__ import (absolute_import, division, print_function)
__metaclass__ = type
DOCUMENTATION = r"""
author: Maykel Moya (!UNKNOWN) <mmoya@speedyrails.com>
@@ -80,7 +81,7 @@ from ansible.errors import AnsibleError
from ansible.module_utils.basic import is_executable
from ansible.module_utils.common.process import get_bin_path
from ansible.module_utils.six.moves import shlex_quote
from ansible.module_utils.common.text.converters import to_bytes
from ansible.module_utils.common.text.converters import to_bytes, to_native
from ansible.plugins.connection import ConnectionBase, BUFSIZE
from ansible.utils.display import Display
@@ -106,15 +107,15 @@ class Connection(ConnectionBase):
# do some trivial checks for ensuring 'host' is actually a chroot'able dir
if not os.path.isdir(self.chroot):
raise AnsibleError(f"{self.chroot} is not a directory")
raise AnsibleError("%s is not a directory" % self.chroot)
chrootsh = os.path.join(self.chroot, 'bin/sh')
# Want to check for a usable bourne shell inside the chroot.
# is_executable() == True is sufficient. For symlinks it
# gets really complicated really fast. So we punt on finding that
# out. As long as it is a symlink we assume that it will work
# out. As long as it's a symlink we assume that it will work
if not (is_executable(chrootsh) or (os.path.lexists(chrootsh) and os.path.islink(chrootsh))):
raise AnsibleError(f"{self.chroot} does not look like a chrootable dir (/bin/sh missing)")
raise AnsibleError("%s does not look like a chrootable dir (/bin/sh missing)" % self.chroot)
def _connect(self):
""" connect to the chroot """
@@ -129,7 +130,7 @@ class Connection(ConnectionBase):
try:
self.chroot_cmd = get_bin_path(self.get_option('chroot_exe'))
except ValueError as e:
raise AnsibleError(str(e))
raise AnsibleError(to_native(e))
super(Connection, self)._connect()
if not self._connected:
@@ -147,7 +148,7 @@ class Connection(ConnectionBase):
executable = self.get_option('executable')
local_cmd = [self.chroot_cmd, self.chroot, executable, '-c', cmd]
display.vvv(f"EXEC {local_cmd}", host=self.chroot)
display.vvv("EXEC %s" % local_cmd, host=self.chroot)
local_cmd = [to_bytes(i, errors='surrogate_or_strict') for i in local_cmd]
p = subprocess.Popen(local_cmd, shell=False, stdin=stdin,
stdout=subprocess.PIPE, stderr=subprocess.PIPE)
@@ -172,7 +173,7 @@ class Connection(ConnectionBase):
exist in any given chroot. So for now we're choosing "/" instead.
This also happens to be the former default.
Can revisit using $HOME instead if it is a problem
Can revisit using $HOME instead if it's a problem
"""
if not remote_path.startswith(os.path.sep):
remote_path = os.path.join(os.path.sep, remote_path)
@@ -181,7 +182,7 @@ class Connection(ConnectionBase):
def put_file(self, in_path, out_path):
""" transfer a file from local to chroot """
super(Connection, self).put_file(in_path, out_path)
display.vvv(f"PUT {in_path} TO {out_path}", host=self.chroot)
display.vvv("PUT %s TO %s" % (in_path, out_path), host=self.chroot)
out_path = shlex_quote(self._prefix_login_path(out_path))
try:
@@ -191,27 +192,27 @@ class Connection(ConnectionBase):
else:
count = ''
try:
p = self._buffered_exec_command(f'dd of={out_path} bs={BUFSIZE}{count}', stdin=in_file)
p = self._buffered_exec_command('dd of=%s bs=%s%s' % (out_path, BUFSIZE, count), stdin=in_file)
except OSError:
raise AnsibleError("chroot connection requires dd command in the chroot")
try:
stdout, stderr = p.communicate()
except Exception:
traceback.print_exc()
raise AnsibleError(f"failed to transfer file {in_path} to {out_path}")
raise AnsibleError("failed to transfer file %s to %s" % (in_path, out_path))
if p.returncode != 0:
raise AnsibleError(f"failed to transfer file {in_path} to {out_path}:\n{stdout}\n{stderr}")
raise AnsibleError("failed to transfer file %s to %s:\n%s\n%s" % (in_path, out_path, stdout, stderr))
except IOError:
raise AnsibleError(f"file or module does not exist at: {in_path}")
raise AnsibleError("file or module does not exist at: %s" % in_path)
def fetch_file(self, in_path, out_path):
""" fetch a file from chroot to local """
super(Connection, self).fetch_file(in_path, out_path)
display.vvv(f"FETCH {in_path} TO {out_path}", host=self.chroot)
display.vvv("FETCH %s TO %s" % (in_path, out_path), host=self.chroot)
in_path = shlex_quote(self._prefix_login_path(in_path))
try:
p = self._buffered_exec_command(f'dd if={in_path} bs={BUFSIZE}')
p = self._buffered_exec_command('dd if=%s bs=%s' % (in_path, BUFSIZE))
except OSError:
raise AnsibleError("chroot connection requires dd command in the chroot")
@@ -223,10 +224,10 @@ class Connection(ConnectionBase):
chunk = p.stdout.read(BUFSIZE)
except Exception:
traceback.print_exc()
raise AnsibleError(f"failed to transfer file {in_path} to {out_path}")
raise AnsibleError("failed to transfer file %s to %s" % (in_path, out_path))
stdout, stderr = p.communicate()
if p.returncode != 0:
raise AnsibleError(f"failed to transfer file {in_path} to {out_path}:\n{stdout}\n{stderr}")
raise AnsibleError("failed to transfer file %s to %s:\n%s\n%s" % (in_path, out_path, stdout, stderr))
def close(self):
""" terminate the connection; nothing to do here """

View File

@@ -6,7 +6,8 @@
# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
# SPDX-License-Identifier: GPL-3.0-or-later
from __future__ import annotations
from __future__ import (absolute_import, division, print_function)
__metaclass__ = type
DOCUMENTATION = r"""
author: Michael Scherer (@mscherer) <misc@zarb.org>
@@ -71,7 +72,7 @@ class Connection(ConnectionBase):
raise AnsibleError("Internal Error: this module does not support optimized module pipelining")
# totally ignores privilege escalation
display.vvv(f"EXEC {cmd}", host=self.host)
display.vvv("EXEC %s" % cmd, host=self.host)
p = self.client.command.run(cmd)[self.host]
return p[0], p[1], p[2]
@@ -86,14 +87,14 @@ class Connection(ConnectionBase):
""" transfer a file from local to remote """
out_path = self._normalize_path(out_path, '/')
display.vvv(f"PUT {in_path} TO {out_path}", host=self.host)
display.vvv("PUT %s TO %s" % (in_path, out_path), host=self.host)
self.client.local.copyfile.send(in_path, out_path)
def fetch_file(self, in_path, out_path):
""" fetch a file from remote to local """
in_path = self._normalize_path(in_path, '/')
display.vvv(f"FETCH {in_path} TO {out_path}", host=self.host)
display.vvv("FETCH %s TO %s" % (in_path, out_path), host=self.host)
# need to use a tmp dir due to difference of semantic for getfile
# ( who take a # directory as destination) and fetch_file, who
# take a file directly

View File

@@ -5,7 +5,8 @@
# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
# SPDX-License-Identifier: GPL-3.0-or-later
from __future__ import annotations
from __future__ import (absolute_import, division, print_function)
__metaclass__ = type
DOCUMENTATION = r"""
author: Stéphane Graber (@stgraber)
@@ -32,15 +33,6 @@ options:
vars:
- name: ansible_executable
- name: ansible_incus_executable
incus_become_method:
description:
- Become command used to switch to a non-root user.
- Is only used when O(remote_user) is not V(root).
type: str
default: /bin/su
vars:
- name: incus_become_method
version_added: 10.4.0
remote:
description:
- The name of the Incus remote to use (per C(incus remote list)).
@@ -49,22 +41,6 @@ options:
default: local
vars:
- name: ansible_incus_remote
remote_user:
description:
- User to login/authenticate as.
- Can be set from the CLI via the C(--user) or C(-u) options.
type: string
default: root
vars:
- name: ansible_user
env:
- name: ANSIBLE_REMOTE_USER
ini:
- section: defaults
key: remote_user
keyword:
- name: remote_user
version_added: 10.4.0
project:
description:
- The name of the Incus project to use (per C(incus project list)).
@@ -89,6 +65,7 @@ class Connection(ConnectionBase):
transport = "incus"
has_pipelining = True
default_user = 'root'
def __init__(self, play_context, new_stdin, *args, **kwargs):
super(Connection, self).__init__(play_context, new_stdin, *args, **kwargs)
@@ -103,34 +80,10 @@ class Connection(ConnectionBase):
super(Connection, self)._connect()
if not self._connected:
self._display.vvv(f"ESTABLISH Incus CONNECTION FOR USER: {self.get_option('remote_user')}",
self._display.vvv(u"ESTABLISH Incus CONNECTION FOR USER: root",
host=self._instance())
self._connected = True
def _build_command(self, cmd) -> str:
"""build the command to execute on the incus host"""
exec_cmd = [
self._incus_cmd,
"--project", self.get_option("project"),
"exec",
f"{self.get_option('remote')}:{self._instance()}",
"--"]
if self.get_option("remote_user") != "root":
self._display.vvv(
f"INFO: Running as non-root user: {self.get_option('remote_user')}, \
trying to run 'incus exec' with become method: {self.get_option('incus_become_method')}",
host=self._instance(),
)
exec_cmd.extend(
[self.get_option("incus_become_method"), self.get_option("remote_user"), "-c"]
)
exec_cmd.extend([self.get_option("executable"), "-c", cmd])
return exec_cmd
def _instance(self):
# Return only the leading part of the FQDN as the instance name
# as Incus instance names cannot be a FQDN.
@@ -140,11 +93,16 @@ class Connection(ConnectionBase):
""" execute a command on the Incus host """
super(Connection, self).exec_command(cmd, in_data=in_data, sudoable=sudoable)
self._display.vvv(f"EXEC {cmd}",
self._display.vvv(u"EXEC {0}".format(cmd),
host=self._instance())
local_cmd = self._build_command(cmd)
self._display.vvvvv(f"EXEC {local_cmd}", host=self._instance())
local_cmd = [
self._incus_cmd,
"--project", self.get_option("project"),
"exec",
"%s:%s" % (self.get_option("remote"), self._instance()),
"--",
self._play_context.executable, "-c", cmd]
local_cmd = [to_bytes(i, errors='surrogate_or_strict') for i in local_cmd]
in_data = to_bytes(in_data, errors='surrogate_or_strict', nonstring='passthru')
@@ -156,71 +114,33 @@ class Connection(ConnectionBase):
stderr = to_text(stderr)
if stderr == "Error: Instance is not running.\n":
raise AnsibleConnectionFailure(f"instance not running: {self._instance()}")
raise AnsibleConnectionFailure("instance not running: %s" %
self._instance())
if stderr == "Error: Instance not found\n":
raise AnsibleConnectionFailure(f"instance not found: {self._instance()}")
raise AnsibleConnectionFailure("instance not found: %s" %
self._instance())
return process.returncode, stdout, stderr
def _get_remote_uid_gid(self) -> tuple[int, int]:
"""Get the user and group ID of 'remote_user' from the instance."""
rc, uid_out, err = self.exec_command("/bin/id -u")
if rc != 0:
raise AnsibleError(
f"Failed to get remote uid for user {self.get_option('remote_user')}: {err}"
)
uid = uid_out.strip()
rc, gid_out, err = self.exec_command("/bin/id -g")
if rc != 0:
raise AnsibleError(
f"Failed to get remote gid for user {self.get_option('remote_user')}: {err}"
)
gid = gid_out.strip()
return int(uid), int(gid)
def put_file(self, in_path, out_path):
""" put a file from local to Incus """
super(Connection, self).put_file(in_path, out_path)
self._display.vvv(f"PUT {in_path} TO {out_path}",
self._display.vvv(u"PUT {0} TO {1}".format(in_path, out_path),
host=self._instance())
if not os.path.isfile(to_bytes(in_path, errors='surrogate_or_strict')):
raise AnsibleFileNotFound(f"input path is not a file: {in_path}")
raise AnsibleFileNotFound("input path is not a file: %s" % in_path)
if self.get_option("remote_user") != "root":
uid, gid = self._get_remote_uid_gid()
local_cmd = [
self._incus_cmd,
"--project",
self.get_option("project"),
"file",
"push",
"--uid",
str(uid),
"--gid",
str(gid),
"--quiet",
in_path,
f"{self.get_option('remote')}:{self._instance()}/{out_path}",
]
else:
local_cmd = [
self._incus_cmd,
"--project",
self.get_option("project"),
"file",
"push",
"--quiet",
in_path,
f"{self.get_option('remote')}:{self._instance()}/{out_path}",
]
self._display.vvvvv(f"PUT {local_cmd}", host=self._instance())
local_cmd = [
self._incus_cmd,
"--project", self.get_option("project"),
"file", "push", "--quiet",
in_path,
"%s:%s/%s" % (self.get_option("remote"),
self._instance(),
out_path)]
local_cmd = [to_bytes(i, errors='surrogate_or_strict') for i in local_cmd]
@@ -230,14 +150,16 @@ class Connection(ConnectionBase):
""" fetch a file from Incus to local """
super(Connection, self).fetch_file(in_path, out_path)
self._display.vvv(f"FETCH {in_path} TO {out_path}",
self._display.vvv(u"FETCH {0} TO {1}".format(in_path, out_path),
host=self._instance())
local_cmd = [
self._incus_cmd,
"--project", self.get_option("project"),
"file", "pull", "--quiet",
f"{self.get_option('remote')}:{self._instance()}/{in_path}",
"%s:%s/%s" % (self.get_option("remote"),
self._instance(),
in_path),
out_path]
local_cmd = [to_bytes(i, errors='surrogate_or_strict') for i in local_cmd]

View File

@@ -7,7 +7,8 @@
# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
# SPDX-License-Identifier: GPL-3.0-or-later
from __future__ import annotations
from __future__ import (absolute_import, division, print_function)
__metaclass__ = type
DOCUMENTATION = r"""
author: Stephan Lohse (!UNKNOWN) <dev-github@ploek.org>
@@ -54,12 +55,11 @@ class Connection(Jail):
jail_uuid = self.get_jail_uuid()
kwargs[Jail.modified_jailname_key] = f'ioc-{jail_uuid}'
kwargs[Jail.modified_jailname_key] = 'ioc-{0}'.format(jail_uuid)
display.vvv(
f"Jail {self.ioc_jail} has been translated to {kwargs[Jail.modified_jailname_key]}",
host=kwargs[Jail.modified_jailname_key]
)
display.vvv(u"Jail {iocjail} has been translated to {rawjail}".format(
iocjail=self.ioc_jail, rawjail=kwargs[Jail.modified_jailname_key]),
host=kwargs[Jail.modified_jailname_key])
super(Connection, self).__init__(play_context, new_stdin, *args, **kwargs)
@@ -81,6 +81,6 @@ class Connection(Jail):
p.wait()
if p.returncode != 0:
raise AnsibleError(f"iocage returned an error: {stdout}")
raise AnsibleError(u"iocage returned an error: {0}".format(stdout))
return stdout.strip('\n')

View File

@@ -7,7 +7,8 @@
# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
# SPDX-License-Identifier: GPL-3.0-or-later
from __future__ import annotations
from __future__ import (absolute_import, division, print_function)
__metaclass__ = type
DOCUMENTATION = r"""
author: Ansible Core Team
@@ -74,14 +75,14 @@ class Connection(ConnectionBase):
self.jexec_cmd = self._search_executable('jexec')
if self.jail not in self.list_jails():
raise AnsibleError(f"incorrect jail name {self.jail}")
raise AnsibleError("incorrect jail name %s" % self.jail)
@staticmethod
def _search_executable(executable):
try:
return get_bin_path(executable)
except ValueError:
raise AnsibleError(f"{executable} command not found in PATH")
raise AnsibleError("%s command not found in PATH" % executable)
def list_jails(self):
p = subprocess.Popen([self.jls_cmd, '-q', 'name'],
@@ -96,7 +97,7 @@ class Connection(ConnectionBase):
""" connect to the jail; nothing to do here """
super(Connection, self)._connect()
if not self._connected:
display.vvv(f"ESTABLISH JAIL CONNECTION FOR USER: {self._play_context.remote_user}", host=self.jail)
display.vvv(u"ESTABLISH JAIL CONNECTION FOR USER: {0}".format(self._play_context.remote_user), host=self.jail)
self._connected = True
def _buffered_exec_command(self, cmd, stdin=subprocess.PIPE):
@@ -114,11 +115,11 @@ class Connection(ConnectionBase):
if self._play_context.remote_user is not None:
local_cmd += ['-U', self._play_context.remote_user]
# update HOME since -U does not update the jail environment
set_env = f"HOME=~{self._play_context.remote_user} "
set_env = 'HOME=~' + self._play_context.remote_user + ' '
local_cmd += [self.jail, self._play_context.executable, '-c', set_env + cmd]
display.vvv(f"EXEC {local_cmd}", host=self.jail)
display.vvv("EXEC %s" % (local_cmd,), host=self.jail)
local_cmd = [to_bytes(i, errors='surrogate_or_strict') for i in local_cmd]
p = subprocess.Popen(local_cmd, shell=False, stdin=stdin,
stdout=subprocess.PIPE, stderr=subprocess.PIPE)
@@ -143,7 +144,7 @@ class Connection(ConnectionBase):
exist in any given chroot. So for now we're choosing "/" instead.
This also happens to be the former default.
Can revisit using $HOME instead if it is a problem
Can revisit using $HOME instead if it's a problem
"""
if not remote_path.startswith(os.path.sep):
remote_path = os.path.join(os.path.sep, remote_path)
@@ -152,7 +153,7 @@ class Connection(ConnectionBase):
def put_file(self, in_path, out_path):
""" transfer a file from local to jail """
super(Connection, self).put_file(in_path, out_path)
display.vvv(f"PUT {in_path} TO {out_path}", host=self.jail)
display.vvv("PUT %s TO %s" % (in_path, out_path), host=self.jail)
out_path = shlex_quote(self._prefix_login_path(out_path))
try:
@@ -162,27 +163,27 @@ class Connection(ConnectionBase):
else:
count = ''
try:
p = self._buffered_exec_command(f'dd of={out_path} bs={BUFSIZE}{count}', stdin=in_file)
p = self._buffered_exec_command('dd of=%s bs=%s%s' % (out_path, BUFSIZE, count), stdin=in_file)
except OSError:
raise AnsibleError("jail connection requires dd command in the jail")
try:
stdout, stderr = p.communicate()
except Exception:
traceback.print_exc()
raise AnsibleError(f"failed to transfer file {in_path} to {out_path}")
raise AnsibleError("failed to transfer file %s to %s" % (in_path, out_path))
if p.returncode != 0:
raise AnsibleError(f"failed to transfer file {in_path} to {out_path}:\n{to_native(stdout)}\n{to_native(stderr)}")
raise AnsibleError("failed to transfer file %s to %s:\n%s\n%s" % (in_path, out_path, to_native(stdout), to_native(stderr)))
except IOError:
raise AnsibleError(f"file or module does not exist at: {in_path}")
raise AnsibleError("file or module does not exist at: %s" % in_path)
def fetch_file(self, in_path, out_path):
""" fetch a file from jail to local """
super(Connection, self).fetch_file(in_path, out_path)
display.vvv(f"FETCH {in_path} TO {out_path}", host=self.jail)
display.vvv("FETCH %s TO %s" % (in_path, out_path), host=self.jail)
in_path = shlex_quote(self._prefix_login_path(in_path))
try:
p = self._buffered_exec_command(f'dd if={in_path} bs={BUFSIZE}')
p = self._buffered_exec_command('dd if=%s bs=%s' % (in_path, BUFSIZE))
except OSError:
raise AnsibleError("jail connection requires dd command in the jail")
@@ -194,10 +195,10 @@ class Connection(ConnectionBase):
chunk = p.stdout.read(BUFSIZE)
except Exception:
traceback.print_exc()
raise AnsibleError(f"failed to transfer file {in_path} to {out_path}")
raise AnsibleError("failed to transfer file %s to %s" % (in_path, out_path))
stdout, stderr = p.communicate()
if p.returncode != 0:
raise AnsibleError(f"failed to transfer file {in_path} to {out_path}:\n{to_native(stdout)}\n{to_native(stderr)}")
raise AnsibleError("failed to transfer file %s to %s:\n%s\n%s" % (in_path, out_path, to_native(stdout), to_native(stderr)))
def close(self):
""" terminate the connection; nothing to do here """

View File

@@ -4,7 +4,8 @@
# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
# SPDX-License-Identifier: GPL-3.0-or-later
from __future__ import annotations
from __future__ import (absolute_import, division, print_function)
__metaclass__ = type
DOCUMENTATION = r"""
author: Joerg Thalheim (!UNKNOWN) <joerg@higgsboson.tk>
@@ -81,7 +82,7 @@ class Connection(ConnectionBase):
self._display.vvv("THIS IS A LOCAL LXC DIR", host=self.container_name)
self.container = _lxc.Container(self.container_name)
if self.container.state == "STOPPED":
raise errors.AnsibleError(f"{self.container_name} is not running")
raise errors.AnsibleError("%s is not running" % self.container_name)
@staticmethod
def _communicate(pid, in_data, stdin, stdout, stderr):
@@ -143,10 +144,10 @@ class Connection(ConnectionBase):
read_stdin, write_stdin = os.pipe()
kwargs['stdin'] = self._set_nonblocking(read_stdin)
self._display.vvv(f"EXEC {local_cmd}", host=self.container_name)
self._display.vvv("EXEC %s" % (local_cmd), host=self.container_name)
pid = self.container.attach(_lxc.attach_run_command, local_cmd, **kwargs)
if pid == -1:
msg = f"failed to attach to container {self.container_name}"
msg = "failed to attach to container %s" % self.container_name
raise errors.AnsibleError(msg)
write_stdout = os.close(write_stdout)
@@ -173,18 +174,18 @@ class Connection(ConnectionBase):
def put_file(self, in_path, out_path):
''' transfer a file from local to lxc '''
super(Connection, self).put_file(in_path, out_path)
self._display.vvv(f"PUT {in_path} TO {out_path}", host=self.container_name)
self._display.vvv("PUT %s TO %s" % (in_path, out_path), host=self.container_name)
in_path = to_bytes(in_path, errors='surrogate_or_strict')
out_path = to_bytes(out_path, errors='surrogate_or_strict')
if not os.path.exists(in_path):
msg = f"file or module does not exist: {in_path}"
msg = "file or module does not exist: %s" % in_path
raise errors.AnsibleFileNotFound(msg)
try:
src_file = open(in_path, "rb")
except IOError:
traceback.print_exc()
raise errors.AnsibleError(f"failed to open input file to {in_path}")
raise errors.AnsibleError("failed to open input file to %s" % in_path)
try:
def write_file(args):
with open(out_path, 'wb+') as dst_file:
@@ -193,7 +194,7 @@ class Connection(ConnectionBase):
self.container.attach_wait(write_file, None)
except IOError:
traceback.print_exc()
msg = f"failed to transfer file to {out_path}"
msg = "failed to transfer file to %s" % out_path
raise errors.AnsibleError(msg)
finally:
src_file.close()
@@ -201,7 +202,7 @@ class Connection(ConnectionBase):
def fetch_file(self, in_path, out_path):
''' fetch a file from lxc to local '''
super(Connection, self).fetch_file(in_path, out_path)
self._display.vvv(f"FETCH {in_path} TO {out_path}", host=self.container_name)
self._display.vvv("FETCH %s TO %s" % (in_path, out_path), host=self.container_name)
in_path = to_bytes(in_path, errors='surrogate_or_strict')
out_path = to_bytes(out_path, errors='surrogate_or_strict')
@@ -209,7 +210,7 @@ class Connection(ConnectionBase):
dst_file = open(out_path, "wb")
except IOError:
traceback.print_exc()
msg = f"failed to open output file {out_path}"
msg = "failed to open output file %s" % out_path
raise errors.AnsibleError(msg)
try:
def write_file(args):
@@ -224,7 +225,7 @@ class Connection(ConnectionBase):
self.container.attach_wait(write_file, None)
except IOError:
traceback.print_exc()
msg = f"failed to transfer file from {in_path} to {out_path}"
msg = "failed to transfer file from %s to %s" % (in_path, out_path)
raise errors.AnsibleError(msg)
finally:
dst_file.close()

View File

@@ -4,7 +4,8 @@
# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
# SPDX-License-Identifier: GPL-3.0-or-later
from __future__ import annotations
from __future__ import (absolute_import, division, print_function)
__metaclass__ = type
DOCUMENTATION = r"""
author: Matt Clay (@mattclay) <matt@mystile.com>
@@ -32,15 +33,6 @@ options:
vars:
- name: ansible_executable
- name: ansible_lxd_executable
lxd_become_method:
description:
- Become command used to switch to a non-root user.
- Is only used when O(remote_user) is not V(root).
type: str
default: /bin/su
vars:
- name: lxd_become_method
version_added: 10.4.0
remote:
description:
- Name of the LXD remote to use.
@@ -49,22 +41,6 @@ options:
vars:
- name: ansible_lxd_remote
version_added: 2.0.0
remote_user:
description:
- User to login/authenticate as.
- Can be set from the CLI via the C(--user) or C(-u) options.
type: string
default: root
vars:
- name: ansible_user
env:
- name: ANSIBLE_REMOTE_USER
ini:
- section: defaults
key: remote_user
keyword:
- name: remote_user
version_added: 10.4.0
project:
description:
- Name of the LXD project to use.
@@ -88,6 +64,7 @@ class Connection(ConnectionBase):
transport = 'community.general.lxd'
has_pipelining = True
default_user = 'root'
def __init__(self, play_context, new_stdin, *args, **kwargs):
super(Connection, self).__init__(play_context, new_stdin, *args, **kwargs)
@@ -97,6 +74,9 @@ class Connection(ConnectionBase):
except ValueError:
raise AnsibleError("lxc command not found in PATH")
if self._play_context.remote_user is not None and self._play_context.remote_user != 'root':
self._display.warning('lxd does not support remote_user, using default: root')
def _host(self):
""" translate remote_addr to lxd (short) hostname """
return self.get_option("remote_addr").split(".", 1)[0]
@@ -106,41 +86,26 @@ class Connection(ConnectionBase):
super(Connection, self)._connect()
if not self._connected:
self._display.vvv(f"ESTABLISH LXD CONNECTION FOR USER: {self.get_option('remote_user')}", host=self._host())
self._display.vvv(u"ESTABLISH LXD CONNECTION FOR USER: root", host=self._host())
self._connected = True
def _build_command(self, cmd) -> str:
"""build the command to execute on the lxd host"""
exec_cmd = [self._lxc_cmd]
if self.get_option("project"):
exec_cmd.extend(["--project", self.get_option("project")])
exec_cmd.extend(["exec", f"{self.get_option('remote')}:{self._host()}", "--"])
if self.get_option("remote_user") != "root":
self._display.vvv(
f"INFO: Running as non-root user: {self.get_option('remote_user')}, \
trying to run 'lxc exec' with become method: {self.get_option('lxd_become_method')}",
host=self._host(),
)
exec_cmd.extend(
[self.get_option("lxd_become_method"), self.get_option("remote_user"), "-c"]
)
exec_cmd.extend([self.get_option("executable"), "-c", cmd])
return exec_cmd
def exec_command(self, cmd, in_data=None, sudoable=True):
""" execute a command on the lxd host """
super(Connection, self).exec_command(cmd, in_data=in_data, sudoable=sudoable)
self._display.vvv(f"EXEC {cmd}", host=self._host())
self._display.vvv(u"EXEC {0}".format(cmd), host=self._host())
local_cmd = self._build_command(cmd)
self._display.vvvvv(f"EXEC {local_cmd}", host=self._host())
local_cmd = [self._lxc_cmd]
if self.get_option("project"):
local_cmd.extend(["--project", self.get_option("project")])
local_cmd.extend([
"exec",
"%s:%s" % (self.get_option("remote"), self._host()),
"--",
self.get_option("executable"), "-c", cmd
])
self._display.vvvvv(u"EXEC {0}".format(local_cmd), host=self._host())
local_cmd = [to_bytes(i, errors='surrogate_or_strict') for i in local_cmd]
in_data = to_bytes(in_data, errors='surrogate_or_strict', nonstring='passthru')
@@ -151,73 +116,33 @@ class Connection(ConnectionBase):
stdout = to_text(stdout)
stderr = to_text(stderr)
self._display.vvvvv(f"EXEC lxc output: {stdout} {stderr}", host=self._host())
self._display.vvvvv(u"EXEC lxc output: {0} {1}".format(stdout, stderr), host=self._host())
if "is not running" in stderr:
raise AnsibleConnectionFailure(f"instance not running: {self._host()}")
raise AnsibleConnectionFailure("instance not running: %s" % self._host())
if stderr.strip() == "Error: Instance not found" or stderr.strip() == "error: not found":
raise AnsibleConnectionFailure(f"instance not found: {self._host()}")
raise AnsibleConnectionFailure("instance not found: %s" % self._host())
return process.returncode, stdout, stderr
def _get_remote_uid_gid(self) -> tuple[int, int]:
"""Get the user and group ID of 'remote_user' from the instance."""
rc, uid_out, err = self.exec_command("/bin/id -u")
if rc != 0:
raise AnsibleError(
f"Failed to get remote uid for user {self.get_option('remote_user')}: {err}"
)
uid = uid_out.strip()
rc, gid_out, err = self.exec_command("/bin/id -g")
if rc != 0:
raise AnsibleError(
f"Failed to get remote gid for user {self.get_option('remote_user')}: {err}"
)
gid = gid_out.strip()
return int(uid), int(gid)
def put_file(self, in_path, out_path):
""" put a file from local to lxd """
super(Connection, self).put_file(in_path, out_path)
self._display.vvv(f"PUT {in_path} TO {out_path}", host=self._host())
self._display.vvv(u"PUT {0} TO {1}".format(in_path, out_path), host=self._host())
if not os.path.isfile(to_bytes(in_path, errors='surrogate_or_strict')):
raise AnsibleFileNotFound(f"input path is not a file: {in_path}")
raise AnsibleFileNotFound("input path is not a file: %s" % in_path)
local_cmd = [self._lxc_cmd]
if self.get_option("project"):
local_cmd.extend(["--project", self.get_option("project")])
if self.get_option("remote_user") != "root":
uid, gid = self._get_remote_uid_gid()
local_cmd.extend(
[
"file",
"push",
"--uid",
str(uid),
"--gid",
str(gid),
in_path,
f"{self.get_option('remote')}:{self._host()}/{out_path}",
]
)
else:
local_cmd.extend(
[
"file",
"push",
in_path,
f"{self.get_option('remote')}:{self._host()}/{out_path}",
]
)
self._display.vvvvv(f"PUT {local_cmd}", host=self._host())
local_cmd.extend([
"file", "push",
in_path,
"%s:%s/%s" % (self.get_option("remote"), self._host(), out_path)
])
local_cmd = [to_bytes(i, errors='surrogate_or_strict') for i in local_cmd]
@@ -228,14 +153,14 @@ class Connection(ConnectionBase):
""" fetch a file from lxd to local """
super(Connection, self).fetch_file(in_path, out_path)
self._display.vvv(f"FETCH {in_path} TO {out_path}", host=self._host())
self._display.vvv(u"FETCH {0} TO {1}".format(in_path, out_path), host=self._host())
local_cmd = [self._lxc_cmd]
if self.get_option("project"):
local_cmd.extend(["--project", self.get_option("project")])
local_cmd.extend([
"file", "pull",
f"{self.get_option('remote')}:{self._host()}/{in_path}",
"%s:%s/%s" % (self.get_option("remote"), self._host(), in_path),
out_path
])

View File

@@ -1,857 +0,0 @@
# -*- coding: utf-8 -*-
# Derived from ansible/plugins/connection/paramiko_ssh.py (c) 2012, Michael DeHaan <michael.dehaan@gmail.com>
# Copyright (c) 2024 Nils Stein (@mietzen) <github.nstein@mailbox.org>
# Copyright (c) 2024 Ansible Project
# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
# SPDX-License-Identifier: GPL-3.0-or-later
from __future__ import annotations
DOCUMENTATION = r"""
author: Nils Stein (@mietzen) <github.nstein@mailbox.org>
name: proxmox_pct_remote
short_description: Run tasks in Proxmox LXC container instances using pct CLI via SSH
requirements:
- paramiko
description:
- Run commands or put/fetch files to an existing Proxmox LXC container using pct CLI via SSH.
- Uses the Python SSH implementation (Paramiko) to connect to the Proxmox host.
version_added: "10.3.0"
options:
remote_addr:
description:
- Address of the remote target.
default: inventory_hostname
type: string
vars:
- name: inventory_hostname
- name: ansible_host
- name: ansible_ssh_host
- name: ansible_paramiko_host
port:
description: Remote port to connect to.
type: int
default: 22
ini:
- section: defaults
key: remote_port
- section: paramiko_connection
key: remote_port
env:
- name: ANSIBLE_REMOTE_PORT
- name: ANSIBLE_REMOTE_PARAMIKO_PORT
vars:
- name: ansible_port
- name: ansible_ssh_port
- name: ansible_paramiko_port
keyword:
- name: port
remote_user:
description:
- User to login/authenticate as.
- Can be set from the CLI via the C(--user) or C(-u) options.
type: string
vars:
- name: ansible_user
- name: ansible_ssh_user
- name: ansible_paramiko_user
env:
- name: ANSIBLE_REMOTE_USER
- name: ANSIBLE_PARAMIKO_REMOTE_USER
ini:
- section: defaults
key: remote_user
- section: paramiko_connection
key: remote_user
keyword:
- name: remote_user
password:
description:
- Secret used to either login the SSH server or as a passphrase for SSH keys that require it.
- Can be set from the CLI via the C(--ask-pass) option.
type: string
vars:
- name: ansible_password
- name: ansible_ssh_pass
- name: ansible_ssh_password
- name: ansible_paramiko_pass
- name: ansible_paramiko_password
use_rsa_sha2_algorithms:
description:
- Whether or not to enable RSA SHA2 algorithms for pubkeys and hostkeys.
- On paramiko versions older than 2.9, this only affects hostkeys.
- For behavior matching paramiko<2.9 set this to V(false).
vars:
- name: ansible_paramiko_use_rsa_sha2_algorithms
ini:
- {key: use_rsa_sha2_algorithms, section: paramiko_connection}
env:
- {name: ANSIBLE_PARAMIKO_USE_RSA_SHA2_ALGORITHMS}
default: true
type: boolean
host_key_auto_add:
description: "Automatically add host keys to C(~/.ssh/known_hosts)."
env:
- name: ANSIBLE_PARAMIKO_HOST_KEY_AUTO_ADD
ini:
- key: host_key_auto_add
section: paramiko_connection
type: boolean
look_for_keys:
default: True
description: "Set to V(false) to disable searching for private key files in C(~/.ssh/)."
env:
- name: ANSIBLE_PARAMIKO_LOOK_FOR_KEYS
ini:
- {key: look_for_keys, section: paramiko_connection}
type: boolean
proxy_command:
default: ""
description:
- Proxy information for running the connection via a jumphost.
type: string
env:
- name: ANSIBLE_PARAMIKO_PROXY_COMMAND
ini:
- {key: proxy_command, section: paramiko_connection}
vars:
- name: ansible_paramiko_proxy_command
pty:
default: True
description: "C(sudo) usually requires a PTY, V(true) to give a PTY and V(false) to not give a PTY."
env:
- name: ANSIBLE_PARAMIKO_PTY
ini:
- section: paramiko_connection
key: pty
type: boolean
record_host_keys:
default: True
description: "Save the host keys to a file."
env:
- name: ANSIBLE_PARAMIKO_RECORD_HOST_KEYS
ini:
- section: paramiko_connection
key: record_host_keys
type: boolean
host_key_checking:
description: "Set this to V(false) if you want to avoid host key checking by the underlying tools Ansible uses to connect to the host."
type: boolean
default: true
env:
- name: ANSIBLE_HOST_KEY_CHECKING
- name: ANSIBLE_SSH_HOST_KEY_CHECKING
- name: ANSIBLE_PARAMIKO_HOST_KEY_CHECKING
ini:
- section: defaults
key: host_key_checking
- section: paramiko_connection
key: host_key_checking
vars:
- name: ansible_host_key_checking
- name: ansible_ssh_host_key_checking
- name: ansible_paramiko_host_key_checking
use_persistent_connections:
description: "Toggles the use of persistence for connections."
type: boolean
default: False
env:
- name: ANSIBLE_USE_PERSISTENT_CONNECTIONS
ini:
- section: defaults
key: use_persistent_connections
banner_timeout:
type: float
default: 30
description:
- Configures, in seconds, the amount of time to wait for the SSH
banner to be presented. This option is supported by paramiko
version 1.15.0 or newer.
ini:
- section: paramiko_connection
key: banner_timeout
env:
- name: ANSIBLE_PARAMIKO_BANNER_TIMEOUT
timeout:
type: int
default: 10
description: Number of seconds until the plugin gives up on failing to establish a TCP connection.
ini:
- section: defaults
key: timeout
- section: ssh_connection
key: timeout
- section: paramiko_connection
key: timeout
env:
- name: ANSIBLE_TIMEOUT
- name: ANSIBLE_SSH_TIMEOUT
- name: ANSIBLE_PARAMIKO_TIMEOUT
vars:
- name: ansible_ssh_timeout
- name: ansible_paramiko_timeout
cli:
- name: timeout
lock_file_timeout:
type: int
default: 60
description: Number of seconds until the plugin gives up on trying to write a lock file when writing SSH known host keys.
vars:
- name: ansible_lock_file_timeout
env:
- name: ANSIBLE_LOCK_FILE_TIMEOUT
private_key_file:
description:
- Path to private key file to use for authentication.
type: string
ini:
- section: defaults
key: private_key_file
- section: paramiko_connection
key: private_key_file
env:
- name: ANSIBLE_PRIVATE_KEY_FILE
- name: ANSIBLE_PARAMIKO_PRIVATE_KEY_FILE
vars:
- name: ansible_private_key_file
- name: ansible_ssh_private_key_file
- name: ansible_paramiko_private_key_file
cli:
- name: private_key_file
option: "--private-key"
vmid:
description:
- LXC Container ID
type: int
vars:
- name: proxmox_vmid
proxmox_become_method:
description:
- Become command used in proxmox
type: str
default: sudo
vars:
- name: proxmox_become_method
notes:
- >
When NOT using this plugin as root, you need to have a become mechanism,
e.g. C(sudo), installed on Proxmox and setup so we can run it without prompting for the password.
Inside the container, we need a shell, for example C(sh) and the C(cat) command to be available in the C(PATH) for this plugin to work.
"""
EXAMPLES = r"""
# --------------------------------------------------------------
# Setup sudo with password less access to pct for user 'ansible':
# --------------------------------------------------------------
#
# Open a Proxmox root shell and execute:
# $ useradd -d /opt/ansible-pct -r -m -s /bin/sh ansible
# $ mkdir -p /opt/ansible-pct/.ssh
# $ ssh-keygen -t ed25519 -C 'ansible' -N "" -f /opt/ansible-pct/.ssh/ansible <<< y > /dev/null
# $ cat /opt/ansible-pct/.ssh/ansible
# $ mv /opt/ansible-pct/.ssh/ansible.pub /opt/ansible-pct/.ssh/authorized-keys
# $ rm /opt/ansible-pct/.ssh/ansible*
# $ chown -R ansible:ansible /opt/ansible-pct/.ssh
# $ chmod 700 /opt/ansible-pct/.ssh
# $ chmod 600 /opt/ansible-pct/.ssh/authorized-keys
# $ echo 'ansible ALL = (root) NOPASSWD: /usr/sbin/pct' > /etc/sudoers.d/ansible_pct
#
# Save the displayed private key and add it to your ssh-agent
#
# Or use ansible:
# ---
# - name: Setup ansible-pct user and configure environment on Proxmox host
# hosts: proxmox
# become: true
# gather_facts: false
#
# tasks:
# - name: Create ansible user
# ansible.builtin.user:
# name: ansible
# comment: Ansible User
# home: /opt/ansible-pct
# shell: /bin/sh
# create_home: true
# system: true
#
# - name: Create .ssh directory
# ansible.builtin.file:
# path: /opt/ansible-pct/.ssh
# state: directory
# owner: ansible
# group: ansible
# mode: '0700'
#
# - name: Generate SSH key for ansible user
# community.crypto.openssh_keypair:
# path: /opt/ansible-pct/.ssh/ansible
# type: ed25519
# comment: 'ansible'
# force: true
# mode: '0600'
# owner: ansible
# group: ansible
#
# - name: Set public key as authorized key
# ansible.builtin.copy:
# src: /opt/ansible-pct/.ssh/ansible.pub
# dest: /opt/ansible-pct/.ssh/authorized-keys
# remote_src: yes
# owner: ansible
# group: ansible
# mode: '0600'
#
# - name: Add sudoers entry for ansible user
# ansible.builtin.copy:
# content: 'ansible ALL = (root) NOPASSWD: /usr/sbin/pct'
# dest: /etc/sudoers.d/ansible_pct
# owner: root
# group: root
# mode: '0440'
#
# - name: Fetch private SSH key to localhost
# ansible.builtin.fetch:
# src: /opt/ansible-pct/.ssh/ansible
# dest: ~/.ssh/proxmox_ansible_private_key
# flat: yes
# fail_on_missing: true
#
# - name: Clean up generated SSH keys
# ansible.builtin.file:
# path: /opt/ansible-pct/.ssh/ansible*
# state: absent
#
# - name: Configure private key permissions on localhost
# hosts: localhost
# tasks:
# - name: Set permissions for fetched private key
# ansible.builtin.file:
# path: ~/.ssh/proxmox_ansible_private_key
# mode: '0600'
#
# --------------------------------
# Static inventory file: hosts.yml
# --------------------------------
# all:
# children:
# lxc:
# hosts:
# container-1:
# ansible_host: 10.0.0.10
# proxmox_vmid: 100
# ansible_connection: community.general.proxmox_pct_remote
# ansible_user: ansible
# container-2:
# ansible_host: 10.0.0.10
# proxmox_vmid: 200
# ansible_connection: community.general.proxmox_pct_remote
# ansible_user: ansible
# proxmox:
# hosts:
# proxmox-1:
# ansible_host: 10.0.0.10
#
#
# ---------------------------------------------
# Dynamic inventory file: inventory.proxmox.yml
# ---------------------------------------------
# plugin: community.general.proxmox
# url: https://10.0.0.10:8006
# validate_certs: false
# user: ansible@pam
# token_id: ansible
# token_secret: !vault |
# $ANSIBLE_VAULT;1.1;AES256
# ...
# want_facts: true
# exclude_nodes: true
# filters:
# - proxmox_vmtype == "lxc"
# want_proxmox_nodes_ansible_host: false
# compose:
# ansible_host: "'10.0.0.10'"
# ansible_connection: "'community.general.proxmox_pct_remote'"
# ansible_user: "'ansible'"
#
#
# ----------------------
# Playbook: playbook.yml
# ----------------------
---
- hosts: lxc
# On nodes with many containers you might want to deactivate the devices facts
# or set `gather_facts: false` if you don't need them.
# More info on gathering fact subsets:
# https://docs.ansible.com/ansible/latest/collections/ansible/builtin/setup_module.html
#
# gather_facts: true
# gather_subset:
# - "!devices"
tasks:
- name: Ping LXC container
ansible.builtin.ping:
"""
import os
import pathlib
import socket
import tempfile
import typing as t
from ansible.errors import (
AnsibleAuthenticationFailure,
AnsibleConnectionFailure,
AnsibleError,
)
from ansible_collections.community.general.plugins.module_utils._filelock import FileLock, LockTimeout
from ansible.module_utils.common.text.converters import to_bytes, to_native, to_text
from ansible.module_utils.compat.paramiko import PARAMIKO_IMPORT_ERR, paramiko
from ansible.module_utils.compat.version import LooseVersion
from ansible.plugins.connection import ConnectionBase
from ansible.utils.display import Display
from ansible.utils.path import makedirs_safe
from binascii import hexlify
display = Display()
def authenticity_msg(hostname: str, ktype: str, fingerprint: str) -> str:
msg = f"""
paramiko: The authenticity of host '{hostname}' can't be established.
The {ktype} key fingerprint is {fingerprint}.
Are you sure you want to continue connecting (yes/no)?
"""
return msg
MissingHostKeyPolicy: type = object
if paramiko:
MissingHostKeyPolicy = paramiko.MissingHostKeyPolicy
class MyAddPolicy(MissingHostKeyPolicy):
"""
Based on AutoAddPolicy in paramiko so we can determine when keys are added
and also prompt for input.
Policy for automatically adding the hostname and new host key to the
local L{HostKeys} object, and saving it. This is used by L{SSHClient}.
"""
def __init__(self, connection: Connection) -> None:
self.connection = connection
self._options = connection._options
def missing_host_key(self, client, hostname, key) -> None:
if all((self.connection.get_option('host_key_checking'), not self.connection.get_option('host_key_auto_add'))):
fingerprint = hexlify(key.get_fingerprint())
ktype = key.get_name()
if self.connection.get_option('use_persistent_connections') or self.connection.force_persistence:
# don't print the prompt string since the user cannot respond
# to the question anyway
raise AnsibleError(authenticity_msg(hostname, ktype, fingerprint)[1:92])
inp = to_text(
display.prompt_until(authenticity_msg(hostname, ktype, fingerprint), private=False),
errors='surrogate_or_strict'
)
if inp.lower() not in ['yes', 'y', '']:
raise AnsibleError('host connection rejected by user')
key._added_by_ansible_this_time = True
# existing implementation below:
client._host_keys.add(hostname, key.get_name(), key)
# host keys are actually saved in close() function below
# in order to control ordering.
class Connection(ConnectionBase):
""" SSH based connections (paramiko) to Proxmox pct """
transport = 'community.general.proxmox_pct_remote'
_log_channel: str | None = None
def __init__(self, play_context, new_stdin, *args, **kwargs):
super(Connection, self).__init__(play_context, new_stdin, *args, **kwargs)
def _set_log_channel(self, name: str) -> None:
""" Mimic paramiko.SSHClient.set_log_channel """
self._log_channel = name
def _parse_proxy_command(self, port: int = 22) -> dict[str, t.Any]:
proxy_command = self.get_option('proxy_command') or None
sock_kwarg = {}
if proxy_command:
replacers = {
'%h': self.get_option('remote_addr'),
'%p': port,
'%r': self.get_option('remote_user')
}
for find, replace in replacers.items():
proxy_command = proxy_command.replace(find, str(replace))
try:
sock_kwarg = {'sock': paramiko.ProxyCommand(proxy_command)}
display.vvv(f'CONFIGURE PROXY COMMAND FOR CONNECTION: {proxy_command}', host=self.get_option('remote_addr'))
except AttributeError:
display.warning('Paramiko ProxyCommand support unavailable. '
'Please upgrade to Paramiko 1.9.0 or newer. '
'Not using configured ProxyCommand')
return sock_kwarg
def _connect(self) -> Connection:
""" activates the connection object """
if paramiko is None:
raise AnsibleError(f'paramiko is not installed: {to_native(PARAMIKO_IMPORT_ERR)}')
port = self.get_option('port')
display.vvv(f'ESTABLISH PARAMIKO SSH CONNECTION FOR USER: {self.get_option("remote_user")} on PORT {to_text(port)} TO {self.get_option("remote_addr")}',
host=self.get_option('remote_addr'))
ssh = paramiko.SSHClient()
# Set pubkey and hostkey algorithms to disable, the only manipulation allowed currently
# is keeping or omitting rsa-sha2 algorithms
# default_keys: t.Tuple[str] = ()
paramiko_preferred_pubkeys = getattr(paramiko.Transport, '_preferred_pubkeys', ())
paramiko_preferred_hostkeys = getattr(paramiko.Transport, '_preferred_keys', ())
use_rsa_sha2_algorithms = self.get_option('use_rsa_sha2_algorithms')
disabled_algorithms: t.Dict[str, t.Iterable[str]] = {}
if not use_rsa_sha2_algorithms:
if paramiko_preferred_pubkeys:
disabled_algorithms['pubkeys'] = tuple(a for a in paramiko_preferred_pubkeys if 'rsa-sha2' in a)
if paramiko_preferred_hostkeys:
disabled_algorithms['keys'] = tuple(a for a in paramiko_preferred_hostkeys if 'rsa-sha2' in a)
# override paramiko's default logger name
if self._log_channel is not None:
ssh.set_log_channel(self._log_channel)
self.keyfile = os.path.expanduser('~/.ssh/known_hosts')
if self.get_option('host_key_checking'):
for ssh_known_hosts in ('/etc/ssh/ssh_known_hosts', '/etc/openssh/ssh_known_hosts'):
try:
ssh.load_system_host_keys(ssh_known_hosts)
break
except IOError:
pass # file was not found, but not required to function
except paramiko.hostkeys.InvalidHostKey as e:
raise AnsibleConnectionFailure(f'Invalid host key: {to_text(e.line)}')
try:
ssh.load_system_host_keys()
except paramiko.hostkeys.InvalidHostKey as e:
raise AnsibleConnectionFailure(f'Invalid host key: {to_text(e.line)}')
ssh_connect_kwargs = self._parse_proxy_command(port)
ssh.set_missing_host_key_policy(MyAddPolicy(self))
conn_password = self.get_option('password')
allow_agent = True
if conn_password is not None:
allow_agent = False
try:
key_filename = None
if self.get_option('private_key_file'):
key_filename = os.path.expanduser(self.get_option('private_key_file'))
# paramiko 2.2 introduced auth_timeout parameter
if LooseVersion(paramiko.__version__) >= LooseVersion('2.2.0'):
ssh_connect_kwargs['auth_timeout'] = self.get_option('timeout')
# paramiko 1.15 introduced banner timeout parameter
if LooseVersion(paramiko.__version__) >= LooseVersion('1.15.0'):
ssh_connect_kwargs['banner_timeout'] = self.get_option('banner_timeout')
ssh.connect(
self.get_option('remote_addr').lower(),
username=self.get_option('remote_user'),
allow_agent=allow_agent,
look_for_keys=self.get_option('look_for_keys'),
key_filename=key_filename,
password=conn_password,
timeout=self.get_option('timeout'),
port=port,
disabled_algorithms=disabled_algorithms,
**ssh_connect_kwargs,
)
except paramiko.ssh_exception.BadHostKeyException as e:
raise AnsibleConnectionFailure(f'host key mismatch for {to_text(e.hostname)}')
except paramiko.ssh_exception.AuthenticationException as e:
msg = f'Failed to authenticate: {e}'
raise AnsibleAuthenticationFailure(msg)
except Exception as e:
msg = to_text(e)
if u'PID check failed' in msg:
raise AnsibleError('paramiko version issue, please upgrade paramiko on the machine running ansible')
elif u'Private key file is encrypted' in msg:
msg = f'ssh {self.get_option("remote_user")}@{self.get_options("remote_addr")}:{port} : ' + \
f'{msg}\nTo connect as a different user, use -u <username>.'
raise AnsibleConnectionFailure(msg)
else:
raise AnsibleConnectionFailure(msg)
self.ssh = ssh
self._connected = True
return self
def _any_keys_added(self) -> bool:
for hostname, keys in self.ssh._host_keys.items():
for keytype, key in keys.items():
added_this_time = getattr(key, '_added_by_ansible_this_time', False)
if added_this_time:
return True
return False
def _save_ssh_host_keys(self, filename: str) -> None:
"""
not using the paramiko save_ssh_host_keys function as we want to add new SSH keys at the bottom so folks
don't complain about it :)
"""
if not self._any_keys_added():
return
path = os.path.expanduser('~/.ssh')
makedirs_safe(path)
with open(filename, 'w') as f:
for hostname, keys in self.ssh._host_keys.items():
for keytype, key in keys.items():
# was f.write
added_this_time = getattr(key, '_added_by_ansible_this_time', False)
if not added_this_time:
f.write(f'{hostname} {keytype} {key.get_base64()}\n')
for hostname, keys in self.ssh._host_keys.items():
for keytype, key in keys.items():
added_this_time = getattr(key, '_added_by_ansible_this_time', False)
if added_this_time:
f.write(f'{hostname} {keytype} {key.get_base64()}\n')
def _build_pct_command(self, cmd: str) -> str:
cmd = ['/usr/sbin/pct', 'exec', str(self.get_option('vmid')), '--', cmd]
if self.get_option('remote_user') != 'root':
cmd = [self.get_option('proxmox_become_method')] + cmd
display.vvv(f'INFO Running as non root user: {self.get_option("remote_user")}, trying to run pct with become method: ' +
f'{self.get_option("proxmox_become_method")}',
host=self.get_option('remote_addr'))
return ' '.join(cmd)
def exec_command(self, cmd: str, in_data: bytes | None = None, sudoable: bool = True) -> tuple[int, bytes, bytes]:
""" run a command on inside the LXC container """
cmd = self._build_pct_command(cmd)
super(Connection, self).exec_command(cmd, in_data=in_data, sudoable=sudoable)
bufsize = 4096
try:
self.ssh.get_transport().set_keepalive(5)
chan = self.ssh.get_transport().open_session()
except Exception as e:
text_e = to_text(e)
msg = 'Failed to open session'
if text_e:
msg += f': {text_e}'
raise AnsibleConnectionFailure(to_native(msg))
# sudo usually requires a PTY (cf. requiretty option), therefore
# we give it one by default (pty=True in ansible.cfg), and we try
# to initialise from the calling environment when sudoable is enabled
if self.get_option('pty') and sudoable:
chan.get_pty(term=os.getenv('TERM', 'vt100'), width=int(os.getenv('COLUMNS', 0)), height=int(os.getenv('LINES', 0)))
display.vvv(f'EXEC {cmd}', host=self.get_option('remote_addr'))
cmd = to_bytes(cmd, errors='surrogate_or_strict')
no_prompt_out = b''
no_prompt_err = b''
become_output = b''
try:
chan.exec_command(cmd)
if self.become and self.become.expect_prompt():
password_prompt = False
become_success = False
while not (become_success or password_prompt):
display.debug('Waiting for Privilege Escalation input')
chunk = chan.recv(bufsize)
display.debug(f'chunk is: {to_text(chunk)}')
if not chunk:
if b'unknown user' in become_output:
n_become_user = to_native(self.become.get_option('become_user'))
raise AnsibleError(f'user {n_become_user} does not exist')
else:
break
# raise AnsibleError('ssh connection closed waiting for password prompt')
become_output += chunk
# need to check every line because we might get lectured
# and we might get the middle of a line in a chunk
for line in become_output.splitlines(True):
if self.become.check_success(line):
become_success = True
break
elif self.become.check_password_prompt(line):
password_prompt = True
break
if password_prompt:
if self.become:
become_pass = self.become.get_option('become_pass')
chan.sendall(to_bytes(become_pass, errors='surrogate_or_strict') + b'\n')
else:
raise AnsibleError('A password is required but none was supplied')
else:
no_prompt_out += become_output
no_prompt_err += become_output
if in_data:
for i in range(0, len(in_data), bufsize):
chan.send(in_data[i:i + bufsize])
chan.shutdown_write()
elif in_data == b'':
chan.shutdown_write()
except socket.timeout:
raise AnsibleError('ssh timed out waiting for privilege escalation.\n' + to_text(become_output))
stdout = b''.join(chan.makefile('rb', bufsize))
stderr = b''.join(chan.makefile_stderr('rb', bufsize))
returncode = chan.recv_exit_status()
if 'pct: not found' in stderr.decode('utf-8'):
raise AnsibleError(
f'pct not found in path of host: {to_text(self.get_option("remote_addr"))}')
return (returncode, no_prompt_out + stdout, no_prompt_out + stderr)
def put_file(self, in_path: str, out_path: str) -> None:
""" transfer a file from local to remote """
display.vvv(f'PUT {in_path} TO {out_path}', host=self.get_option('remote_addr'))
try:
with open(in_path, 'rb') as f:
data = f.read()
returncode, stdout, stderr = self.exec_command(
' '.join([
self._shell.executable, '-c',
self._shell.quote(f'cat > {out_path}')]),
in_data=data,
sudoable=False)
if returncode != 0:
if 'cat: not found' in stderr.decode('utf-8'):
raise AnsibleError(
f'cat not found in path of container: {to_text(self.get_option("vmid"))}')
raise AnsibleError(
f'{to_text(stdout)}\n{to_text(stderr)}')
except Exception as e:
raise AnsibleError(
f'error occurred while putting file from {in_path} to {out_path}!\n{to_text(e)}')
def fetch_file(self, in_path: str, out_path: str) -> None:
""" save a remote file to the specified path """
display.vvv(f'FETCH {in_path} TO {out_path}', host=self.get_option('remote_addr'))
try:
returncode, stdout, stderr = self.exec_command(
' '.join([
self._shell.executable, '-c',
self._shell.quote(f'cat {in_path}')]),
sudoable=False)
if returncode != 0:
if 'cat: not found' in stderr.decode('utf-8'):
raise AnsibleError(
f'cat not found in path of container: {to_text(self.get_option("vmid"))}')
raise AnsibleError(
f'{to_text(stdout)}\n{to_text(stderr)}')
with open(out_path, 'wb') as f:
f.write(stdout)
except Exception as e:
raise AnsibleError(
f'error occurred while fetching file from {in_path} to {out_path}!\n{to_text(e)}')
def reset(self) -> None:
""" reset the connection """
if not self._connected:
return
self.close()
self._connect()
def close(self) -> None:
""" terminate the connection """
if self.get_option('host_key_checking') and self.get_option('record_host_keys') and self._any_keys_added():
# add any new SSH host keys -- warning -- this could be slow
# (This doesn't acquire the connection lock because it needs
# to exclude only other known_hosts writers, not connections
# that are starting up.)
lockfile = os.path.basename(self.keyfile)
dirname = os.path.dirname(self.keyfile)
makedirs_safe(dirname)
tmp_keyfile_name = None
try:
with FileLock().lock_file(lockfile, dirname, self.get_option('lock_file_timeout')):
# just in case any were added recently
self.ssh.load_system_host_keys()
self.ssh._host_keys.update(self.ssh._system_host_keys)
# gather information about the current key file, so
# we can ensure the new file has the correct mode/owner
key_dir = os.path.dirname(self.keyfile)
if os.path.exists(self.keyfile):
key_stat = os.stat(self.keyfile)
mode = key_stat.st_mode & 0o777
uid = key_stat.st_uid
gid = key_stat.st_gid
else:
mode = 0o644
uid = os.getuid()
gid = os.getgid()
# Save the new keys to a temporary file and move it into place
# rather than rewriting the file. We set delete=False because
# the file will be moved into place rather than cleaned up.
with tempfile.NamedTemporaryFile(dir=key_dir, delete=False) as tmp_keyfile:
tmp_keyfile_name = tmp_keyfile.name
os.chmod(tmp_keyfile_name, mode)
os.chown(tmp_keyfile_name, uid, gid)
self._save_ssh_host_keys(tmp_keyfile_name)
os.rename(tmp_keyfile_name, self.keyfile)
except LockTimeout:
raise AnsibleError(
f'writing lock file for {self.keyfile} ran in to the timeout of {self.get_option("lock_file_timeout")}s')
except paramiko.hostkeys.InvalidHostKey as e:
raise AnsibleConnectionFailure(f'Invalid host key: {e.line}')
except Exception as e:
# unable to save keys, including scenario when key was invalid
# and caught earlier
raise AnsibleError(
f'error occurred while writing SSH host keys!\n{to_text(e)}')
finally:
if tmp_keyfile_name is not None:
pathlib.Path(tmp_keyfile_name).unlink(missing_ok=True)
self.ssh.close()
self._connected = False

View File

@@ -8,7 +8,8 @@
#
# Written by: Kushal Das (https://github.com/kushaldas)
from __future__ import annotations
from __future__ import (absolute_import, division, print_function)
__metaclass__ = type
DOCUMENTATION = r"""
@@ -76,7 +77,7 @@ class Connection(ConnectionBase):
"""
display.vvvv("CMD: ", cmd)
if not cmd.endswith("\n"):
cmd = f"{cmd}\n"
cmd = cmd + "\n"
local_cmd = []
# For dom0
@@ -93,7 +94,7 @@ class Connection(ConnectionBase):
display.vvvv("Local cmd: ", local_cmd)
display.vvv(f"RUN {local_cmd}", host=self._remote_vmname)
display.vvv("RUN %s" % (local_cmd,), host=self._remote_vmname)
p = subprocess.Popen(local_cmd, shell=False, stdin=subprocess.PIPE,
stdout=subprocess.PIPE, stderr=subprocess.PIPE)
@@ -112,42 +113,42 @@ class Connection(ConnectionBase):
"""Run specified command in a running QubesVM """
super(Connection, self).exec_command(cmd, in_data=in_data, sudoable=sudoable)
display.vvvv(f"CMD IS: {cmd}")
display.vvvv("CMD IS: %s" % cmd)
rc, stdout, stderr = self._qubes(cmd)
display.vvvvv(f"STDOUT {stdout!r} STDERR {stderr!r}")
display.vvvvv("STDOUT %r STDERR %r" % (stdout, stderr))
return rc, stdout, stderr
def put_file(self, in_path, out_path):
""" Place a local file located in 'in_path' inside VM at 'out_path' """
super(Connection, self).put_file(in_path, out_path)
display.vvv(f"PUT {in_path} TO {out_path}", host=self._remote_vmname)
display.vvv("PUT %s TO %s" % (in_path, out_path), host=self._remote_vmname)
with open(in_path, "rb") as fobj:
source_data = fobj.read()
retcode, dummy, dummy = self._qubes(f'cat > "{out_path}\"\n', source_data, "qubes.VMRootShell")
retcode, dummy, dummy = self._qubes('cat > "{0}"\n'.format(out_path), source_data, "qubes.VMRootShell")
# if qubes.VMRootShell service not supported, fallback to qubes.VMShell and
# hope it will have appropriate permissions
if retcode == 127:
retcode, dummy, dummy = self._qubes(f'cat > "{out_path}\"\n', source_data)
retcode, dummy, dummy = self._qubes('cat > "{0}"\n'.format(out_path), source_data)
if retcode != 0:
raise AnsibleConnectionFailure(f'Failed to put_file to {out_path}')
raise AnsibleConnectionFailure('Failed to put_file to {0}'.format(out_path))
def fetch_file(self, in_path, out_path):
"""Obtain file specified via 'in_path' from the container and place it at 'out_path' """
super(Connection, self).fetch_file(in_path, out_path)
display.vvv(f"FETCH {in_path} TO {out_path}", host=self._remote_vmname)
display.vvv("FETCH %s TO %s" % (in_path, out_path), host=self._remote_vmname)
# We are running in dom0
cmd_args_list = ["qvm-run", "--pass-io", self._remote_vmname, f"cat {in_path}"]
cmd_args_list = ["qvm-run", "--pass-io", self._remote_vmname, "cat {0}".format(in_path)]
with open(out_path, "wb") as fobj:
p = subprocess.Popen(cmd_args_list, shell=False, stdout=fobj)
p.communicate()
if p.returncode != 0:
raise AnsibleConnectionFailure(f'Failed to fetch file to {out_path}')
raise AnsibleConnectionFailure('Failed to fetch file to {0}'.format(out_path))
def close(self):
""" Closing the connection """

View File

@@ -7,7 +7,8 @@
# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
# SPDX-License-Identifier: GPL-3.0-or-later
from __future__ import annotations
from __future__ import (absolute_import, division, print_function)
__metaclass__ = type
DOCUMENTATION = r"""
author: Michael Scherer (@mscherer) <misc@zarb.org>
@@ -58,11 +59,11 @@ class Connection(ConnectionBase):
if in_data:
raise errors.AnsibleError("Internal Error: this module does not support optimized module pipelining")
self._display.vvv(f"EXEC {cmd}", host=self.host)
self._display.vvv("EXEC %s" % cmd, host=self.host)
# need to add 'true;' to work around https://github.com/saltstack/salt/issues/28077
res = self.client.cmd(self.host, 'cmd.exec_code_all', ['bash', f"true;{cmd}"])
res = self.client.cmd(self.host, 'cmd.exec_code_all', ['bash', 'true;' + cmd])
if self.host not in res:
raise errors.AnsibleError(f"Minion {self.host} didn't answer, check if salt-minion is running and the name is correct")
raise errors.AnsibleError("Minion %s didn't answer, check if salt-minion is running and the name is correct" % self.host)
p = res[self.host]
return p['retcode'], p['stdout'], p['stderr']
@@ -80,7 +81,7 @@ class Connection(ConnectionBase):
super(Connection, self).put_file(in_path, out_path)
out_path = self._normalize_path(out_path, '/')
self._display.vvv(f"PUT {in_path} TO {out_path}", host=self.host)
self._display.vvv("PUT %s TO %s" % (in_path, out_path), host=self.host)
with open(in_path, 'rb') as in_fh:
content = in_fh.read()
self.client.cmd(self.host, 'hashutil.base64_decodefile', [base64.b64encode(content), out_path])
@@ -92,7 +93,7 @@ class Connection(ConnectionBase):
super(Connection, self).fetch_file(in_path, out_path)
in_path = self._normalize_path(in_path, '/')
self._display.vvv(f"FETCH {in_path} TO {out_path}", host=self.host)
self._display.vvv("FETCH %s TO %s" % (in_path, out_path), host=self.host)
content = self.client.cmd(self.host, 'cp.get_file_str', [in_path])[self.host]
open(out_path, 'wb').write(content)

View File

@@ -8,7 +8,8 @@
# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
# SPDX-License-Identifier: GPL-3.0-or-later
from __future__ import annotations
from __future__ import (absolute_import, division, print_function)
__metaclass__ = type
DOCUMENTATION = r"""
author: Ansible Core Team
@@ -61,14 +62,14 @@ class Connection(ConnectionBase):
self.zlogin_cmd = to_bytes(self._search_executable('zlogin'))
if self.zone not in self.list_zones():
raise AnsibleError(f"incorrect zone name {self.zone}")
raise AnsibleError("incorrect zone name %s" % self.zone)
@staticmethod
def _search_executable(executable):
try:
return get_bin_path(executable)
except ValueError:
raise AnsibleError(f"{executable} command not found in PATH")
raise AnsibleError("%s command not found in PATH" % executable)
def list_zones(self):
process = subprocess.Popen([self.zoneadm_cmd, 'list', '-ip'],
@@ -93,7 +94,7 @@ class Connection(ConnectionBase):
# stdout, stderr = p.communicate()
path = process.stdout.readlines()[0].split(':')[3]
return f"{path}/root"
return path + '/root'
def _connect(self):
""" connect to the zone; nothing to do here """
@@ -116,7 +117,7 @@ class Connection(ConnectionBase):
local_cmd = [self.zlogin_cmd, self.zone, cmd]
local_cmd = map(to_bytes, local_cmd)
display.vvv(f"EXEC {local_cmd}", host=self.zone)
display.vvv("EXEC %s" % (local_cmd), host=self.zone)
p = subprocess.Popen(local_cmd, shell=False, stdin=stdin,
stdout=subprocess.PIPE, stderr=subprocess.PIPE)
@@ -139,7 +140,7 @@ class Connection(ConnectionBase):
exist in any given chroot. So for now we're choosing "/" instead.
This also happens to be the former default.
Can revisit using $HOME instead if it is a problem
Can revisit using $HOME instead if it's a problem
"""
if not remote_path.startswith(os.path.sep):
remote_path = os.path.join(os.path.sep, remote_path)
@@ -148,7 +149,7 @@ class Connection(ConnectionBase):
def put_file(self, in_path, out_path):
""" transfer a file from local to zone """
super(Connection, self).put_file(in_path, out_path)
display.vvv(f"PUT {in_path} TO {out_path}", host=self.zone)
display.vvv("PUT %s TO %s" % (in_path, out_path), host=self.zone)
out_path = shlex_quote(self._prefix_login_path(out_path))
try:
@@ -158,27 +159,27 @@ class Connection(ConnectionBase):
else:
count = ''
try:
p = self._buffered_exec_command(f'dd of={out_path} bs={BUFSIZE}{count}', stdin=in_file)
p = self._buffered_exec_command('dd of=%s bs=%s%s' % (out_path, BUFSIZE, count), stdin=in_file)
except OSError:
raise AnsibleError("jail connection requires dd command in the jail")
try:
stdout, stderr = p.communicate()
except Exception:
traceback.print_exc()
raise AnsibleError(f"failed to transfer file {in_path} to {out_path}")
raise AnsibleError("failed to transfer file %s to %s" % (in_path, out_path))
if p.returncode != 0:
raise AnsibleError(f"failed to transfer file {in_path} to {out_path}:\n{stdout}\n{stderr}")
raise AnsibleError("failed to transfer file %s to %s:\n%s\n%s" % (in_path, out_path, stdout, stderr))
except IOError:
raise AnsibleError(f"file or module does not exist at: {in_path}")
raise AnsibleError("file or module does not exist at: %s" % in_path)
def fetch_file(self, in_path, out_path):
""" fetch a file from zone to local """
super(Connection, self).fetch_file(in_path, out_path)
display.vvv(f"FETCH {in_path} TO {out_path}", host=self.zone)
display.vvv("FETCH %s TO %s" % (in_path, out_path), host=self.zone)
in_path = shlex_quote(self._prefix_login_path(in_path))
try:
p = self._buffered_exec_command(f'dd if={in_path} bs={BUFSIZE}')
p = self._buffered_exec_command('dd if=%s bs=%s' % (in_path, BUFSIZE))
except OSError:
raise AnsibleError("zone connection requires dd command in the zone")
@@ -190,10 +191,10 @@ class Connection(ConnectionBase):
chunk = p.stdout.read(BUFSIZE)
except Exception:
traceback.print_exc()
raise AnsibleError(f"failed to transfer file {in_path} to {out_path}")
raise AnsibleError("failed to transfer file %s to %s" % (in_path, out_path))
stdout, stderr = p.communicate()
if p.returncode != 0:
raise AnsibleError(f"failed to transfer file {in_path} to {out_path}:\n{stdout}\n{stderr}")
raise AnsibleError("failed to transfer file %s to %s:\n%s\n%s" % (in_path, out_path, stdout, stderr))
def close(self):
""" terminate the connection; nothing to do here """

View File

@@ -11,73 +11,75 @@ __metaclass__ = type
class ModuleDocFragment(object):
# Alicloud only documentation fragment
DOCUMENTATION = r"""
DOCUMENTATION = r'''
options:
alicloud_access_key:
description:
- Alibaba Cloud access key. If not set then the value of environment variable E(ALICLOUD_ACCESS_KEY), E(ALICLOUD_ACCESS_KEY_ID)
will be used instead.
- Alibaba Cloud access key. If not set then the value of environment variable E(ALICLOUD_ACCESS_KEY),
E(ALICLOUD_ACCESS_KEY_ID) will be used instead.
aliases: ['access_key_id', 'access_key']
type: str
alicloud_secret_key:
description:
- Alibaba Cloud secret key. If not set then the value of environment variable E(ALICLOUD_SECRET_KEY), E(ALICLOUD_SECRET_ACCESS_KEY)
will be used instead.
- Alibaba Cloud secret key. If not set then the value of environment variable E(ALICLOUD_SECRET_KEY),
E(ALICLOUD_SECRET_ACCESS_KEY) will be used instead.
aliases: ['secret_access_key', 'secret_key']
type: str
alicloud_region:
description:
- The Alibaba Cloud region to use. If not specified then the value of environment variable E(ALICLOUD_REGION), E(ALICLOUD_REGION_ID)
will be used instead.
- The Alibaba Cloud region to use. If not specified then the value of environment variable
E(ALICLOUD_REGION), E(ALICLOUD_REGION_ID) will be used instead.
aliases: ['region', 'region_id']
required: true
type: str
alicloud_security_token:
description:
- The Alibaba Cloud security token. If not specified then the value of environment variable E(ALICLOUD_SECURITY_TOKEN)
will be used instead.
- The Alibaba Cloud security token. If not specified then the value of environment variable
E(ALICLOUD_SECURITY_TOKEN) will be used instead.
aliases: ['security_token']
type: str
alicloud_assume_role:
description:
- If provided with a role ARN, Ansible will attempt to assume this role using the supplied credentials.
- The nested assume_role block supports C(alicloud_assume_role_arn), C(alicloud_assume_role_session_name), C(alicloud_assume_role_session_expiration)
and C(alicloud_assume_role_policy).
- The nested assume_role block supports C(alicloud_assume_role_arn), C(alicloud_assume_role_session_name),
C(alicloud_assume_role_session_expiration) and C(alicloud_assume_role_policy).
type: dict
aliases: ['assume_role']
alicloud_assume_role_arn:
description:
- The Alibaba Cloud C(role_arn). The ARN of the role to assume. If ARN is set to an empty string, it does not perform
role switching. It supports environment variable E(ALICLOUD_ASSUME_ROLE_ARN). ansible will execute with provided credentials.
- The Alibaba Cloud C(role_arn). The ARN of the role to assume. If ARN is set to an empty string,
it does not perform role switching. It supports environment variable E(ALICLOUD_ASSUME_ROLE_ARN).
ansible will execute with provided credentials.
aliases: ['assume_role_arn']
type: str
alicloud_assume_role_session_name:
description:
- The Alibaba Cloud session_name. The session name to use when assuming the role. If omitted, 'ansible' is passed to
the AssumeRole call as session name. It supports environment variable E(ALICLOUD_ASSUME_ROLE_SESSION_NAME).
- The Alibaba Cloud session_name. The session name to use when assuming the role. If omitted,
'ansible' is passed to the AssumeRole call as session name. It supports environment variable
E(ALICLOUD_ASSUME_ROLE_SESSION_NAME).
aliases: ['assume_role_session_name']
type: str
alicloud_assume_role_session_expiration:
description:
- The Alibaba Cloud C(session_expiration). The time after which the established session for assuming role expires. Valid
value range 900-3600 seconds. Default to 3600 (in this case Alicloud use own default value). It supports environment
variable E(ALICLOUD_ASSUME_ROLE_SESSION_EXPIRATION).
- The Alibaba Cloud C(session_expiration). The time after which the established session for assuming
role expires. Valid value range 900-3600 seconds. Default to 3600 (in this case Alicloud use own default
value). It supports environment variable E(ALICLOUD_ASSUME_ROLE_SESSION_EXPIRATION).
aliases: ['assume_role_session_expiration']
type: int
ecs_role_name:
description:
- The RAM Role Name attached on a ECS instance for API operations. You can retrieve this from the 'Access Control' section
of the Alibaba Cloud console.
- If you are running Ansible from an ECS instance with RAM Instance using RAM Role, Ansible will just access the metadata
U(http://100.100.100.200/latest/meta-data/ram/security-credentials/<ecs_role_name>) to obtain the STS credential.
This is a preferred approach over any other when running in ECS as you can avoid hard coding credentials. Instead
these are leased on-the-fly by Ansible which reduces the chance of leakage.
- The RAM Role Name attached on a ECS instance for API operations. You can retrieve this from the 'Access Control'
section of the Alibaba Cloud console.
- If you're running Ansible from an ECS instance with RAM Instance using RAM Role, Ansible will just access the
metadata U(http://100.100.100.200/latest/meta-data/ram/security-credentials/<ecs_role_name>) to obtain the STS
credential. This is a preferred approach over any other when running in ECS as you can avoid hard coding
credentials. Instead these are leased on-the-fly by Ansible which reduces the chance of leakage.
aliases: ['role_name']
type: str
profile:
description:
- This is the Alicloud profile name as set in the shared credentials file. It can also be sourced from the E(ALICLOUD_PROFILE)
environment variable.
- This is the Alicloud profile name as set in the shared credentials file. It can also be sourced from the
E(ALICLOUD_PROFILE) environment variable.
type: str
shared_credentials_file:
description:
@@ -86,14 +88,22 @@ options:
- If this is not set and a profile is specified, C(~/.aliyun/config.json) will be used.
type: str
author:
- "He Guimin (@xiaozhu36)"
- "He Guimin (@xiaozhu36)"
requirements:
- "Python >= 3.6"
- "Python >= 3.6"
notes:
- If parameters are not set within the module, the following environment variables can be used in decreasing order of precedence
E(ALICLOUD_ACCESS_KEY) or E(ALICLOUD_ACCESS_KEY_ID), E(ALICLOUD_SECRET_KEY) or E(ALICLOUD_SECRET_ACCESS_KEY), E(ALICLOUD_REGION)
or E(ALICLOUD_REGION_ID), E(ALICLOUD_SECURITY_TOKEN), E(ALICLOUD_ECS_ROLE_NAME), E(ALICLOUD_SHARED_CREDENTIALS_FILE),
E(ALICLOUD_PROFILE), E(ALICLOUD_ASSUME_ROLE_ARN), E(ALICLOUD_ASSUME_ROLE_SESSION_NAME), E(ALICLOUD_ASSUME_ROLE_SESSION_EXPIRATION).
- E(ALICLOUD_REGION) or E(ALICLOUD_REGION_ID) can be typically be used to specify the Alicloud region, when required, but
this can also be configured in the footmark config file.
"""
- If parameters are not set within the module, the following
environment variables can be used in decreasing order of precedence
E(ALICLOUD_ACCESS_KEY) or E(ALICLOUD_ACCESS_KEY_ID),
E(ALICLOUD_SECRET_KEY) or E(ALICLOUD_SECRET_ACCESS_KEY),
E(ALICLOUD_REGION) or E(ALICLOUD_REGION_ID),
E(ALICLOUD_SECURITY_TOKEN),
E(ALICLOUD_ECS_ROLE_NAME),
E(ALICLOUD_SHARED_CREDENTIALS_FILE),
E(ALICLOUD_PROFILE),
E(ALICLOUD_ASSUME_ROLE_ARN),
E(ALICLOUD_ASSUME_ROLE_SESSION_NAME),
E(ALICLOUD_ASSUME_ROLE_SESSION_EXPIRATION).
- E(ALICLOUD_REGION) or E(ALICLOUD_REGION_ID) can be typically be used to specify the
Alicloud region, when required, but this can also be configured in the footmark config file
'''

View File

@@ -11,22 +11,22 @@ __metaclass__ = type
class ModuleDocFragment(object):
# Standard documentation fragment
DOCUMENTATION = r"""
DOCUMENTATION = r'''
options: {}
attributes:
check_mode:
description: Can run in C(check_mode) and return changed status prediction without modifying target.
diff_mode:
description: Will return details on what has changed (or possibly needs changing in C(check_mode)), when in diff mode.
"""
check_mode:
description: Can run in C(check_mode) and return changed status prediction without modifying target.
diff_mode:
description: Will return details on what has changed (or possibly needs changing in C(check_mode)), when in diff mode.
'''
PLATFORM = r"""
PLATFORM = r'''
options: {}
attributes:
platform:
description: Target OS/families that can be operated against.
support: N/A
"""
platform:
description: Target OS/families that can be operated against.
support: N/A
'''
# Should be used together with the standard fragment
INFO_MODULE = r'''
@@ -42,23 +42,23 @@ attributes:
- This action does not modify state.
'''
CONN = r"""
CONN = r'''
options: {}
attributes:
become:
description: Is usable alongside C(become) keywords.
connection:
description: Uses the target's configured connection information to execute code on it.
delegation:
description: Can be used in conjunction with C(delegate_to) and related keywords.
"""
become:
description: Is usable alongside C(become) keywords.
connection:
description: Uses the target's configured connection information to execute code on it.
delegation:
description: Can be used in conjunction with C(delegate_to) and related keywords.
'''
FACTS = r"""
FACTS = r'''
options: {}
attributes:
facts:
description: Action returns an C(ansible_facts) dictionary that will update existing host facts.
"""
facts:
description: Action returns an C(ansible_facts) dictionary that will update existing host facts.
'''
# Should be used together with the standard fragment and the FACTS fragment
FACTS_MODULE = r'''
@@ -76,18 +76,18 @@ attributes:
support: full
'''
FILES = r"""
FILES = r'''
options: {}
attributes:
safe_file_operations:
description: Uses Ansible's strict file operation functions to ensure proper permissions and avoid data corruption.
"""
safe_file_operations:
description: Uses Ansible's strict file operation functions to ensure proper permissions and avoid data corruption.
'''
FLOW = r"""
FLOW = r'''
options: {}
attributes:
action:
description: Indicates this has a corresponding action plugin so some parts of the options can be executed on the controller.
async:
description: Supports being used with the C(async) keyword.
"""
action:
description: Indicates this has a corresponding action plugin so some parts of the options can be executed on the controller.
async:
description: Supports being used with the C(async) keyword.
'''

View File

@@ -10,7 +10,7 @@ __metaclass__ = type
class ModuleDocFragment(object):
# Standard files documentation fragment
DOCUMENTATION = r"""
DOCUMENTATION = r'''
options:
api_url:
description:
@@ -29,4 +29,4 @@ options:
- Whether or not to validate SSL certs when supplying a HTTPS endpoint.
type: bool
default: true
"""
'''

View File

@@ -11,7 +11,7 @@ __metaclass__ = type
class ModuleDocFragment(object):
# Standard documentation fragment
DOCUMENTATION = r"""
DOCUMENTATION = r'''
options:
client_id:
description:
@@ -30,7 +30,7 @@ options:
- O(ignore:username) is an alias of O(user) since community.general 6.0.0. It was an alias of O(workspace) before.
type: str
version_added: 4.0.0
aliases: [username]
aliases: [ username ]
password:
description:
- The App password.
@@ -41,4 +41,4 @@ notes:
- Bitbucket OAuth consumer key and secret can be obtained from Bitbucket profile -> Settings -> Access Management -> OAuth.
- Bitbucket App password can be created from Bitbucket profile -> Personal Settings -> App passwords.
- If both OAuth and Basic Auth credentials are passed, OAuth credentials take precedence.
"""
'''

View File

@@ -1,28 +0,0 @@
# -*- coding: utf-8 -*-
# Copyright (c) 2024, Alexei Znamensky <russoz@gmail.com>
# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
# SPDX-License-Identifier: GPL-3.0-or-later
from __future__ import (absolute_import, division, print_function)
__metaclass__ = type
class ModuleDocFragment(object):
# Standard documentation fragment
DOCUMENTATION = r"""
options: {}
requirements:
- requests >= 2.5.0
- clc-sdk
notes:
- To use this module, it is required to set the below environment variables which enables access to the Centurylink Cloud.
- E(CLC_V2_API_USERNAME), the account login ID for the Centurylink Cloud.
- E(CLC_V2_API_PASSWORD), the account password for the Centurylink Cloud.
- Alternatively, the module accepts the API token and account alias. The API token can be generated using the CLC account
login and password using the HTTP API call @ U(https://api.ctl.io/v2/authentication/login).
- E(CLC_V2_API_TOKEN), the API token generated from U(https://api.ctl.io/v2/authentication/login).
- E(CLC_ACCT_ALIAS), the account alias associated with the Centurylink Cloud.
- Users can set E(CLC_V2_API_URL) to specify an endpoint for pointing to a different CLC environment.
"""

View File

@@ -15,7 +15,7 @@ class ModuleDocFragment:
options:
host:
description:
- Host of the Consul agent.
- Host of the consul agent, defaults to V(localhost).
default: localhost
type: str
port:
@@ -25,18 +25,18 @@ options:
default: 8500
scheme:
description:
- The protocol scheme on which the Consul agent is running. Defaults to V(http) and can be set to V(https) for secure
connections.
- The protocol scheme on which the consul agent is running.
Defaults to V(http) and can be set to V(https) for secure connections.
default: http
type: str
validate_certs:
type: bool
description:
- Whether to verify the TLS certificate of the Consul agent.
- Whether to verify the TLS certificate of the consul agent.
default: true
ca_path:
description:
- The CA bundle to use for https connections.
- The CA bundle to use for https connections
type: str
"""

View File

@@ -14,7 +14,8 @@ __metaclass__ = type
class ModuleDocFragment(object):
# Dimension Data doc fragment
DOCUMENTATION = r"""
DOCUMENTATION = r'''
options:
region:
description:
@@ -47,4 +48,4 @@ options:
- This should only be used on private instances of the CloudControl API that use self-signed certificates.
type: bool
default: true
"""
'''

View File

@@ -14,7 +14,8 @@ __metaclass__ = type
class ModuleDocFragment(object):
# Dimension Data ("wait-for-completion" parameters) doc fragment
DOCUMENTATION = r"""
DOCUMENTATION = r'''
options:
wait:
description:
@@ -33,4 +34,4 @@ options:
- Only applicable if O(wait=true).
type: int
default: 2
"""
'''

View File

@@ -8,7 +8,7 @@ __metaclass__ = type
class ModuleDocFragment(object):
DOCUMENTATION = r"""
DOCUMENTATION = r'''
options:
venv:
description:
@@ -43,19 +43,20 @@ options:
notes:
- The C(django-admin) command is always executed using the C(C) locale, and the option C(--no-color) is always passed.
seealso:
- name: django-admin and manage.py in official Django documentation
description: >-
Refer to this documentation for the builtin commands and options of C(django-admin). Please make sure that you select
the right version of Django in the version selector on that page.
Refer to this documentation for the builtin commands and options of C(django-admin).
Please make sure that you select the right version of Django in the version selector on that page.
link: https://docs.djangoproject.com/en/5.0/ref/django-admin/
"""
'''
DATABASE = r"""
DATABASE = r'''
options:
database:
description:
- Specify the database to be used.
type: str
default: default
"""
'''

View File

@@ -10,6 +10,15 @@ __metaclass__ = type
class ModuleDocFragment(object):
DOCUMENTATION = r'''
options:
- See respective platform section for more details
requirements:
- See respective platform section for more details
notes:
- Ansible modules are available for EMC VNX.
'''
# Documentation fragment for VNX (emc_vnx)
EMC_VNX = r'''
options:

View File

@@ -10,7 +10,7 @@ __metaclass__ = type
class ModuleDocFragment(object):
# Standard files documentation fragment
DOCUMENTATION = r"""
DOCUMENTATION = r'''
requirements:
- requests (Python library U(https://pypi.org/project/requests/))
@@ -34,4 +34,4 @@ options:
- The CA certificates bundle to use to verify GitLab server certificate.
type: str
version_added: 8.1.0
"""
'''

View File

@@ -10,26 +10,26 @@ __metaclass__ = type
class ModuleDocFragment(object):
# HPE 3PAR doc fragment
DOCUMENTATION = r"""
DOCUMENTATION = '''
options:
storage_system_ip:
description:
- The storage system IP address.
type: str
required: true
storage_system_password:
description:
- The storage system password.
type: str
required: true
storage_system_username:
description:
- The storage system user name.
type: str
required: true
storage_system_ip:
description:
- The storage system IP address.
type: str
required: true
storage_system_password:
description:
- The storage system password.
type: str
required: true
storage_system_username:
description:
- The storage system user name.
type: str
required: true
requirements:
- hpe3par_sdk >= 1.0.2. Install using C(pip install hpe3par_sdk).
- WSAPI service should be enabled on the 3PAR storage array.
notes:
"""
'''

Some files were not shown because too many files have changed in this diff Show More