Compare commits

...

63 Commits
8.6.3 ... 8.6.7

Author SHA1 Message Date
Felix Fontein
8e1aaf927b Release 8.6.7. 2024-11-03 11:35:13 +01:00
patchback[bot]
f0bcb7f477 [PR #9085/9553dd9d backport][stable-8] Stop using ansible.module_utils.compat.importlib (#9088)
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:10 +01:00
Felix Fontein
d96705d55a Adjust changelog fragment. 2024-10-28 21:28:43 +01:00
Felix Fontein
d7e8f7a8cb Prepare 8.6.7. 2024-10-28 21:27:44 +01:00
patchback[bot]
becc6c7200 [PR #9052/d0b4e91c backport][stable-8] modprobe: fix --check mode not being honored for persistent option (#9070)
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:13 +01:00
patchback[bot]
5cddc4d617 [PR #9045/ccf7f623 backport][stable-8] Update documentation in apk.py (#9054)
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:01 +02:00
patchback[bot]
392e89ee86 [PR #9040/cc72fa07 backport][stable-8] groupby_as_dict: mention Jinja2's groupby filter (#9042)
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:51:01 +02:00
patchback[bot]
3e43029a32 [PR #9035/b1f46040 backport][stable-8] Skip timezone test on RHEL 7.9 VMs (#9038)
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:26:24 +02:00
Felix Fontein
3ee2ec4908 Fix reuse workflow branches.
(cherry picked from commit 5874711c6e)
2024-10-19 12:36:17 +02:00
Felix Fontein
719844cd4f Next release will be 8.6.7. 2024-10-07 23:37:09 +02:00
Felix Fontein
1dac3cd991 Release 8.6.6. 2024-10-07 23:12:59 +02:00
patchback[bot]
416a4ad6f8 [PR #8948/1bdf8fc0 backport][stable-8] cloudflare_dns: Update SRV record handling for Cloudflare API changes (#9000)
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:39 +02:00
patchback[bot]
0ce3841bda [PR #8956/b523d1b1 backport][stable-8] Remove 'CapacityBytes' from list of required parameters (#9006)
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:27 +02:00
patchback[bot]
5362908efb [PR #8987/29a2df8e backport][stable-8] udm_user, homectl: use legacycrypt on Python 3.13+ (#8992)
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:18 +02:00
patchback[bot]
d9d9148510 [PR #8970/8610223d backport][stable-8] dig lookup plugin: Fix using only last nameserver specified (#8985)
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:12 +02:00
patchback[bot]
214f0be60d [PR #8812/5d9a7ab2 backport][stable-8] keycloak_user_federation: remove lastSync param from kc API responses (#8976)
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:12:53 +03:00
patchback[bot]
715e6706cc [PR #8925/7c913b23 backport][stable-8] Pass absolute paths to atomic_move() (#8958)
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:53 +03:00
Felix Fontein
086b403336 Prepare 8.6.6 release. 2024-09-28 08:35:12 +03:00
Felix Fontein
717c2ca8dd [stable-8] Move ansible-core 2.15 tests to EOL tests (#8939)
Move ansible-core 2.15 tests to EOL tests (#8933)

Move ansible-core 2.15 tests to EOL tests.

(cherry picked from commit bc6ae849b3)
2024-09-26 16:42:24 +03:00
patchback[bot]
18a8c6f350 [PR #8887/0bc5f248 backport][stable-8] one_service: fix recreation (#8931)
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:30 +03:00
patchback[bot]
1caee897b1 [PR #8913/199ba0a1 backport][stable-8] Fix parameter name (#8915)
Fix parameter name (#8913)

(cherry picked from commit 199ba0a170)

Co-authored-by: Niko Ehrenfeuchter <mail@he1ix.org>
2024-09-24 23:08:52 +03:00
Felix Fontein
4a0da7fcbb [stable-8] Replace devel with stable-2.18 in CI (#8911)
Replace devel with stable-2.18 in CI.
2024-09-24 13:46:47 +03:00
patchback[bot]
4bd6b35d31 [PR #8877/deaad6e5 backport][stable-8] keycloak_realm: fix change detection in check mode by normalizing realms beforehand (#8902)
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:35 +03:00
patchback[bot]
cf66c8a249 [PR #8900/a32f1d69 backport][stable-8] ipa_hostgroup: fix state params (#8905)
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:23 +03:00
patchback[bot]
841ceffbcb [PR #8785/ac302eb7 backport][stable-8] keycloak_user_federation: set krbPrincipalAttribute to '' if unset in kc responses (#8891)
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:36 +03:00
patchback[bot]
d122d3f6fc [PR #8860/f93883aa backport][stable-8] gitlab_runner: update requirements in docs (#8879)
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:20 +02:00
patchback[bot]
c825648063 [PR #8870/2f1df973 backport][stable-8] Remove private key and certificates from documentation (#8873)
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:14 +02:00
patchback[bot]
5c60788abf [PR #8861/76ebda7f backport][stable-8] snap tests: re-enable test for --dangerous using smaller snap (#8867)
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:38 +02:00
Felix Fontein
bf318b3838 Next release will be 8.6.6. 2024-09-09 14:55:13 +02:00
Felix Fontein
03b12029aa Release 8.6.5. 2024-09-09 14:31:47 +02:00
patchback[bot]
6777d9471f [PR #8831/2ae41fa8 backport][stable-8] keycloak_user_federation: get the before mappers from before_comp to fix UnboundLocalError (#8849)
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:12 +00:00
patchback[bot]
61ea1aef35 [PR #8843/d73f977b backport][stable-8] Remove link to Google Groups mailing list (#8845)
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:07 +02:00
patchback[bot]
ae4358d189 [PR #8823/ea389e70 backport][stable-8] bugfix(keycloak): fix parameters for realm key creation (#8839)
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:55 +02:00
patchback[bot]
8fe7cdd864 [PR #8827/afd754e3 backport][stable-8] (doc) random_string lookup: fix examples (#8841)
(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:38 +02:00
patchback[bot]
586fdefa75 [PR #8761/982b8d89 backport][stable-8] keycloak_user_federation: sort desired and after mappers by name (#8836)
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:24 +02:00
Felix Fontein
765fc79d28 Prepare 8.6.5. 2024-09-07 09:51:33 +02:00
patchback[bot]
e14ebe38f4 [PR #8794/249126f4 backport][stable-8] proxmox inventory: fixing possible concatenation error (#8816)
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:52:53 +02:00
patchback[bot]
a3d9f72462 [PR #8815/593d302f backport][stable-8] Fix and enable test for datadog_downtime (#8820)
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:52:43 +02:00
patchback[bot]
4f5a50642d [PR #8792/3607e3d0 backport][stable-8] pipx: add doc example (#8800)
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:04 +02:00
patchback[bot]
a3c5cc6773 [PR #8796/e9071e98 backport][stable-8] Fix gitlab access token crash in check mode for new tokens (#8803)
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:51 +02:00
patchback[bot]
581ad7bbd8 [PR #8762/b79ac4f0 backport][stable-8] keycloak_user_federation: fix key error when removing mappers in update (#8780)
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:43 +02:00
patchback[bot]
6fd530dbff [PR #8770/14e86bde backport][stable-8] one_template: update name in copyright (#8773)
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:05 +02:00
Felix Fontein
076fe3cfb0 Improve communication link description.
(cherry picked from commit 9571ec7c72)
2024-08-15 21:42:34 +02:00
patchback[bot]
decadf7cbc [PR #8756/34519a5e backport][stable-8] Improve communication info (#8757)
Improve communication info (#8756)

Improve communication info.

(cherry picked from commit 34519a5ecb)

Co-authored-by: Felix Fontein <felix@fontein.de>
2024-08-12 17:22:58 +02:00
patchback[bot]
559b4494de [PR #8732/4cb4c608 backport][stable-8] README: Add Communication section with Forum information (#8754)
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:21 +02:00
Felix Fontein
ddbe3028e5 Next release will be 8.6.5. 2024-08-12 09:14:08 +02:00
Felix Fontein
98fede2ba0 Release 8.6.4. 2024-08-12 08:54:45 +02:00
patchback[bot]
b6b6e0db94 [PR #8735/57e28e5a backport][stable-8] keycloak_identity_provider: get cleartext clientsecret (#8743)
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:00 +02:00
patchback[bot]
f9ad7304ca [PR #8689/8989b6c4 backport][stable-8] Namespace the passwordstore lockfile (#8745)
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:41 +02:00
patchback[bot]
d0fe612858 [PR #8708/76d0222a backport][stable-8] homebrew_cask: fix upgrade_all changed when nothing upgraded (#8748)
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:29 +02:00
patchback[bot]
31b7c8aace [PR #8695/2942eda8 backport][stable-8] keycloak_user_federation: add mapper removal (#8752)
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:09 +02:00
patchback[bot]
d017b603ce [PR #8644/9f340861 backport][stable-8] django_manage: rely on package idempotency to install virtualenv (#8736)
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:04 +00:00
patchback[bot]
55f8456229 [PR #8718/b16263eb backport][stable-8] Clarify contribution guide on integration tests (#8733)
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:45 +02:00
patchback[bot]
c4b3c94092 [PR #8725/5322dd94 backport][stable-8] Remove invalid cloud/gandi entry (#8727)
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:34 +02:00
Felix Fontein
ca32d9f925 [stable-8] Fix pylint and pep8 issues exposed by latest ansible-core's ansible-test sanity checks (#8723)
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)
2024-08-07 16:03:43 +02:00
patchback[bot]
ee6d8cea9d [PR #8710/c517f1c4 backport][stable-8] ensure util-linux-extra is installed in Ubuntu 24.04 (#8716)
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:18 +02:00
patchback[bot]
6920a247c2 [PR #8657/7bbf32dc backport][stable-8] Update proxmox.py (#8698)
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:24 +02:00
patchback[bot]
bce61ee785 [PR #8648/b6c6253b backport][stable-8] fix(modules/gitlab_runners): pass paused to gitlab (#8700)
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:14 +02:00
patchback[bot]
8465e87bdc [PR #8692/fd811df4 backport][stable-8] Update timezone.py (#8702)
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:02 +02:00
Felix Fontein
f3ef0bc8e1 Prepare 8.6.4 release. 2024-07-27 13:58:11 +02:00
patchback[bot]
104d98ef02 [PR #8665/58f9860b backport][stable-8] Fix pipx tests (#8669)
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:23 +02:00
patchback[bot]
5251c8b075 [PR #8634/a78f7b1e backport][stable-8] #8572 - Updated docs to include pip >= 20.3b1 requirement (#8636)
#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:03 +02:00
Felix Fontein
a151726272 Next release will be 8.6.4. 2024-07-14 14:49:46 +02:00
78 changed files with 1704 additions and 574 deletions

View File

@@ -59,14 +59,14 @@ pool: Standard
stages:
### Sanity
- stage: Sanity_devel
displayName: Sanity devel
- stage: Sanity_2_18
displayName: Sanity 2.18
dependsOn: []
jobs:
- template: templates/matrix.yml
parameters:
nameFormat: Test {0}
testFormat: devel/sanity/{0}
testFormat: 2.18/sanity/{0}
targets:
- test: 1
- test: 2
@@ -99,28 +99,15 @@ stages:
- test: 2
- test: 3
- test: 4
- stage: Sanity_2_15
displayName: Sanity 2.15
dependsOn: []
jobs:
- template: templates/matrix.yml
parameters:
nameFormat: Test {0}
testFormat: 2.15/sanity/{0}
targets:
- test: 1
- test: 2
- test: 3
- test: 4
### Units
- stage: Units_devel
displayName: Units devel
- stage: Units_2_18
displayName: Units 2.18
dependsOn: []
jobs:
- template: templates/matrix.yml
parameters:
nameFormat: Python {0}
testFormat: devel/units/{0}/1
testFormat: 2.18/units/{0}/1
targets:
- test: 3.8
- test: 3.9
@@ -151,26 +138,15 @@ stages:
- test: 2.7
- test: 3.6
- test: "3.11"
- stage: Units_2_15
displayName: Units 2.15
dependsOn: []
jobs:
- template: templates/matrix.yml
parameters:
nameFormat: Python {0}
testFormat: 2.15/units/{0}/1
targets:
- test: 3.5
- test: "3.10"
## Remote
- stage: Remote_devel_extra_vms
displayName: Remote devel extra VMs
- stage: Remote_2_18_extra_vms
displayName: Remote 2.18 extra VMs
dependsOn: []
jobs:
- template: templates/matrix.yml
parameters:
testFormat: devel/{0}
testFormat: 2.18/{0}
targets:
- name: Alpine 3.20
test: alpine/3.20
@@ -182,13 +158,13 @@ stages:
test: ubuntu/24.04
groups:
- vm
- stage: Remote_devel
displayName: Remote devel
- stage: Remote_2_18
displayName: Remote 2.18
dependsOn: []
jobs:
- template: templates/matrix.yml
parameters:
testFormat: devel/{0}
testFormat: 2.18/{0}
targets:
- name: macOS 14.3
test: macos/14.3
@@ -232,43 +208,23 @@ stages:
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
- stage: Remote_2_15
displayName: Remote 2.15
dependsOn: []
jobs:
- template: templates/matrix.yml
parameters:
testFormat: 2.15/{0}
targets:
- name: RHEL 9.1
test: rhel/9.1
- name: RHEL 8.7
test: rhel/8.7
- name: RHEL 7.9
test: rhel/7.9
# - name: FreeBSD 13.1
# test: freebsd/13.1
# - name: FreeBSD 12.4
# test: freebsd/12.4
groups:
- 1
- 2
- 3
### Docker
- stage: Docker_devel
displayName: Docker devel
- stage: Docker_2_18
displayName: Docker 2.18
dependsOn: []
jobs:
- template: templates/matrix.yml
parameters:
testFormat: devel/linux/{0}
testFormat: 2.18/linux/{0}
targets:
- name: Fedora 40
test: fedora40
@@ -314,20 +270,6 @@ stages:
test: opensuse15
- name: Alpine 3
test: alpine3
groups:
- 1
- 2
- 3
- stage: Docker_2_15
displayName: Docker 2.15
dependsOn: []
jobs:
- template: templates/matrix.yml
parameters:
testFormat: 2.15/linux/{0}
targets:
- name: Fedora 37
test: fedora37
- name: CentOS 7
test: centos7
groups:
@@ -336,13 +278,13 @@ stages:
- 3
### Community Docker
- stage: Docker_community_devel
displayName: Docker (community images) devel
- stage: Docker_community_2_18
displayName: Docker (community images) 2.18
dependsOn: []
jobs:
- template: templates/matrix.yml
parameters:
testFormat: devel/linux-community/{0}
testFormat: 2.18/linux-community/{0}
targets:
- name: Debian Bullseye
test: debian-bullseye/3.9
@@ -356,77 +298,63 @@ stages:
- 3
### Generic
- 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_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: Generic_2_15
displayName: Generic 2.15
dependsOn: []
jobs:
- template: templates/matrix.yml
parameters:
nameFormat: Python {0}
testFormat: 2.15/generic/{0}/1
targets:
- test: '3.9'
# Right now all generic tests are disabled. Uncomment when at least one of them is re-enabled.
# - 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.11'
# - 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
- Sanity_2_15
- Units_devel
- Units_2_18
- Units_2_17
- Units_2_16
- Units_2_15
- Remote_devel_extra_vms
- Remote_devel
- Remote_2_18_extra_vms
- Remote_2_18
- Remote_2_17
- Remote_2_16
- Remote_2_15
- Docker_devel
- Docker_2_18
- Docker_2_17
- Docker_2_16
- Docker_2_15
- Docker_community_devel
- Docker_community_2_18
# 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
# - Generic_2_15
jobs:
- template: templates/coverage.yml

View File

@@ -31,6 +31,7 @@ jobs:
ansible:
- '2.13'
- '2.14'
- '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
@@ -76,6 +77,10 @@ jobs:
python: '3.8'
- ansible: '2.14'
python: '3.9'
- ansible: '2.15'
python: '3.5'
- ansible: '2.15'
python: '3.10'
steps:
- name: >-
@@ -166,16 +171,32 @@ jobs:
docker: alpine3
python: ''
target: azp/posix/3/
# 2.15
- 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/
# Right now all generic tests are disabled. Uncomment when at least one of them is re-enabled.
# - 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: >-

View File

@@ -7,10 +7,14 @@ name: Verify REUSE
on:
push:
branches: [main]
pull_request_target:
branches:
- main
- stable-*
pull_request:
types: [opened, synchronize, reopened]
branches: [main]
branches:
- main
- stable-*
# Run CI once per day (at 07:30 UTC)
schedule:
- cron: '30 7 * * *'

View File

@@ -2,94 +2,197 @@
**Topics**
- <a href="#v8-6-3">v8\.6\.3</a>
- <a href="#v8-6-7">v8\.6\.7</a>
- <a href="#release-summary">Release Summary</a>
- <a href="#minor-changes">Minor Changes</a>
- <a href="#bugfixes">Bugfixes</a>
- <a href="#v8-6-2">v8\.6\.2</a>
- <a href="#v8-6-6">v8\.6\.6</a>
- <a href="#release-summary-1">Release Summary</a>
- <a href="#minor-changes">Minor Changes</a>
- <a href="#bugfixes-1">Bugfixes</a>
- <a href="#known-issues">Known Issues</a>
- <a href="#v8-6-1">v8\.6\.1</a>
- <a href="#v8-6-5">v8\.6\.5</a>
- <a href="#release-summary-2">Release Summary</a>
- <a href="#security-fixes">Security Fixes</a>
- <a href="#bugfixes-2">Bugfixes</a>
- <a href="#v8-6-0">v8\.6\.0</a>
- <a href="#v8-6-4">v8\.6\.4</a>
- <a href="#release-summary-3">Release Summary</a>
- <a href="#minor-changes-1">Minor Changes</a>
- <a href="#deprecated-features">Deprecated Features</a>
- <a href="#bugfixes-3">Bugfixes</a>
- <a href="#new-modules">New Modules</a>
- <a href="#v8-5-0">v8\.5\.0</a>
- <a href="#v8-6-3">v8\.6\.3</a>
- <a href="#release-summary-4">Release Summary</a>
- <a href="#minor-changes-2">Minor Changes</a>
- <a href="#security-fixes-1">Security Fixes</a>
- <a href="#bugfixes-4">Bugfixes</a>
- <a href="#v8-6-2">v8\.6\.2</a>
- <a href="#release-summary-5">Release Summary</a>
- <a href="#bugfixes-5">Bugfixes</a>
- <a href="#known-issues">Known Issues</a>
- <a href="#v8-6-1">v8\.6\.1</a>
- <a href="#release-summary-6">Release Summary</a>
- <a href="#security-fixes">Security Fixes</a>
- <a href="#bugfixes-6">Bugfixes</a>
- <a href="#v8-6-0">v8\.6\.0</a>
- <a href="#release-summary-7">Release Summary</a>
- <a href="#minor-changes-3">Minor Changes</a>
- <a href="#deprecated-features">Deprecated Features</a>
- <a href="#bugfixes-7">Bugfixes</a>
- <a href="#new-modules">New Modules</a>
- <a href="#v8-5-0">v8\.5\.0</a>
- <a href="#release-summary-8">Release Summary</a>
- <a href="#minor-changes-4">Minor Changes</a>
- <a href="#security-fixes-1">Security Fixes</a>
- <a href="#bugfixes-8">Bugfixes</a>
- <a href="#new-modules-1">New Modules</a>
- <a href="#v8-4-0">v8\.4\.0</a>
- <a href="#release-summary-5">Release Summary</a>
- <a href="#minor-changes-3">Minor Changes</a>
- <a href="#bugfixes-5">Bugfixes</a>
- <a href="#release-summary-9">Release Summary</a>
- <a href="#minor-changes-5">Minor Changes</a>
- <a href="#bugfixes-9">Bugfixes</a>
- <a href="#new-plugins">New Plugins</a>
- <a href="#callback">Callback</a>
- <a href="#filter">Filter</a>
- <a href="#new-modules-2">New Modules</a>
- <a href="#v8-3-0">v8\.3\.0</a>
- <a href="#release-summary-6">Release Summary</a>
- <a href="#minor-changes-4">Minor Changes</a>
- <a href="#release-summary-10">Release Summary</a>
- <a href="#minor-changes-6">Minor Changes</a>
- <a href="#deprecated-features-1">Deprecated Features</a>
- <a href="#bugfixes-6">Bugfixes</a>
- <a href="#bugfixes-10">Bugfixes</a>
- <a href="#new-modules-3">New Modules</a>
- <a href="#v8-2-0">v8\.2\.0</a>
- <a href="#release-summary-7">Release Summary</a>
- <a href="#minor-changes-5">Minor Changes</a>
- <a href="#bugfixes-7">Bugfixes</a>
- <a href="#release-summary-11">Release Summary</a>
- <a href="#minor-changes-7">Minor Changes</a>
- <a href="#bugfixes-11">Bugfixes</a>
- <a href="#new-plugins-1">New Plugins</a>
- <a href="#connection">Connection</a>
- <a href="#filter-1">Filter</a>
- <a href="#lookup">Lookup</a>
- <a href="#new-modules-4">New Modules</a>
- <a href="#v8-1-0">v8\.1\.0</a>
- <a href="#release-summary-8">Release Summary</a>
- <a href="#minor-changes-6">Minor Changes</a>
- <a href="#bugfixes-8">Bugfixes</a>
- <a href="#release-summary-12">Release Summary</a>
- <a href="#minor-changes-8">Minor Changes</a>
- <a href="#bugfixes-12">Bugfixes</a>
- <a href="#new-plugins-2">New Plugins</a>
- <a href="#lookup-1">Lookup</a>
- <a href="#test">Test</a>
- <a href="#new-modules-5">New Modules</a>
- <a href="#v8-0-2">v8\.0\.2</a>
- <a href="#release-summary-9">Release Summary</a>
- <a href="#bugfixes-9">Bugfixes</a>
- <a href="#release-summary-13">Release Summary</a>
- <a href="#bugfixes-13">Bugfixes</a>
- <a href="#v8-0-1">v8\.0\.1</a>
- <a href="#release-summary-10">Release Summary</a>
- <a href="#bugfixes-10">Bugfixes</a>
- <a href="#release-summary-14">Release Summary</a>
- <a href="#bugfixes-14">Bugfixes</a>
- <a href="#v8-0-0">v8\.0\.0</a>
- <a href="#release-summary-11">Release Summary</a>
- <a href="#minor-changes-7">Minor Changes</a>
- <a href="#release-summary-15">Release Summary</a>
- <a href="#minor-changes-9">Minor Changes</a>
- <a href="#breaking-changes--porting-guide">Breaking Changes / Porting Guide</a>
- <a href="#deprecated-features-2">Deprecated Features</a>
- <a href="#removed-features-previously-deprecated">Removed Features \(previously deprecated\)</a>
- <a href="#bugfixes-11">Bugfixes</a>
- <a href="#bugfixes-15">Bugfixes</a>
- <a href="#known-issues-1">Known Issues</a>
- <a href="#new-plugins-3">New Plugins</a>
- <a href="#lookup-2">Lookup</a>
- <a href="#new-modules-6">New Modules</a>
This changelog describes changes after version 7\.0\.0\.
<a id="v8-6-3"></a>
## v8\.6\.3
<a id="v8-6-7"></a>
## v8\.6\.7
<a id="release-summary"></a>
### Release Summary
Bugfix release\.
<a id="bugfixes"></a>
### Bugfixes
* collection\_version lookup plugin \- use <code>importlib</code> directly instead of the deprecated and in ansible\-core 2\.19 removed <code>ansible\.module\_utils\.compat\.importlib</code> \([https\://github\.com/ansible\-collections/community\.general/pull/9084](https\://github\.com/ansible\-collections/community\.general/pull/9084)\)\.
* modprobe \- fix check mode not being honored for <code>persistent</code> option \([https\://github\.com/ansible\-collections/community\.general/issues/9051](https\://github\.com/ansible\-collections/community\.general/issues/9051)\, [https\://github\.com/ansible\-collections/community\.general/pull/9052](https\://github\.com/ansible\-collections/community\.general/pull/9052)\)\.
<a id="v8-6-6"></a>
## v8\.6\.6
<a id="release-summary-1"></a>
### Release Summary
Regular bugfix release\.
Note that this is the last regular bugfix release of community\.general 8\.x\.y\.
From now on\, there will only be maintenance releases with major bugfixes and
security fixes\.
<a id="minor-changes"></a>
### Minor Changes
* redfish\_confg \- remove <code>CapacityBytes</code> from required paramaters of the <code>CreateVolume</code> command \([https\://github\.com/ansible\-collections/community\.general/pull/8956](https\://github\.com/ansible\-collections/community\.general/pull/8956)\)\.
<a id="bugfixes-1"></a>
### Bugfixes
* cloudflare\_dns \- fix changing Cloudflare SRV records \([https\://github\.com/ansible\-collections/community\.general/issues/8679](https\://github\.com/ansible\-collections/community\.general/issues/8679)\, [https\://github\.com/ansible\-collections/community\.general/pull/8948](https\://github\.com/ansible\-collections/community\.general/pull/8948)\)\.
* dig lookup plugin \- fix using only the last nameserver specified \([https\://github\.com/ansible\-collections/community\.general/pull/8970](https\://github\.com/ansible\-collections/community\.general/pull/8970)\)\.
* homectl \- the module now tries to use <code>legacycrypt</code> on Python 3\.13\+ \([https\://github\.com/ansible\-collections/community\.general/issues/4691](https\://github\.com/ansible\-collections/community\.general/issues/4691)\, [https\://github\.com/ansible\-collections/community\.general/pull/8987](https\://github\.com/ansible\-collections/community\.general/pull/8987)\)\.
* ini\_file \- pass absolute paths to <code>module\.atomic\_move\(\)</code> \([https\://github\.com/ansible/ansible/issues/83950](https\://github\.com/ansible/ansible/issues/83950)\, [https\://github\.com/ansible\-collections/community\.general/pull/8925](https\://github\.com/ansible\-collections/community\.general/pull/8925)\)\.
* ipa\_hostgroup \- fix <code>enabled \`\` and \`\`disabled</code> states \([https\://github\.com/ansible\-collections/community\.general/issues/8408](https\://github\.com/ansible\-collections/community\.general/issues/8408)\, [https\://github\.com/ansible\-collections/community\.general/pull/8900](https\://github\.com/ansible\-collections/community\.general/pull/8900)\)\.
* java\_keystore \- pass absolute paths to <code>module\.atomic\_move\(\)</code> \([https\://github\.com/ansible/ansible/issues/83950](https\://github\.com/ansible/ansible/issues/83950)\, [https\://github\.com/ansible\-collections/community\.general/pull/8925](https\://github\.com/ansible\-collections/community\.general/pull/8925)\)\.
* jenkins\_plugin \- pass absolute paths to <code>module\.atomic\_move\(\)</code> \([https\://github\.com/ansible/ansible/issues/83950](https\://github\.com/ansible/ansible/issues/83950)\, [https\://github\.com/ansible\-collections/community\.general/pull/8925](https\://github\.com/ansible\-collections/community\.general/pull/8925)\)\.
* kdeconfig \- pass absolute paths to <code>module\.atomic\_move\(\)</code> \([https\://github\.com/ansible/ansible/issues/83950](https\://github\.com/ansible/ansible/issues/83950)\, [https\://github\.com/ansible\-collections/community\.general/pull/8925](https\://github\.com/ansible\-collections/community\.general/pull/8925)\)\.
* keycloak\_realm \- fix change detection in check mode by sorting the lists in the realms beforehand \([https\://github\.com/ansible\-collections/community\.general/pull/8877](https\://github\.com/ansible\-collections/community\.general/pull/8877)\)\.
* keycloak\_user\_federation \- minimize change detection by setting <code>krbPrincipalAttribute</code> to <code>\'\'</code> in Keycloak responses if missing \([https\://github\.com/ansible\-collections/community\.general/pull/8785](https\://github\.com/ansible\-collections/community\.general/pull/8785)\)\.
* keycloak\_user\_federation \- remove <code>lastSync</code> parameter from Keycloak responses to minimize diff/changes \([https\://github\.com/ansible\-collections/community\.general/pull/8812](https\://github\.com/ansible\-collections/community\.general/pull/8812)\)\.
* one\_service \- fix service creation after it was deleted with <code>unique</code> parameter \([https\://github\.com/ansible\-collections/community\.general/issues/3137](https\://github\.com/ansible\-collections/community\.general/issues/3137)\, [https\://github\.com/ansible\-collections/community\.general/pull/8887](https\://github\.com/ansible\-collections/community\.general/pull/8887)\)\.
* pam\_limits \- pass absolute paths to <code>module\.atomic\_move\(\)</code> \([https\://github\.com/ansible/ansible/issues/83950](https\://github\.com/ansible/ansible/issues/83950)\, [https\://github\.com/ansible\-collections/community\.general/pull/8925](https\://github\.com/ansible\-collections/community\.general/pull/8925)\)\.
* udm\_user \- the module now tries to use <code>legacycrypt</code> on Python 3\.13\+ \([https\://github\.com/ansible\-collections/community\.general/issues/4690](https\://github\.com/ansible\-collections/community\.general/issues/4690)\, [https\://github\.com/ansible\-collections/community\.general/pull/8987](https\://github\.com/ansible\-collections/community\.general/pull/8987)\)\.
<a id="v8-6-5"></a>
## v8\.6\.5
<a id="release-summary-2"></a>
### Release Summary
Regular bugfix release\.
<a id="bugfixes-2"></a>
### Bugfixes
* gitlab\_group\_access\_token \- fix crash in check mode caused by attempted access to a newly created access token \([https\://github\.com/ansible\-collections/community\.general/pull/8796](https\://github\.com/ansible\-collections/community\.general/pull/8796)\)\.
* gitlab\_project\_access\_token \- fix crash in check mode caused by attempted access to a newly created access token \([https\://github\.com/ansible\-collections/community\.general/pull/8796](https\://github\.com/ansible\-collections/community\.general/pull/8796)\)\.
* keycloak\_realm\_key \- fix invalid usage of <code>parent\_id</code> \([https\://github\.com/ansible\-collections/community\.general/issues/7850](https\://github\.com/ansible\-collections/community\.general/issues/7850)\, [https\://github\.com/ansible\-collections/community\.general/pull/8823](https\://github\.com/ansible\-collections/community\.general/pull/8823)\)\.
* keycloak\_user\_federation \- fix key error when removing mappers during an update and new mappers are specified in the module args \([https\://github\.com/ansible\-collections/community\.general/pull/8762](https\://github\.com/ansible\-collections/community\.general/pull/8762)\)\.
* keycloak\_user\_federation \- fix the <code>UnboundLocalError</code> that occurs when an ID is provided for a user federation mapper \([https\://github\.com/ansible\-collections/community\.general/pull/8831](https\://github\.com/ansible\-collections/community\.general/pull/8831)\)\.
* keycloak\_user\_federation \- sort desired and after mapper list by name \(analog to before mapper list\) to minimize diff and make change detection more accurate \([https\://github\.com/ansible\-collections/community\.general/pull/8761](https\://github\.com/ansible\-collections/community\.general/pull/8761)\)\.
* proxmox inventory plugin \- fixed a possible error on concatenating responses from proxmox\. In case an API call unexpectedly returned an empty result\, the inventory failed with a fatal error\. Added check for empty response \([https\://github\.com/ansible\-collections/community\.general/issues/8798](https\://github\.com/ansible\-collections/community\.general/issues/8798)\, [https\://github\.com/ansible\-collections/community\.general/pull/8794](https\://github\.com/ansible\-collections/community\.general/pull/8794)\)\.
<a id="v8-6-4"></a>
## v8\.6\.4
<a id="release-summary-3"></a>
### Release Summary
Regular bugfix release\.
<a id="minor-changes-1"></a>
### Minor Changes
* passwordstore lookup plugin \- add the current user to the lockfile file name to address issues on multi\-user systems \([https\://github\.com/ansible\-collections/community\.general/pull/8689](https\://github\.com/ansible\-collections/community\.general/pull/8689)\)\.
<a id="bugfixes-3"></a>
### Bugfixes
* gitlab\_runner \- fix <code>paused</code> parameter being ignored \([https\://github\.com/ansible\-collections/community\.general/pull/8648](https\://github\.com/ansible\-collections/community\.general/pull/8648)\)\.
* homebrew\_cask \- fix <code>upgrade\_all</code> returns <code>changed</code> when nothing upgraded \([https\://github\.com/ansible\-collections/community\.general/issues/8707](https\://github\.com/ansible\-collections/community\.general/issues/8707)\, [https\://github\.com/ansible\-collections/community\.general/pull/8708](https\://github\.com/ansible\-collections/community\.general/pull/8708)\)\.
* keycloak\_user\_federation \- get cleartext IDP <code>clientSecret</code> from full realm info to detect changes to it \([https\://github\.com/ansible\-collections/community\.general/issues/8294](https\://github\.com/ansible\-collections/community\.general/issues/8294)\, [https\://github\.com/ansible\-collections/community\.general/pull/8735](https\://github\.com/ansible\-collections/community\.general/pull/8735)\)\.
* keycloak\_user\_federation \- remove existing user federation mappers if they are not present in the federation configuration and will not be updated \([https\://github\.com/ansible\-collections/community\.general/issues/7169](https\://github\.com/ansible\-collections/community\.general/issues/7169)\, [https\://github\.com/ansible\-collections/community\.general/pull/8695](https\://github\.com/ansible\-collections/community\.general/pull/8695)\)\.
<a id="v8-6-3"></a>
## v8\.6\.3
<a id="release-summary-4"></a>
### Release Summary
Regular bugfix release\.
<a id="minor-changes-2"></a>
### Minor Changes
* wdc\_redfish\_command \- minor change to handle upgrade file for Redfish WD platforms \([https\://github\.com/ansible\-collections/community\.general/pull/8444](https\://github\.com/ansible\-collections/community\.general/pull/8444)\)\.
<a id="bugfixes"></a>
<a id="bugfixes-4"></a>
### Bugfixes
* bitwarden lookup plugin \- fix <code>KeyError</code> in <code>search\_field</code> \([https\://github\.com/ansible\-collections/community\.general/issues/8549](https\://github\.com/ansible\-collections/community\.general/issues/8549)\, [https\://github\.com/ansible\-collections/community\.general/pull/8557](https\://github\.com/ansible\-collections/community\.general/pull/8557)\)\.
@@ -100,12 +203,12 @@ Regular bugfix release\.
<a id="v8-6-2"></a>
## v8\.6\.2
<a id="release-summary-1"></a>
<a id="release-summary-5"></a>
### Release Summary
Regular bugfix release\.
<a id="bugfixes-1"></a>
<a id="bugfixes-5"></a>
### Bugfixes
* git\_config \- fix behavior of <code>state\=absent</code> if <code>value</code> is present \([https\://github\.com/ansible\-collections/community\.general/issues/8436](https\://github\.com/ansible\-collections/community\.general/issues/8436)\, [https\://github\.com/ansible\-collections/community\.general/pull/8452](https\://github\.com/ansible\-collections/community\.general/pull/8452)\)\.
@@ -127,7 +230,7 @@ Regular bugfix release\.
<a id="v8-6-1"></a>
## v8\.6\.1
<a id="release-summary-2"></a>
<a id="release-summary-6"></a>
### Release Summary
Regular bugfix release\.
@@ -137,7 +240,7 @@ Regular bugfix release\.
* keycloak\_identity\_provider \- the client secret was not correctly sanitized by the module\. The return values <code>proposed</code>\, <code>existing</code>\, and <code>end\_state</code>\, as well as the diff\, did contain the client secret unmasked \([https\://github\.com/ansible\-collections/community\.general/pull/8355](https\://github\.com/ansible\-collections/community\.general/pull/8355)\)\.
<a id="bugfixes-2"></a>
<a id="bugfixes-6"></a>
### Bugfixes
* keycloak\_user\_federation \- fix diff of empty <code>krbPrincipalAttribute</code> \([https\://github\.com/ansible\-collections/community\.general/pull/8320](https\://github\.com/ansible\-collections/community\.general/pull/8320)\)\.
@@ -148,12 +251,12 @@ Regular bugfix release\.
<a id="v8-6-0"></a>
## v8\.6\.0
<a id="release-summary-3"></a>
<a id="release-summary-7"></a>
### Release Summary
Regular bugfix and features release\.
<a id="minor-changes-1"></a>
<a id="minor-changes-3"></a>
### Minor Changes
* Use offset\-aware <code>datetime\.datetime</code> objects \(with timezone UTC\) instead of offset\-naive UTC timestamps\, which are deprecated in Python 3\.12 \([https\://github\.com/ansible\-collections/community\.general/pull/8222](https\://github\.com/ansible\-collections/community\.general/pull/8222)\)\.
@@ -176,7 +279,7 @@ Regular bugfix and features release\.
* hipchat callback plugin \- the hipchat service has been discontinued and the self\-hosted variant has been End of Life since 2020\. The callback plugin is therefore deprecated and will be removed from community\.general 10\.0\.0 if nobody provides compelling reasons to still keep it \([https\://github\.com/ansible\-collections/community\.general/issues/8184](https\://github\.com/ansible\-collections/community\.general/issues/8184)\, [https\://github\.com/ansible\-collections/community\.general/pull/8189](https\://github\.com/ansible\-collections/community\.general/pull/8189)\)\.
<a id="bugfixes-3"></a>
<a id="bugfixes-7"></a>
### Bugfixes
* aix\_filesystem \- fix <code>\_validate\_vg</code> not passing VG name to <code>lsvg\_cmd</code> \([https\://github\.com/ansible\-collections/community\.general/issues/8151](https\://github\.com/ansible\-collections/community\.general/issues/8151)\)\.
@@ -202,12 +305,12 @@ Regular bugfix and features release\.
<a id="v8-5-0"></a>
## v8\.5\.0
<a id="release-summary-4"></a>
<a id="release-summary-8"></a>
### Release Summary
Regular feature and bugfix release with security fixes\.
<a id="minor-changes-2"></a>
<a id="minor-changes-4"></a>
### Minor Changes
* bitwarden lookup plugin \- allows to fetch all records of a given collection ID\, by allowing to pass an empty value for <code>search\_value</code> when <code>collection\_id</code> is provided \([https\://github\.com/ansible\-collections/community\.general/pull/8013](https\://github\.com/ansible\-collections/community\.general/pull/8013)\)\.
@@ -225,7 +328,7 @@ Regular feature and bugfix release with security fixes\.
* cobbler\, gitlab\_runners\, icinga2\, linode\, lxd\, nmap\, online\, opennebula\, proxmox\, scaleway\, stackpath\_compute\, virtualbox\, and xen\_orchestra inventory plugin \- make sure all data received from the remote servers is marked as unsafe\, so remote code execution by obtaining texts that can be evaluated as templates is not possible \([https\://www\.die\-welt\.net/2024/03/remote\-code\-execution\-in\-ansible\-dynamic\-inventory\-plugins/](https\://www\.die\-welt\.net/2024/03/remote\-code\-execution\-in\-ansible\-dynamic\-inventory\-plugins/)\, [https\://github\.com/ansible\-collections/community\.general/pull/8098](https\://github\.com/ansible\-collections/community\.general/pull/8098)\)\.
<a id="bugfixes-4"></a>
<a id="bugfixes-8"></a>
### Bugfixes
* aix\_filesystem \- fix issue with empty list items in crfs logic and option order \([https\://github\.com/ansible\-collections/community\.general/pull/8052](https\://github\.com/ansible\-collections/community\.general/pull/8052)\)\.
@@ -247,12 +350,12 @@ Regular feature and bugfix release with security fixes\.
<a id="v8-4-0"></a>
## v8\.4\.0
<a id="release-summary-5"></a>
<a id="release-summary-9"></a>
### Release Summary
Regular bugfix and feature release\.
<a id="minor-changes-3"></a>
<a id="minor-changes-5"></a>
### Minor Changes
* bitwarden lookup plugin \- add <code>bw\_session</code> option\, to pass session key instead of reading from env \([https\://github\.com/ansible\-collections/community\.general/pull/7994](https\://github\.com/ansible\-collections/community\.general/pull/7994)\)\.
@@ -265,7 +368,7 @@ Regular bugfix and feature release\.
* sudoers \- add support for the <code>NOEXEC</code> tag in sudoers rules \([https\://github\.com/ansible\-collections/community\.general/pull/7983](https\://github\.com/ansible\-collections/community\.general/pull/7983)\)\.
* terraform \- fix <code>diff\_mode</code> in state <code>absent</code> and when terraform <code>resource\_changes</code> does not exist \([https\://github\.com/ansible\-collections/community\.general/pull/7963](https\://github\.com/ansible\-collections/community\.general/pull/7963)\)\.
<a id="bugfixes-5"></a>
<a id="bugfixes-9"></a>
### Bugfixes
* cargo \- fix idempotency issues when using a custom installation path for packages \(using the <code>\-\-path</code> parameter\)\. The initial installation runs fine\, but subsequent runs use the <code>get\_installed\(\)</code> function which did not check the given installation location\, before running <code>cargo install</code>\. This resulted in a false <code>changed</code> state\. Also the removal of packeges using <code>state\: absent</code> failed\, as the installation check did not use the given parameter \([https\://github\.com/ansible\-collections/community\.general/pull/7970](https\://github\.com/ansible\-collections/community\.general/pull/7970)\)\.
@@ -303,12 +406,12 @@ Regular bugfix and feature release\.
<a id="v8-3-0"></a>
## v8\.3\.0
<a id="release-summary-6"></a>
<a id="release-summary-10"></a>
### Release Summary
Regular bugfix and feature release\.
<a id="minor-changes-4"></a>
<a id="minor-changes-6"></a>
### Minor Changes
* consul\_auth\_method\, consul\_binding\_rule\, consul\_policy\, consul\_role\, consul\_session\, consul\_token \- added action group <code>community\.general\.consul</code> \([https\://github\.com/ansible\-collections/community\.general/pull/7897](https\://github\.com/ansible\-collections/community\.general/pull/7897)\)\.
@@ -326,7 +429,7 @@ Regular bugfix and feature release\.
* consul\_acl \- the module has been deprecated and will be removed in community\.general 10\.0\.0\. <code>consul\_token</code> and <code>consul\_policy</code> can be used instead \([https\://github\.com/ansible\-collections/community\.general/pull/7901](https\://github\.com/ansible\-collections/community\.general/pull/7901)\)\.
<a id="bugfixes-6"></a>
<a id="bugfixes-10"></a>
### Bugfixes
* homebrew \- detect already installed formulae and casks using JSON output from <code>brew info</code> \([https\://github\.com/ansible\-collections/community\.general/issues/864](https\://github\.com/ansible\-collections/community\.general/issues/864)\)\.
@@ -350,12 +453,12 @@ Regular bugfix and feature release\.
<a id="v8-2-0"></a>
## v8\.2\.0
<a id="release-summary-7"></a>
<a id="release-summary-11"></a>
### Release Summary
Regular bugfix and feature release\.
<a id="minor-changes-5"></a>
<a id="minor-changes-7"></a>
### Minor Changes
* ipa\_dnsrecord \- adds ability to manage NS record types \([https\://github\.com/ansible\-collections/community\.general/pull/7737](https\://github\.com/ansible\-collections/community\.general/pull/7737)\)\.
@@ -371,7 +474,7 @@ Regular bugfix and feature release\.
* ssh\_config \- new feature to set <code>IdentitiesOnly</code> option to <code>yes</code> or <code>no</code> \([https\://github\.com/ansible\-collections/community\.general/pull/7704](https\://github\.com/ansible\-collections/community\.general/pull/7704)\)\.
* xcc\_redfish\_command \- added support for raw POSTs \(<code>command\=PostResource</code> in <code>category\=Raw</code>\) without a specific action info \([https\://github\.com/ansible\-collections/community\.general/pull/7746](https\://github\.com/ansible\-collections/community\.general/pull/7746)\)\.
<a id="bugfixes-7"></a>
<a id="bugfixes-11"></a>
### Bugfixes
* keycloak\_identity\_provider \- <code>mappers</code> processing was not idempotent if the mappers configuration list had not been sorted by name \(in ascending order\)\. Fix resolves the issue by sorting mappers in the desired state using the same key which is used for obtaining existing state \([https\://github\.com/ansible\-collections/community\.general/pull/7418](https\://github\.com/ansible\-collections/community\.general/pull/7418)\)\.
@@ -411,12 +514,12 @@ Regular bugfix and feature release\.
<a id="v8-1-0"></a>
## v8\.1\.0
<a id="release-summary-8"></a>
<a id="release-summary-12"></a>
### Release Summary
Regular bugfix and feature release\.
<a id="minor-changes-6"></a>
<a id="minor-changes-8"></a>
### Minor Changes
* bitwarden lookup plugin \- when looking for items using an item ID\, the item is now accessed directly with <code>bw get item</code> instead of searching through all items\. This doubles the lookup speed \([https\://github\.com/ansible\-collections/community\.general/pull/7468](https\://github\.com/ansible\-collections/community\.general/pull/7468)\)\.
@@ -453,7 +556,7 @@ Regular bugfix and feature release\.
* redfish\_info \- adding the <code>BootProgress</code> property when getting <code>Systems</code> info \([https\://github\.com/ansible\-collections/community\.general/pull/7626](https\://github\.com/ansible\-collections/community\.general/pull/7626)\)\.
* ssh\_config \- adds <code>controlmaster</code>\, <code>controlpath</code> and <code>controlpersist</code> parameters \([https\://github\.com/ansible\-collections/community\.general/pull/7456](https\://github\.com/ansible\-collections/community\.general/pull/7456)\)\.
<a id="bugfixes-8"></a>
<a id="bugfixes-12"></a>
### Bugfixes
* apt\-rpm \- the module did not upgrade packages if a newer version exists\. Now the package will be reinstalled if the candidate is newer than the installed version \([https\://github\.com/ansible\-collections/community\.general/issues/7414](https\://github\.com/ansible\-collections/community\.general/issues/7414)\)\.
@@ -494,12 +597,12 @@ Regular bugfix and feature release\.
<a id="v8-0-2"></a>
## v8\.0\.2
<a id="release-summary-9"></a>
<a id="release-summary-13"></a>
### Release Summary
Bugfix release for inclusion in Ansible 9\.0\.0rc1\.
<a id="bugfixes-9"></a>
<a id="bugfixes-13"></a>
### Bugfixes
* ocapi\_utils\, oci\_utils\, redfish\_utils module utils \- replace <code>type\(\)</code> calls with <code>isinstance\(\)</code> calls \([https\://github\.com/ansible\-collections/community\.general/pull/7501](https\://github\.com/ansible\-collections/community\.general/pull/7501)\)\.
@@ -508,12 +611,12 @@ Bugfix release for inclusion in Ansible 9\.0\.0rc1\.
<a id="v8-0-1"></a>
## v8\.0\.1
<a id="release-summary-10"></a>
<a id="release-summary-14"></a>
### Release Summary
Bugfix release for inclusion in Ansible 9\.0\.0b1\.
<a id="bugfixes-10"></a>
<a id="bugfixes-14"></a>
### Bugfixes
* gitlab\_group\_members \- fix gitlab constants call in <code>gitlab\_group\_members</code> module \([https\://github\.com/ansible\-collections/community\.general/issues/7467](https\://github\.com/ansible\-collections/community\.general/issues/7467)\)\.
@@ -526,12 +629,12 @@ Bugfix release for inclusion in Ansible 9\.0\.0b1\.
<a id="v8-0-0"></a>
## v8\.0\.0
<a id="release-summary-11"></a>
<a id="release-summary-15"></a>
### Release Summary
This is release 8\.0\.0 of <code>community\.general</code>\, released on 2023\-11\-01\.
<a id="minor-changes-7"></a>
<a id="minor-changes-9"></a>
### Minor Changes
* The collection will start using semantic markup \([https\://github\.com/ansible\-collections/community\.general/pull/6539](https\://github\.com/ansible\-collections/community\.general/pull/6539)\)\.
@@ -730,7 +833,7 @@ This is release 8\.0\.0 of <code>community\.general</code>\, released on 2023\-1
* proxmox module utils \- removed unused imports \([https\://github\.com/ansible\-collections/community\.general/pull/6873](https\://github\.com/ansible\-collections/community\.general/pull/6873)\)\.
* xfconf \- the deprecated <code>disable\_facts</code> option was removed \([https\://github\.com/ansible\-collections/community\.general/pull/7358](https\://github\.com/ansible\-collections/community\.general/pull/7358)\)\.
<a id="bugfixes-11"></a>
<a id="bugfixes-15"></a>
### Bugfixes
* CmdRunner module utils \- does not attempt to resolve path if executable is a relative or absolute path \([https\://github\.com/ansible\-collections/community\.general/pull/7200](https\://github\.com/ansible\-collections/community\.general/pull/7200)\)\.

View File

@@ -6,6 +6,95 @@ Community General Release Notes
This changelog describes changes after version 7.0.0.
v8.6.7
======
Release Summary
---------------
Bugfix release.
Bugfixes
--------
- collection_version lookup plugin - use ``importlib`` directly instead of the deprecated and in ansible-core 2.19 removed ``ansible.module_utils.compat.importlib`` (https://github.com/ansible-collections/community.general/pull/9084).
- modprobe - fix check mode not being honored for ``persistent`` option (https://github.com/ansible-collections/community.general/issues/9051, https://github.com/ansible-collections/community.general/pull/9052).
v8.6.6
======
Release Summary
---------------
Regular bugfix release.
Note that this is the last regular bugfix release of community.general 8.x.y.
From now on, there will only be maintenance releases with major bugfixes and
security fixes.
Minor Changes
-------------
- redfish_confg - remove ``CapacityBytes`` from required paramaters of the ``CreateVolume`` command (https://github.com/ansible-collections/community.general/pull/8956).
Bugfixes
--------
- cloudflare_dns - fix changing Cloudflare SRV records (https://github.com/ansible-collections/community.general/issues/8679, https://github.com/ansible-collections/community.general/pull/8948).
- dig lookup plugin - fix using only the last nameserver specified (https://github.com/ansible-collections/community.general/pull/8970).
- homectl - the module now tries to use ``legacycrypt`` on Python 3.13+ (https://github.com/ansible-collections/community.general/issues/4691, https://github.com/ansible-collections/community.general/pull/8987).
- ini_file - pass absolute paths to ``module.atomic_move()`` (https://github.com/ansible/ansible/issues/83950, https://github.com/ansible-collections/community.general/pull/8925).
- ipa_hostgroup - fix ``enabled `` and ``disabled`` states (https://github.com/ansible-collections/community.general/issues/8408, https://github.com/ansible-collections/community.general/pull/8900).
- java_keystore - pass absolute paths to ``module.atomic_move()`` (https://github.com/ansible/ansible/issues/83950, https://github.com/ansible-collections/community.general/pull/8925).
- jenkins_plugin - pass absolute paths to ``module.atomic_move()`` (https://github.com/ansible/ansible/issues/83950, https://github.com/ansible-collections/community.general/pull/8925).
- kdeconfig - pass absolute paths to ``module.atomic_move()`` (https://github.com/ansible/ansible/issues/83950, https://github.com/ansible-collections/community.general/pull/8925).
- keycloak_realm - fix change detection in check mode by sorting the lists in the realms beforehand (https://github.com/ansible-collections/community.general/pull/8877).
- keycloak_user_federation - minimize change detection by setting ``krbPrincipalAttribute`` to ``''`` in Keycloak responses if missing (https://github.com/ansible-collections/community.general/pull/8785).
- keycloak_user_federation - remove ``lastSync`` parameter from Keycloak responses to minimize diff/changes (https://github.com/ansible-collections/community.general/pull/8812).
- one_service - fix service creation after it was deleted with ``unique`` parameter (https://github.com/ansible-collections/community.general/issues/3137, https://github.com/ansible-collections/community.general/pull/8887).
- pam_limits - pass absolute paths to ``module.atomic_move()`` (https://github.com/ansible/ansible/issues/83950, https://github.com/ansible-collections/community.general/pull/8925).
- udm_user - the module now tries to use ``legacycrypt`` on Python 3.13+ (https://github.com/ansible-collections/community.general/issues/4690, https://github.com/ansible-collections/community.general/pull/8987).
v8.6.5
======
Release Summary
---------------
Regular bugfix release.
Bugfixes
--------
- gitlab_group_access_token - fix crash in check mode caused by attempted access to a newly created access token (https://github.com/ansible-collections/community.general/pull/8796).
- gitlab_project_access_token - fix crash in check mode caused by attempted access to a newly created access token (https://github.com/ansible-collections/community.general/pull/8796).
- keycloak_realm_key - fix invalid usage of ``parent_id`` (https://github.com/ansible-collections/community.general/issues/7850, https://github.com/ansible-collections/community.general/pull/8823).
- keycloak_user_federation - fix key error when removing mappers during an update and new mappers are specified in the module args (https://github.com/ansible-collections/community.general/pull/8762).
- keycloak_user_federation - fix the ``UnboundLocalError`` that occurs when an ID is provided for a user federation mapper (https://github.com/ansible-collections/community.general/pull/8831).
- keycloak_user_federation - sort desired and after mapper list by name (analog to before mapper list) to minimize diff and make change detection more accurate (https://github.com/ansible-collections/community.general/pull/8761).
- proxmox inventory plugin - fixed a possible error on concatenating responses from proxmox. In case an API call unexpectedly returned an empty result, the inventory failed with a fatal error. Added check for empty response (https://github.com/ansible-collections/community.general/issues/8798, https://github.com/ansible-collections/community.general/pull/8794).
v8.6.4
======
Release Summary
---------------
Regular bugfix release.
Minor Changes
-------------
- passwordstore lookup plugin - add the current user to the lockfile file name to address issues on multi-user systems (https://github.com/ansible-collections/community.general/pull/8689).
Bugfixes
--------
- gitlab_runner - fix ``paused`` parameter being ignored (https://github.com/ansible-collections/community.general/pull/8648).
- homebrew_cask - fix ``upgrade_all`` returns ``changed`` when nothing upgraded (https://github.com/ansible-collections/community.general/issues/8707, https://github.com/ansible-collections/community.general/pull/8708).
- keycloak_user_federation - get cleartext IDP ``clientSecret`` from full realm info to detect changes to it (https://github.com/ansible-collections/community.general/issues/8294, https://github.com/ansible-collections/community.general/pull/8735).
- keycloak_user_federation - remove existing user federation mappers if they are not present in the federation configuration and will not be updated (https://github.com/ansible-collections/community.general/issues/7169, https://github.com/ansible-collections/community.general/pull/8695).
v8.6.3
======

View File

@@ -56,6 +56,8 @@ 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
The following commands show how to run sanity tests:
```.bash
@@ -66,6 +68,8 @@ ansible-test sanity --docker -v
ansible-test sanity --docker -v plugins/modules/system/pids.py tests/integration/targets/pids/
```
### Unit tests
The following commands show how to run unit tests:
```.bash
@@ -79,13 +83,32 @@ ansible-test units --docker -v --python 3.8
ansible-test units --docker -v --python 3.8 tests/unit/plugins/modules/net_tools/test_nmcli.py
```
### Integration tests
The following commands show how to run integration tests:
```.bash
# Run integration tests for the interfaces_files module in a Docker container using the
# fedora35 operating system image (the supported images depend on your ansible-core version):
ansible-test integration --docker fedora35 -v interfaces_file
#### In Docker
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`.
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
ansible-test integration -v --docker fedora40
# Template
ansible-test integration -v --docker image_name test_name
# Example community.general.ini_file module on fedora40 Docker image:
ansible-test integration -v --docker fedora40 ini_file
```
#### Without isolation
```.bash
# Run integration tests for the flattened lookup **without any isolation**:
ansible-test integration -v lookup_flattened
```

View File

@@ -23,9 +23,21 @@ We follow [Ansible Code of Conduct](https://docs.ansible.com/ansible/latest/comm
If you encounter abusive behavior violating the [Ansible Code of Conduct](https://docs.ansible.com/ansible/latest/community/code_of_conduct.html), please refer to the [policy violations](https://docs.ansible.com/ansible/latest/community/code_of_conduct.html#policy-violations) section of the Code of Conduct for information on how to raise a complaint.
## Communication
* Join the Ansible forum:
* [Get Help](https://forum.ansible.com/c/help/6): get help or help others. This is for questions about modules or plugins in the collection. Please add appropriate tags if you start new discussions.
* [Tag `community-general`](https://forum.ansible.com/tag/community-general): discuss the *collection itself*, instead of specific modules or plugins.
* [Social Spaces](https://forum.ansible.com/c/chat/4): gather and interact with fellow enthusiasts.
* [News & Announcements](https://forum.ansible.com/c/news/5): track project-wide announcements including social events.
* The Ansible [Bullhorn newsletter](https://docs.ansible.com/ansible/devel/community/communication.html#the-bullhorn): used to announce releases and important changes.
For more information about communication, see the [Ansible communication guide](https://docs.ansible.com/ansible/devel/community/communication.html).
## Tested with Ansible
Tested with the current ansible-core 2.13, ansible-core 2.14, ansible-core 2.15, ansible-core 2.16, ansible-core 2.17 releases and the current development version of ansible-core. Ansible-core versions before 2.13.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, and ansible-core 2.18 releases of ansible-core. Ansible-core versions before 2.13.0 are not supported. This includes all ansible-base 2.10 and Ansible 2.9 releases.
## External requirements
@@ -98,18 +110,6 @@ It is necessary for maintainers of this collection to be subscribed to:
They also should be subscribed to Ansible's [The Bullhorn newsletter](https://docs.ansible.com/ansible/devel/community/communication.html#the-bullhorn).
## Communication
We announce important development changes and releases through Ansible's [The Bullhorn newsletter](https://eepurl.com/gZmiEP). If you are a collection developer, be sure you are subscribed.
Join us in the `#ansible` (general use questions and support), `#ansible-community` (community and collection development questions), and other [IRC channels](https://docs.ansible.com/ansible/devel/community/communication.html#irc-channels) on [Libera.chat](https://libera.chat).
We take part in the global quarterly [Ansible Contributor Summit](https://github.com/ansible/community/wiki/Contributor-Summit) virtually or in-person. Track [The Bullhorn newsletter](https://eepurl.com/gZmiEP) and join us.
For more information about communities, meetings and agendas see [Community Wiki](https://github.com/ansible/community/wiki/Community).
For more information about communication, refer to Ansible's the [Communication guide](https://docs.ansible.com/ansible/devel/community/communication.html).
## Publishing New Version
See the [Releasing guidelines](https://github.com/ansible/community-docs/blob/main/releasing_collections.rst) to learn how to release this collection.

View File

@@ -1541,3 +1541,126 @@ releases:
- 8613-redfish_utils-language.yaml
- 8614-nsupdate-index-out-of-range.yml
release_date: '2024-07-14'
8.6.4:
changes:
bugfixes:
- gitlab_runner - fix ``paused`` parameter being ignored (https://github.com/ansible-collections/community.general/pull/8648).
- homebrew_cask - fix ``upgrade_all`` returns ``changed`` when nothing upgraded
(https://github.com/ansible-collections/community.general/issues/8707, https://github.com/ansible-collections/community.general/pull/8708).
- keycloak_user_federation - get cleartext IDP ``clientSecret`` from full
realm info to detect changes to it (https://github.com/ansible-collections/community.general/issues/8294,
https://github.com/ansible-collections/community.general/pull/8735).
- keycloak_user_federation - remove existing user federation mappers if they
are not present in the federation configuration and will not be updated
(https://github.com/ansible-collections/community.general/issues/7169, https://github.com/ansible-collections/community.general/pull/8695).
minor_changes:
- passwordstore lookup plugin - add the current user to the lockfile file
name to address issues on multi-user systems (https://github.com/ansible-collections/community.general/pull/8689).
release_summary: Regular bugfix release.
fragments:
- 8.6.4.yml
- 8648-fix-gitlab-runner-paused.yaml
- 8689-passwordstore-lock-naming.yml
- 8695-keycloak_user_federation-mapper-removal.yml
- 8708-homebrew_cask-fix-upgrade-all.yml
- 8735-keycloak_identity_provider-get-cleartext-secret-from-realm-info.yml
release_date: '2024-08-12'
8.6.5:
changes:
bugfixes:
- gitlab_group_access_token - fix crash in check mode caused by attempted
access to a newly created access token (https://github.com/ansible-collections/community.general/pull/8796).
- gitlab_project_access_token - fix crash in check mode caused by attempted
access to a newly created access token (https://github.com/ansible-collections/community.general/pull/8796).
- keycloak_realm_key - fix invalid usage of ``parent_id`` (https://github.com/ansible-collections/community.general/issues/7850,
https://github.com/ansible-collections/community.general/pull/8823).
- keycloak_user_federation - fix key error when removing mappers during an
update and new mappers are specified in the module args (https://github.com/ansible-collections/community.general/pull/8762).
- keycloak_user_federation - fix the ``UnboundLocalError`` that occurs when
an ID is provided for a user federation mapper (https://github.com/ansible-collections/community.general/pull/8831).
- keycloak_user_federation - sort desired and after mapper list by name (analog
to before mapper list) to minimize diff and make change detection more accurate
(https://github.com/ansible-collections/community.general/pull/8761).
- proxmox inventory plugin - fixed a possible error on concatenating responses
from proxmox. In case an API call unexpectedly returned an empty result,
the inventory failed with a fatal error. Added check for empty response
(https://github.com/ansible-collections/community.general/issues/8798, https://github.com/ansible-collections/community.general/pull/8794).
release_summary: Regular bugfix release.
fragments:
- 8.6.5.yml
- 8761-keycloak_user_federation-sort-desired-and-after-mappers-by-name.yml
- 8762-keycloac_user_federation-fix-key-error-when-updating.yml
- 8794-Fixing-possible-concatination-error.yaml
- 8796-gitlab-access-token-check-mode.yml
- 8823-keycloak-realm-key.yml
- 8831-fix-error-when-mapper-id-is-provided.yml
release_date: '2024-09-09'
8.6.6:
changes:
bugfixes:
- cloudflare_dns - fix changing Cloudflare SRV records (https://github.com/ansible-collections/community.general/issues/8679,
https://github.com/ansible-collections/community.general/pull/8948).
- dig lookup plugin - fix using only the last nameserver specified (https://github.com/ansible-collections/community.general/pull/8970).
- homectl - the module now tries to use ``legacycrypt`` on Python 3.13+ (https://github.com/ansible-collections/community.general/issues/4691,
https://github.com/ansible-collections/community.general/pull/8987).
- ini_file - pass absolute paths to ``module.atomic_move()`` (https://github.com/ansible/ansible/issues/83950,
https://github.com/ansible-collections/community.general/pull/8925).
- ipa_hostgroup - fix ``enabled `` and ``disabled`` states (https://github.com/ansible-collections/community.general/issues/8408,
https://github.com/ansible-collections/community.general/pull/8900).
- java_keystore - pass absolute paths to ``module.atomic_move()`` (https://github.com/ansible/ansible/issues/83950,
https://github.com/ansible-collections/community.general/pull/8925).
- jenkins_plugin - pass absolute paths to ``module.atomic_move()`` (https://github.com/ansible/ansible/issues/83950,
https://github.com/ansible-collections/community.general/pull/8925).
- kdeconfig - pass absolute paths to ``module.atomic_move()`` (https://github.com/ansible/ansible/issues/83950,
https://github.com/ansible-collections/community.general/pull/8925).
- keycloak_realm - fix change detection in check mode by sorting the lists
in the realms beforehand (https://github.com/ansible-collections/community.general/pull/8877).
- keycloak_user_federation - minimize change detection by setting ``krbPrincipalAttribute``
to ``''`` in Keycloak responses if missing (https://github.com/ansible-collections/community.general/pull/8785).
- keycloak_user_federation - remove ``lastSync`` parameter from Keycloak responses
to minimize diff/changes (https://github.com/ansible-collections/community.general/pull/8812).
- one_service - fix service creation after it was deleted with ``unique``
parameter (https://github.com/ansible-collections/community.general/issues/3137,
https://github.com/ansible-collections/community.general/pull/8887).
- pam_limits - pass absolute paths to ``module.atomic_move()`` (https://github.com/ansible/ansible/issues/83950,
https://github.com/ansible-collections/community.general/pull/8925).
- udm_user - the module now tries to use ``legacycrypt`` on Python 3.13+ (https://github.com/ansible-collections/community.general/issues/4690,
https://github.com/ansible-collections/community.general/pull/8987).
minor_changes:
- redfish_confg - remove ``CapacityBytes`` from required paramaters of the
``CreateVolume`` command (https://github.com/ansible-collections/community.general/pull/8956).
release_summary: 'Regular bugfix release.
Note that this is the last regular bugfix release of community.general 8.x.y.
From now on, there will only be maintenance releases with major bugfixes and
security fixes.'
fragments:
- 8.6.6.yml
- 8679-fix-cloudflare-srv.yml
- 8785-keycloak_user_federation-set-krbPrincipalAttribute-to-empty-string-if-missing.yaml
- 8812-keycloak-user-federation-remove-lastSync-param-from-kc-responses.yml
- 8877-keycloak_realm-sort-lists-before-change-detection.yaml
- 8887-fix-one_service-unique.yml
- 8900-ipa-hostgroup-fix-states.yml
- 8925-atomic.yml
- 8956-remove-capacitybytes-from-the-required-parameters_list.yml
- 8970-fix-dig-multi-nameservers.yml
- 8987-legacycrypt.yml
release_date: '2024-10-07'
8.6.7:
changes:
bugfixes:
- collection_version lookup plugin - use ``importlib`` directly instead of
the deprecated and in ansible-core 2.19 removed ``ansible.module_utils.compat.importlib``
(https://github.com/ansible-collections/community.general/pull/9084).
- modprobe - fix check mode not being honored for ``persistent`` option (https://github.com/ansible-collections/community.general/issues/9051,
https://github.com/ansible-collections/community.general/pull/9052).
release_summary: Bugfix release.
fragments:
- 8.6.7.yml
- 9052-modprobe-bugfix.yml
- 9084-collection_version-importlib.yml
release_date: '2024-11-03'

View File

@@ -9,6 +9,8 @@ edit_on_github:
path_prefix: ''
extra_links:
- description: Ask for help
url: https://forum.ansible.com/c/help/6/none
- description: Submit a bug report
url: https://github.com/ansible-collections/community.general/issues/new?assignees=&labels=&template=bug_report.yml
- description: Request a feature
@@ -22,10 +24,10 @@ communication:
- topic: General usage and support questions
network: Libera
channel: '#ansible'
mailing_lists:
- topic: Ansible Project List
url: https://groups.google.com/g/ansible-project
forums:
- topic: Ansible Forum
- topic: "Ansible Forum: General usage and support questions"
# The following URL directly points to the "Get Help" section
url: https://forum.ansible.com/c/help/6/none
- topic: "Ansible Forum: Discussions about the collection itself, not for specific modules or plugins"
# The following URL directly points to the "community-general" tag
url: https://forum.ansible.com/tag/community-general

View File

@@ -5,7 +5,7 @@
namespace: community
name: general
version: 8.6.3
version: 8.6.7
readme: README.md
authors:
- Ansible (https://github.com/ansible)

View File

@@ -88,6 +88,10 @@ class ActionModule(ActionBase):
max_timeout = self._connection._play_context.timeout
module_args = self._task.args
async_status_args = {}
starter_cmd = None
confirm_cmd = None
if module_args.get('state', None) == 'restored':
if not wrap_async:
if not check_mode:

View File

@@ -304,6 +304,7 @@ class OpenTelemetrySource(object):
status = Status(status_code=StatusCode.OK)
if host_data.status != 'included':
# Support loops
enriched_error_message = None
if 'results' in host_data.result._result:
if host_data.status == 'failed':
message = self.get_error_message_from_results(host_data.result._result['results'], task_data.action)

View File

@@ -13,6 +13,8 @@ DOCUMENTATION = '''
author: Felix Fontein (@felixfontein)
description:
- Transform a sequence of dictionaries to a dictionary where the dictionaries are indexed by an attribute.
- This filter is similar to the Jinja2 C(groupby) filter. Use the Jinja2 C(groupby) filter if you have multiple entries with the same value,
or when you need a dictionary with list values, or when you need to use deeply nested attributes.
positional: attribute
options:
_input:

View File

@@ -329,8 +329,9 @@ class InventoryModule(BaseInventoryPlugin, Constructable, Cacheable):
data = json['data']
break
else:
# /hosts 's 'results' is a list of all hosts, returned is paginated
data = data + json['data']
if json['data']:
# /hosts 's 'results' is a list of all hosts, returned is paginated
data = data + json['data']
break
self._cache[self.cache_key][url] = data

View File

@@ -63,11 +63,11 @@ RETURN = """
import json
import os
import re
from importlib import import_module
import yaml
from ansible.errors import AnsibleLookupError
from ansible.module_utils.compat.importlib import import_module
from ansible.plugins.lookup import LookupBase

View File

@@ -330,6 +330,7 @@ class LookupModule(LookupBase):
myres.use_edns(0, ednsflags=dns.flags.DO, payload=edns_size)
domains = []
nameservers = []
qtype = self.get_option('qtype')
flat = self.get_option('flat')
fail_on_error = self.get_option('fail_on_error')
@@ -345,7 +346,6 @@ class LookupModule(LookupBase):
if t.startswith('@'): # e.g. "@10.0.1.2,192.0.2.1" is ok.
nsset = t[1:].split(',')
for ns in nsset:
nameservers = []
# Check if we have a valid IP address. If so, use that, otherwise
# try to resolve name to address using system's resolver. If that
# fails we bail out.
@@ -358,7 +358,6 @@ class LookupModule(LookupBase):
nameservers.append(nsaddr)
except Exception as e:
raise AnsibleError("dns lookup NS: %s" % to_native(e))
myres.nameservers = nameservers
continue
if '=' in t:
try:
@@ -397,6 +396,9 @@ class LookupModule(LookupBase):
# print "--- domain = {0} qtype={1} rdclass={2}".format(domain, qtype, rdclass)
if len(nameservers) > 0:
myres.nameservers = nameservers
if qtype.upper() == 'PTR':
reversed_domains = []
for domain in domains:

View File

@@ -468,7 +468,8 @@ class LookupModule(LookupBase):
def opt_lock(self, type):
if self.get_option('lock') == type:
tmpdir = os.environ.get('TMPDIR', '/tmp')
lockfile = os.path.join(tmpdir, '.passwordstore.lock')
user = os.environ.get('USER')
lockfile = os.path.join(tmpdir, '.{0}.passwordstore.lock'.format(user))
with FileLock().lock_file(lockfile, tmpdir, self.lock_timeout):
self.locked = type
yield

View File

@@ -104,37 +104,37 @@ EXAMPLES = r"""
- name: Generate random string
ansible.builtin.debug:
var: lookup('community.general.random_string')
# Example result: ['DeadBeeF']
# Example result: 'DeadBeeF'
- name: Generate random string with length 12
ansible.builtin.debug:
var: lookup('community.general.random_string', length=12)
# Example result: ['Uan0hUiX5kVG']
# Example result: 'Uan0hUiX5kVG'
- name: Generate base64 encoded random string
ansible.builtin.debug:
var: lookup('community.general.random_string', base64=True)
# Example result: ['NHZ6eWN5Qk0=']
# Example result: 'NHZ6eWN5Qk0='
- name: Generate a random string with 1 lower, 1 upper, 1 number and 1 special char (at least)
ansible.builtin.debug:
var: lookup('community.general.random_string', min_lower=1, min_upper=1, min_special=1, min_numeric=1)
# Example result: ['&Qw2|E[-']
# Example result: '&Qw2|E[-'
- name: Generate a random string with all lower case characters
debug:
ansible.builtin.debug:
var: query('community.general.random_string', upper=false, numbers=false, special=false)
# Example result: ['exolxzyz']
- name: Generate random hexadecimal string
debug:
ansible.builtin.debug:
var: query('community.general.random_string', upper=false, lower=false, override_special=hex_chars, numbers=false)
vars:
hex_chars: '0123456789ABCDEF'
# Example result: ['D2A40737']
- name: Generate random hexadecimal string with override_all
debug:
ansible.builtin.debug:
var: query('community.general.random_string', override_all=hex_chars)
vars:
hex_chars: '0123456789ABCDEF'

View File

@@ -29,6 +29,7 @@ class iLORedfishUtils(RedfishUtils):
result['ret'] = True
data = response['data']
current_session = None
if 'Oem' in data:
if data["Oem"]["Hpe"]["Links"]["MySession"]["@odata.id"]:
current_session = data["Oem"]["Hpe"]["Links"]["MySession"]["@odata.id"]

View File

@@ -3679,8 +3679,8 @@ class RedfishUtils(object):
'msg': "Provided Storage Subsystem ID %s does not exist on the server" % storage_subsystem_id}
# Validate input parameters
required_parameters = ['RAIDType', 'Drives', 'CapacityBytes']
allowed_parameters = ['DisplayName', 'InitializeMethod', 'MediaSpanCount',
required_parameters = ['RAIDType', 'Drives']
allowed_parameters = ['CapacityBytes', 'DisplayName', 'InitializeMethod', 'MediaSpanCount',
'Name', 'ReadCachePolicy', 'StripSizeBytes', 'VolumeUsage', 'WriteCachePolicy']
for parameter in required_parameters:

View File

@@ -192,6 +192,7 @@ def main():
rmitab = module.get_bin_path('rmitab')
chitab = module.get_bin_path('chitab')
rc = 0
err = None
# check if the new entry exists
current_entry = check_current_entry(module)

View File

@@ -74,6 +74,7 @@ options:
world:
description:
- Use a custom world file when checking for explicitly installed packages.
The file is used only when a value is provided for O(name), and O(state) is set to V(present) or V(latest).
type: str
default: /etc/apk/world
version_added: 5.4.0

View File

@@ -102,40 +102,40 @@ EXAMPLES = r'''
- name: Create a @home subvolume under the root subvolume
community.general.btrfs_subvolume:
name: /@home
device: /dev/vda2
filesystem_device: /dev/vda2
- name: Remove the @home subvolume if it exists
community.general.btrfs_subvolume:
name: /@home
state: absent
device: /dev/vda2
filesystem_device: /dev/vda2
- name: Create a snapshot of the root subvolume named @
community.general.btrfs_subvolume:
name: /@
snapshot_source: /
device: /dev/vda2
filesystem_device: /dev/vda2
- name: Create a snapshot of the root subvolume and make it the new default subvolume
community.general.btrfs_subvolume:
name: /@
snapshot_source: /
default: Yes
device: /dev/vda2
filesystem_device: /dev/vda2
- name: Create a snapshot of the /@ subvolume and recursively creating intermediate subvolumes as required
community.general.btrfs_subvolume:
name: /@snapshots/@2022_06_09
snapshot_source: /@
recursive: True
device: /dev/vda2
filesystem_device: /dev/vda2
- name: Remove the /@ subvolume and recursively delete child subvolumes as required
community.general.btrfs_subvolume:
name: /@snapshots/@2022_06_09
snapshot_source: /@
recursive: True
device: /dev/vda2
filesystem_device: /dev/vda2
'''

View File

@@ -716,12 +716,14 @@ class CloudflareAPI(object):
"port": params['port'],
"weight": params['weight'],
"priority": params['priority'],
"name": params['record'],
"proto": params['proto'],
"service": params['service']
}
new_record = {"type": params['type'], "ttl": params['ttl'], 'data': srv_data}
new_record = {
"type": params['type'],
"name": params['service'] + '.' + params['proto'] + '.' + params['record'],
"ttl": params['ttl'],
'data': srv_data,
}
search_value = str(params['weight']) + '\t' + str(params['port']) + '\t' + params['value']
search_record = params['service'] + '.' + params['proto'] + '.' + params['record']

View File

@@ -183,6 +183,7 @@ class CronVar(object):
fileh = open(backup_file, 'w')
elif self.cron_file:
fileh = open(self.cron_file, 'w')
path = None
else:
filed, path = tempfile.mkstemp(prefix='crontab')
fileh = os.fdopen(filed, 'w')

View File

@@ -313,7 +313,10 @@ def main():
module.exit_json(changed=True, msg="Successfully recreated access token", access_token=gitlab_access_token.access_token_object._attrs)
else:
gitlab_access_token.create_access_token(group, {'name': name, 'scopes': scopes, 'access_level': access_level, 'expires_at': expires_at})
module.exit_json(changed=True, msg="Successfully created access token", access_token=gitlab_access_token.access_token_object._attrs)
if module.check_mode:
module.exit_json(changed=True, msg="Successfully created access token", access_token={})
else:
module.exit_json(changed=True, msg="Successfully created access token", access_token=gitlab_access_token.access_token_object._attrs)
if __name__ == '__main__':

View File

@@ -311,7 +311,10 @@ def main():
module.exit_json(changed=True, msg="Successfully recreated access token", access_token=gitlab_access_token.access_token_object._attrs)
else:
gitlab_access_token.create_access_token(project, {'name': name, 'scopes': scopes, 'access_level': access_level, 'expires_at': expires_at})
module.exit_json(changed=True, msg="Successfully created access token", access_token=gitlab_access_token.access_token_object._attrs)
if module.check_mode:
module.exit_json(changed=True, msg="Successfully created access token", access_token={})
else:
module.exit_json(changed=True, msg="Successfully created access token", access_token=gitlab_access_token.access_token_object._attrs)
if __name__ == '__main__':

View File

@@ -33,7 +33,10 @@ author:
- Samy Coenen (@SamyCoenen)
- Guillaume Martinez (@Lunik)
requirements:
- python-gitlab >= 1.5.0
- python-gitlab >= 1.5.0 for legacy runner registration workflow
(runner registration token - U(https://docs.gitlab.com/runner/register/#register-with-a-runner-registration-token-deprecated))
- python-gitlab >= 4.0.0 for new runner registration workflow
(runner authentication token - U(https://docs.gitlab.com/runner/register/#register-with-a-runner-authentication-token))
extends_documentation_fragment:
- community.general.auth_basic
- community.general.gitlab
@@ -466,6 +469,7 @@ def main():
state = module.params['state']
runner_description = module.params['description']
runner_active = module.params['active']
runner_paused = module.params['paused']
tag_list = module.params['tag_list']
run_untagged = module.params['run_untagged']
runner_locked = module.params['locked']
@@ -500,7 +504,7 @@ def main():
module.exit_json(changed=False, msg="Runner deleted or does not exists")
if state == 'present':
if gitlab_runner.create_or_update_runner(runner_description, {
runner_values = {
"active": runner_active,
"tag_list": tag_list,
"run_untagged": run_untagged,
@@ -510,7 +514,11 @@ def main():
"registration_token": registration_token,
"group": group,
"project": project,
}):
}
if LooseVersion(gitlab_runner._gitlab.version()[0]) >= LooseVersion("14.8.0"):
# the paused attribute for runners is available since 14.8
runner_values["paused"] = runner_paused
if gitlab_runner.create_or_update_runner(runner_description, runner_values):
module.exit_json(changed=True, runner=gitlab_runner.runner_object._attrs,
msg="Successfully created or updated the runner %s" % runner_description)
else:

View File

@@ -598,7 +598,12 @@ class HomebrewCask(object):
rc, out, err = self.module.run_command(cmd)
if rc == 0:
if re.search(r'==> No Casks to upgrade', out.strip(), re.IGNORECASE):
# 'brew upgrade --cask' does not output anything if no casks are upgraded
if not out.strip():
self.message = 'Homebrew casks already upgraded.'
# handle legacy 'brew cask upgrade'
elif re.search(r'==> No Casks to upgrade', out.strip(), re.IGNORECASE):
self.message = 'Homebrew casks already upgraded.'
else:

View File

@@ -18,11 +18,11 @@ version_added: 4.4.0
description:
- Manages a user's home directory managed by systemd-homed.
notes:
- This module does B(not) work with Python 3.13 or newer. It uses the deprecated L(crypt Python module,
https://docs.python.org/3.12/library/crypt.html) from the Python standard library, which was removed
from Python 3.13.
- This module requires the deprecated L(crypt Python module,
https://docs.python.org/3.12/library/crypt.html) library which was removed from Python 3.13.
For Python 3.13 or newer, you need to install L(legacycrypt, https://pypi.org/project/legacycrypt/).
requirements:
- Python 3.12 or earlier
- legacycrypt (on Python 3.13 or newer)
extends_documentation_fragment:
- community.general.attributes
attributes:
@@ -284,6 +284,17 @@ else:
HAS_CRYPT = True
CRYPT_IMPORT_ERROR = None
try:
import legacycrypt
if not HAS_CRYPT:
crypt = legacycrypt
except ImportError:
HAS_LEGACYCRYPT = False
LEGACYCRYPT_IMPORT_ERROR = traceback.format_exc()
else:
HAS_LEGACYCRYPT = True
LEGACYCRYPT_IMPORT_ERROR = None
class Homectl(object):
'''#TODO DOC STRINGS'''
@@ -606,9 +617,9 @@ def main():
]
)
if not HAS_CRYPT:
if not HAS_CRYPT and not HAS_LEGACYCRYPT:
module.fail_json(
msg=missing_required_lib('crypt (part of Python 3.13 standard library)'),
msg=missing_required_lib('crypt (part of standard library up to Python 3.12) or legacycrypt (PyPI)'),
exception=CRYPT_IMPORT_ERROR,
)

View File

@@ -569,7 +569,7 @@ def do_ini(module, filename, section=None, section_has_values=None, option=None,
module.fail_json(msg="Unable to create temporary file %s", traceback=traceback.format_exc())
try:
module.atomic_move(tmpfile, target_filename)
module.atomic_move(tmpfile, os.path.abspath(target_filename))
except IOError:
module.ansible.fail_json(msg='Unable to move temporary \
file %s to %s, IOError' % (tmpfile, target_filename), traceback=traceback.format_exc())

View File

@@ -57,13 +57,14 @@ options:
state:
description:
- State to ensure.
- V("absent") and V("disabled") give the same results.
- V("present") and V("enabled") give the same results.
default: "present"
choices: ["absent", "disabled", "enabled", "present"]
type: str
extends_documentation_fragment:
- community.general.ipa.documentation
- community.general.attributes
'''
EXAMPLES = r'''
@@ -160,7 +161,7 @@ def ensure(module, client):
module_hostgroup = get_hostgroup_dict(description=module.params['description'])
changed = False
if state == 'present':
if state in ['present', 'enabled']:
if not ipa_hostgroup:
changed = True
if not module.check_mode:

View File

@@ -459,6 +459,7 @@ def main():
if not os.access(b_path, os.R_OK):
module.fail_json(msg="Source %s not readable" % path)
state_to_restore = read_state(b_path)
cmd = None
else:
cmd = ' '.join(SAVECOMMAND)

View File

@@ -150,13 +150,11 @@ EXAMPLES = '''
name: example
certificate: |
-----BEGIN CERTIFICATE-----
h19dUZ2co2fI/ibYiwxWk4aeNE6KWvCaTQOMQ8t6Uo2XKhpL/xnjoAgh1uCQN/69
MG+34+RhUWzCfdZH7T8/qDxJw2kEPKluaYh7KnMsba+5jHjmtzix5QIDAQABo4IB
h19dUZ2co2f...
-----END CERTIFICATE-----
private_key: |
-----BEGIN RSA PRIVATE KEY-----
DBVFTEVDVFJJQ0lURSBERSBGUkFOQ0UxFzAVBgNVBAsMDjAwMDIgNTUyMDgxMzE3
GLlDNMw/uHyME7gHFsqJA7O11VY6O5WQ4IDP3m/s5ZV6s+Nn6Lerz17VZ99
DBVFTEVDVFJ...
-----END RSA PRIVATE KEY-----
password: changeit
dest: /etc/security/keystore.jks
@@ -472,7 +470,7 @@ class JavaKeystore:
if self.keystore_type == 'pkcs12':
# Preserve properties of the destination file, if any.
self.module.atomic_move(keystore_p12_path, self.keystore_path)
self.module.atomic_move(os.path.abspath(keystore_p12_path), os.path.abspath(self.keystore_path))
self.update_permissions()
self.result['changed'] = True
return self.result

View File

@@ -685,7 +685,7 @@ class JenkinsPlugin(object):
# Move the updates file to the right place if we could read it
if tmp_updates_file != updates_file:
self.module.atomic_move(tmp_updates_file, updates_file)
self.module.atomic_move(os.path.abspath(tmp_updates_file), os.path.abspath(updates_file))
# Check if we have the plugin data available
if not data.get('plugins', {}).get(self.params['name']):
@@ -718,7 +718,7 @@ class JenkinsPlugin(object):
details=to_native(e))
# Move the file onto the right place
self.module.atomic_move(tmp_f, f)
self.module.atomic_move(os.path.abspath(tmp_f), os.path.abspath(f))
def uninstall(self):
changed = False

View File

@@ -214,7 +214,7 @@ def run_module(module, tmpdir, kwriteconfig):
if module.params['backup'] and os.path.exists(b_path):
result['backup_file'] = module.backup_local(result['path'])
try:
module.atomic_move(b_tmpfile, b_path)
module.atomic_move(b_tmpfile, os.path.abspath(b_path))
except IOError:
module.ansible.fail_json(msg='Unable to move temporary file %s to %s, IOError' % (tmpfile, result['path']), traceback=traceback.format_exc())

View File

@@ -445,6 +445,15 @@ def get_identity_provider_with_mappers(kc, alias, realm):
idp = kc.get_identity_provider(alias, realm)
if idp is not None:
idp['mappers'] = sorted(kc.get_identity_provider_mappers(alias, realm), key=lambda x: x.get('name'))
# clientSecret returned by API when using `get_identity_provider(alias, realm)` is always **********
# to detect changes to the secret, we get the actual cleartext secret from the full realm info
if 'config' in idp:
if 'clientSecret' in idp['config']:
for idp_from_realm in kc.get_realm_by_id(realm).get('identityProviders', []):
if idp_from_realm['internalId'] == idp['internalId']:
cleartext_secret = idp_from_realm.get('config', {}).get('clientSecret')
if cleartext_secret:
idp['config']['clientSecret'] = cleartext_secret
if idp is None:
idp = {}
return idp

View File

@@ -803,7 +803,7 @@ def main():
if module._diff:
result['diff'] = dict(before=sanitize_cr(before_norm),
after=sanitize_cr(desired_norm))
result['changed'] = (before_realm != desired_realm)
result['changed'] = (before_norm != desired_norm)
module.exit_json(**result)

View File

@@ -68,7 +68,7 @@ options:
type: bool
parent_id:
description:
- The parent_id of the realm key. In practice the ID (name) of the realm.
- The parent_id of the realm key. In practice the name of the realm.
type: str
required: true
provider_id:
@@ -300,7 +300,7 @@ def main():
kc = KeycloakAPI(module, connection_header)
params_to_ignore = list(keycloak_argument_spec().keys()) + ["state", "force"]
params_to_ignore = list(keycloak_argument_spec().keys()) + ["state", "force", "parent_id"]
# Filter and map the parameters names that apply to the role
component_params = [x for x in module.params
@@ -371,7 +371,7 @@ def main():
parent_id = module.params.get('parent_id')
# Get a list of all Keycloak components that are of keyprovider type.
realm_keys = kc.get_components(urlencode(dict(type=provider_type, parent=parent_id)), parent_id)
realm_keys = kc.get_components(urlencode(dict(type=provider_type)), parent_id)
# If this component is present get its key ID. Confusingly the key ID is
# also known as the Provider ID.

View File

@@ -713,15 +713,23 @@ from ansible.module_utils.six.moves.urllib.parse import urlencode
from copy import deepcopy
def normalize_kc_comp(comp):
if 'config' in comp:
# kc completely removes the parameter `krbPrincipalAttribute` if it is set to `''`; the unset kc parameter is equivalent to `''`;
# to make change detection and diff more accurate we set it again in the kc responses
if 'krbPrincipalAttribute' not in comp['config']:
comp['config']['krbPrincipalAttribute'] = ['']
# kc stores a timestamp of the last sync in `lastSync` to time the periodic sync, it is removed to minimize diff/changes
comp['config'].pop('lastSync', None)
def sanitize(comp):
compcopy = deepcopy(comp)
if 'config' in compcopy:
compcopy['config'] = dict((k, v[0]) for k, v in compcopy['config'].items())
if 'bindCredential' in compcopy['config']:
compcopy['config']['bindCredential'] = '**********'
# an empty string is valid for krbPrincipalAttribute but is filtered out in diff
if 'krbPrincipalAttribute' not in compcopy['config']:
compcopy['config']['krbPrincipalAttribute'] = ''
if 'mappers' in compcopy:
for mapper in compcopy['mappers']:
if 'config' in mapper:
@@ -868,7 +876,9 @@ def main():
# if user federation exists, get associated mappers
if cid is not None and before_comp:
before_comp['mappers'] = sorted(kc.get_components(urlencode(dict(parent=cid)), realm), key=lambda x: x.get('name'))
before_comp['mappers'] = sorted(kc.get_components(urlencode(dict(parent=cid)), realm), key=lambda x: x.get('name') or '')
normalize_kc_comp(before_comp)
# Build a proposed changeset from parameters given to this module
changeset = {}
@@ -892,11 +902,11 @@ def main():
if cid is None:
old_mapper = {}
elif change.get('id') is not None:
old_mapper = kc.get_component(change['id'], realm)
old_mapper = next((before_mapper for before_mapper in before_comp.get('mappers', []) if before_mapper["id"] == change['id']), None)
if old_mapper is None:
old_mapper = {}
else:
found = kc.get_components(urlencode(dict(parent=cid, name=change['name'])), realm)
found = [before_mapper for before_mapper in before_comp.get('mappers', []) if before_mapper['name'] == change['name']]
if len(found) > 1:
module.fail_json(msg='Found multiple mappers with name `{name}`. Cannot continue.'.format(name=change['name']))
if len(found) == 1:
@@ -905,10 +915,11 @@ def main():
old_mapper = {}
new_mapper = old_mapper.copy()
new_mapper.update(change)
if new_mapper != old_mapper:
if changeset.get('mappers') is None:
changeset['mappers'] = list()
changeset['mappers'].append(new_mapper)
# changeset contains all desired mappers: those existing, to update or to create
if changeset.get('mappers') is None:
changeset['mappers'] = list()
changeset['mappers'].append(new_mapper)
changeset['mappers'] = sorted(changeset['mappers'], key=lambda x: x.get('name') or '')
# Prepare the desired values using the existing values (non-existence results in a dict that is save to use as a basis)
desired_comp = before_comp.copy()
@@ -931,42 +942,52 @@ def main():
# Process a creation
result['changed'] = True
if module._diff:
result['diff'] = dict(before='', after=sanitize(desired_comp))
if module.check_mode:
if module._diff:
result['diff'] = dict(before='', after=sanitize(desired_comp))
module.exit_json(**result)
# create it
desired_comp = desired_comp.copy()
updated_mappers = desired_comp.pop('mappers', [])
desired_mappers = desired_comp.pop('mappers', [])
after_comp = kc.create_component(desired_comp, realm)
cid = after_comp['id']
updated_mappers = []
# when creating a user federation, keycloak automatically creates default mappers
default_mappers = kc.get_components(urlencode(dict(parent=cid)), realm)
for mapper in updated_mappers:
found = kc.get_components(urlencode(dict(parent=cid, name=mapper['name'])), realm)
# create new mappers or update existing default mappers
for desired_mapper in desired_mappers:
found = [default_mapper for default_mapper in default_mappers if default_mapper['name'] == desired_mapper['name']]
if len(found) > 1:
module.fail_json(msg='Found multiple mappers with name `{name}`. Cannot continue.'.format(name=mapper['name']))
module.fail_json(msg='Found multiple mappers with name `{name}`. Cannot continue.'.format(name=desired_mapper['name']))
if len(found) == 1:
old_mapper = found[0]
else:
old_mapper = {}
new_mapper = old_mapper.copy()
new_mapper.update(mapper)
new_mapper.update(desired_mapper)
if new_mapper.get('id') is not None:
kc.update_component(new_mapper, realm)
updated_mappers.append(new_mapper)
else:
if new_mapper.get('parentId') is None:
new_mapper['parentId'] = after_comp['id']
mapper = kc.create_component(new_mapper, realm)
new_mapper['parentId'] = cid
updated_mappers.append(kc.create_component(new_mapper, realm))
after_comp['mappers'] = updated_mappers
# we remove all unwanted default mappers
# we use ids so we dont accidently remove one of the previously updated default mapper
for default_mapper in default_mappers:
if not default_mapper['id'] in [x['id'] for x in updated_mappers]:
kc.delete_component(default_mapper['id'], realm)
after_comp['mappers'] = kc.get_components(urlencode(dict(parent=cid)), realm)
normalize_kc_comp(after_comp)
if module._diff:
result['diff'] = dict(before='', after=sanitize(after_comp))
result['end_state'] = sanitize(after_comp)
result['msg'] = "User federation {id} has been created".format(id=after_comp['id'])
result['msg'] = "User federation {id} has been created".format(id=cid)
module.exit_json(**result)
else:
@@ -990,22 +1011,33 @@ def main():
module.exit_json(**result)
# do the update
desired_comp = desired_comp.copy()
updated_mappers = desired_comp.pop('mappers', [])
desired_mappers = desired_comp.pop('mappers', [])
kc.update_component(desired_comp, realm)
after_comp = kc.get_component(cid, realm)
for mapper in updated_mappers:
for before_mapper in before_comp.get('mappers', []):
# remove unwanted existing mappers that will not be updated
if not before_mapper['id'] in [x['id'] for x in desired_mappers if 'id' in x]:
kc.delete_component(before_mapper['id'], realm)
for mapper in desired_mappers:
if mapper in before_comp.get('mappers', []):
continue
if mapper.get('id') is not None:
kc.update_component(mapper, realm)
else:
if mapper.get('parentId') is None:
mapper['parentId'] = desired_comp['id']
mapper = kc.create_component(mapper, realm)
after_comp['mappers'] = updated_mappers
result['end_state'] = sanitize(after_comp)
kc.create_component(mapper, realm)
after_comp = kc.get_component(cid, realm)
after_comp['mappers'] = sorted(kc.get_components(urlencode(dict(parent=cid)), realm), key=lambda x: x.get('name') or '')
normalize_kc_comp(after_comp)
after_comp_sanitized = sanitize(after_comp)
before_comp_sanitized = sanitize(before_comp)
result['end_state'] = after_comp_sanitized
if module._diff:
result['diff'] = dict(before=before_comp_sanitized, after=after_comp_sanitized)
result['changed'] = before_comp_sanitized != after_comp_sanitized
result['msg'] = "User federation {id} has been updated".format(id=cid)
module.exit_json(**result)

View File

@@ -304,22 +304,7 @@ EXAMPLES = '''
security_protocol: 'ssl-with-validation-custom-ca'
certificate_authority: |
-----BEGIN CERTIFICATE-----
FAKECERTsdKgAwIBAgIBATANBgkqhkiG9w0BAQsFADAmMSQwIgYDVQQDDBtvcGVu
c2hpZnQtc2lnbmVyQDE1MDMzMjAxMTkwHhcNMTcwODIxMTI1NTE5WhcNMjIwODIw
MTI1NTIwWjAmMSQwIgYDVQQDDBtvcGVuc2hpZnQtc2lnbmVyQDE1MDMzMjAxMTkw
ggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDUDnL2tQ2xf/zO7F7hmZ4S
ZuwKENdI4IYuWSxye4i3hPhKg6eKPzGzmDNWkIMDOrDAj1EgVSNPtPwsOL8OWvJm
AaTjr070D7ZGWWnrrDrWEClBx9Rx/6JAM38RT8Pu7c1hXBm0J81KufSLLYiZ/gOw
Znks5v5RUSGcAXvLkBJeATbsbh6fKX0RgQ3fFTvqQaE/r8LxcTN1uehPX1g5AaRa
z/SNDHaFtQlE3XcqAAukyMn4N5kdNcuwF3GlQ+tJnJv8SstPkfQcZbTMUQ7I2KpJ
ajXnMxmBhV5fCN4rb0QUNCrk2/B+EUMBY4MnxIakqNxnN1kvgI7FBbFgrHUe6QvJ
AgMBAAGjIzAhMA4GA1UdDwEB/wQEAwICpDAPBgNVHRMBAf8EBTADAQH/MA0GCSqG
SIb3DQEBCwUAA4IBAQAYRV57LUsqznSLZHA77o9+0fQetIE115DYP7wea42PODJI
QJ+JETEfoCr0+YOMAbVmznP9GH5cMTKEWHExcIpbMBU7nMZp6A3htcJgF2fgPzOA
aTUtzkuVCSrV//mbbYVxoFOc6sR3Br0wBs5+5iz3dBSt7xmgpMzZvqsQl655i051
gGSTIY3z5EJmBZBjwuTjal9mMoPGA4eoTPqlITJDHQ2bdCV2oDbc7zqupGrUfZFA
qzgieEyGzdCSRwjr1/PibA3bpwHyhD9CGD0PRVVTLhw6h6L5kuN1jA20OfzWxf/o
XUsdmRaWiF+l4s6Dcd56SuRp5SGNa2+vP9Of/FX5
FAKECERTsdKgAwI...
-----END CERTIFICATE-----
metrics:
auth_key: 'topSecret'
@@ -330,22 +315,7 @@ EXAMPLES = '''
security_protocol: 'ssl-with-validation-custom-ca'
certificate_authority: |
-----BEGIN CERTIFICATE-----
FAKECERTsdKgAwIBAgIBATANBgkqhkiG9w0BAQsFADAmMSQwIgYDVQQDDBtvcGVu
c2hpZnQtc2lnbmVyQDE1MDMzMjAxMTkwHhcNMTcwODIxMTI1NTE5WhcNMjIwODIw
MTI1NTIwWjAmMSQwIgYDVQQDDBtvcGVuc2hpZnQtc2lnbmVyQDE1MDMzMjAxMTkw
ggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDUDnL2tQ2xf/zO7F7hmZ4S
ZuwKENdI4IYuWSxye4i3hPhKg6eKPzGzmDNWkIMDOrDAj1EgVSNPtPwsOL8OWvJm
AaTjr070D7ZGWWnrrDrWEClBx9Rx/6JAM38RT8Pu7c1hXBm0J81KufSLLYiZ/gOw
Znks5v5RUSGcAXvLkBJeATbsbh6fKX0RgQ3fFTvqQaE/r8LxcTN1uehPX1g5AaRa
z/SNDHaFtQlE3XcqAAukyMn4N5kdNcuwF3GlQ+tJnJv8SstPkfQcZbTMUQ7I2KpJ
ajXnMxmBhV5fCN4rb0QUNCrk2/B+EUMBY4MnxIakqNxnN1kvgI7FBbFgrHUe6QvJ
AgMBAAGjIzAhMA4GA1UdDwEB/wQEAwICpDAPBgNVHRMBAf8EBTADAQH/MA0GCSqG
SIb3DQEBCwUAA4IBAQAYRV57LUsqznSLZHA77o9+0fQetIE115DYP7wea42PODJI
QJ+JETEfoCr0+YOMAbVmznP9GH5cMTKEWHExcIpbMBU7nMZp6A3htcJgF2fgPzOA
aTUtzkuVCSrV//mbbYVxoFOc6sR3Br0wBs5+5iz3dBSt7xmgpMzZvqsQl655i051
gGSTIY3z5EJmBZBjwuTjal9mMoPGA4eoTPqlITJDHQ2bdCV2oDbc7zqupGrUfZFA
qzgieEyGzdCSRwjr1/PibA3bpwHyhD9CGD0PRVVTLhw6h6L5kuN1jA20OfzWxf/o
XUsdmRaWiF+l4s6Dcd56SuRp5SGNa2+vP9Of/FX5
FAKECERTsdKgAwI...
-----END CERTIFICATE-----
manageiq_connection:
url: 'https://127.0.0.1:80'
@@ -367,22 +337,7 @@ EXAMPLES = '''
security_protocol: 'ssl-with-validation-custom-ca'
certificate_authority: |
-----BEGIN CERTIFICATE-----
FAKECERTsdKgAwIBAgIBATANBgkqhkiG9w0BAQsFADAmMSQwIgYDVQQDDBtvcGVu
c2hpZnQtc2lnbmVyQDE1MDMzMjAxMTkwHhcNMTcwODIxMTI1NTE5WhcNMjIwODIw
MTI1NTIwWjAmMSQwIgYDVQQDDBtvcGVuc2hpZnQtc2lnbmVyQDE1MDMzMjAxMTkw
ggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDUDnL2tQ2xf/zO7F7hmZ4S
ZuwKENdI4IYuWSxye4i3hPhKg6eKPzGzmDNWkIMDOrDAj1EgVSNPtPwsOL8OWvJm
AaTjr070D7ZGWWnrrDrWEClBx9Rx/6JAM38RT8Pu7c1hXBm0J81KufSLLYiZ/gOw
Znks5v5RUSGcAXvLkBJeATbsbh6fKX0RgQ3fFTvqQaE/r8LxcTN1uehPX1g5AaRa
z/SNDHaFtQlE3XcqAAukyMn4N5kdNcuwF3GlQ+tJnJv8SstPkfQcZbTMUQ7I2KpJ
ajXnMxmBhV5fCN4rb0QUNCrk2/B+EUMBY4MnxIakqNxnN1kvgI7FBbFgrHUe6QvJ
AgMBAAGjIzAhMA4GA1UdDwEB/wQEAwICpDAPBgNVHRMBAf8EBTADAQH/MA0GCSqG
SIb3DQEBCwUAA4IBAQAYRV57LUsqznSLZHA77o9+0fQetIE115DYP7wea42PODJI
QJ+JETEfoCr0+YOMAbVmznP9GH5cMTKEWHExcIpbMBU7nMZp6A3htcJgF2fgPzOA
aTUtzkuVCSrV//mbbYVxoFOc6sR3Br0wBs5+5iz3dBSt7xmgpMzZvqsQl655i051
gGSTIY3z5EJmBZBjwuTjal9mMoPGA4eoTPqlITJDHQ2bdCV2oDbc7zqupGrUfZFA
qzgieEyGzdCSRwjr1/PibA3bpwHyhD9CGD0PRVVTLhw6h6L5kuN1jA20OfzWxf/o
XUsdmRaWiF+l4s6Dcd56SuRp5SGNa2+vP9Of/FX5
FAKECERTsdKgAwI...
-----END CERTIFICATE-----
metrics:
auth_key: 'topSecret'
@@ -392,22 +347,7 @@ EXAMPLES = '''
security_protocol: 'ssl-with-validation-custom-ca'
certificate_authority: |
-----BEGIN CERTIFICATE-----
FAKECERTsdKgAwIBAgIBATANBgkqhkiG9w0BAQsFADAmMSQwIgYDVQQDDBtvcGVu
c2hpZnQtc2lnbmVyQDE1MDMzMjAxMTkwHhcNMTcwODIxMTI1NTE5WhcNMjIwODIw
MTI1NTIwWjAmMSQwIgYDVQQDDBtvcGVuc2hpZnQtc2lnbmVyQDE1MDMzMjAxMTkw
ggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDUDnL2tQ2xf/zO7F7hmZ4S
ZuwKENdI4IYuWSxye4i3hPhKg6eKPzGzmDNWkIMDOrDAj1EgVSNPtPwsOL8OWvJm
AaTjr070D7ZGWWnrrDrWEClBx9Rx/6JAM38RT8Pu7c1hXBm0J81KufSLLYiZ/gOw
Znks5v5RUSGcAXvLkBJeATbsbh6fKX0RgQ3fFTvqQaE/r8LxcTN1uehPX1g5AaRa
z/SNDHaFtQlE3XcqAAukyMn4N5kdNcuwF3GlQ+tJnJv8SstPkfQcZbTMUQ7I2KpJ
ajXnMxmBhV5fCN4rb0QUNCrk2/B+EUMBY4MnxIakqNxnN1kvgI7FBbFgrHUe6QvJ
AgMBAAGjIzAhMA4GA1UdDwEB/wQEAwICpDAPBgNVHRMBAf8EBTADAQH/MA0GCSqG
SIb3DQEBCwUAA4IBAQAYRV57LUsqznSLZHA77o9+0fQetIE115DYP7wea42PODJI
QJ+JETEfoCr0+YOMAbVmznP9GH5cMTKEWHExcIpbMBU7nMZp6A3htcJgF2fgPzOA
aTUtzkuVCSrV//mbbYVxoFOc6sR3Br0wBs5+5iz3dBSt7xmgpMzZvqsQl655i051
gGSTIY3z5EJmBZBjwuTjal9mMoPGA4eoTPqlITJDHQ2bdCV2oDbc7zqupGrUfZFA
qzgieEyGzdCSRwjr1/PibA3bpwHyhD9CGD0PRVVTLhw6h6L5kuN1jA20OfzWxf/o
XUsdmRaWiF+l4s6Dcd56SuRp5SGNa2+vP9Of/FX5
FAKECERTsdKgAwI...
-----END CERTIFICATE-----
manageiq_connection:
url: 'https://127.0.0.1'
@@ -455,22 +395,7 @@ EXAMPLES = '''
validate_certs: true
certificate_authority: |
-----BEGIN CERTIFICATE-----
FAKECERTsdKgAwIBAgIBATANBgkqhkiG9w0BAQsFADAmMSQwIgYDVQQDDBtvcGVu
c2hpZnQtc2lnbmVyQDE1MDMzMjAxMTkwHhcNMTcwODIxMTI1NTE5WhcNMjIwODIw
MTI1NTIwWjAmMSQwIgYDVQQDDBtvcGVuc2hpZnQtc2lnbmVyQDE1MDMzMjAxMTkw
ggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDUDnL2tQ2xf/zO7F7hmZ4S
ZuwKENdI4IYuWSxye4i3hPhKg6eKPzGzmDNWkIMDOrDAj1EgVSNPtPwsOL8OWvJm
AaTjr070D7ZGWWnrrDrWEClBx9Rx/6JAM38RT8Pu7c1hXBm0J81KufSLLYiZ/gOw
Znks5v5RUSGcAXvLkBJeATbsbh6fKX0RgQ3fFTvqQaE/r8LxcTN1uehPX1g5AaRa
z/SNDHaFtQlE3XcqAAukyMn4N5kdNcuwF3GlQ+tJnJv8SstPkfQcZbTMUQ7I2KpJ
ajXnMxmBhV5fCN4rb0QUNCrk2/B+EUMBY4MnxIakqNxnN1kvgI7FBbFgrHUe6QvJ
AgMBAAGjIzAhMA4GA1UdDwEB/wQEAwICpDAPBgNVHRMBAf8EBTADAQH/MA0GCSqG
SIb3DQEBCwUAA4IBAQAYRV57LUsqznSLZHA77o9+0fQetIE115DYP7wea42PODJI
QJ+JETEfoCr0+YOMAbVmznP9GH5cMTKEWHExcIpbMBU7nMZp6A3htcJgF2fgPzOA
aTUtzkuVCSrV//mbbYVxoFOc6sR3Br0wBs5+5iz3dBSt7xmgpMzZvqsQl655i051
gGSTIY3z5EJmBZBjwuTjal9mMoPGA4eoTPqlITJDHQ2bdCV2oDbc7zqupGrUfZFA
qzgieEyGzdCSRwjr1/PibA3bpwHyhD9CGD0PRVVTLhw6h6L5kuN1jA20OfzWxf/o
XUsdmRaWiF+l4s6Dcd56SuRp5SGNa2+vP9Of/FX5
FAKECERTsdKgAwI...
-----END CERTIFICATE-----
metrics:
hostname: 'metrics.example.com'
@@ -480,22 +405,7 @@ EXAMPLES = '''
validate_certs: true
certificate_authority: |
-----BEGIN CERTIFICATE-----
FAKECERTsdKgAwIBAgIBATANBgkqhkiG9w0BAQsFADAmMSQwIgYDVQQDDBtvcGVu
c2hpZnQtc2lnbmVyQDE1MDMzMjAxMTkwHhcNMTcwODIxMTI1NTE5WhcNMjIwODIw
MTI1NTIwWjAmMSQwIgYDVQQDDBtvcGVuc2hpZnQtc2lnbmVyQDE1MDMzMjAxMTkw
ggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDUDnL2tQ2xf/zO7F7hmZ4S
ZuwKENdI4IYuWSxye4i3hPhKg6eKPzGzmDNWkIMDOrDAj1EgVSNPtPwsOL8OWvJm
AaTjr070D7ZGWWnrrDrWEClBx9Rx/6JAM38RT8Pu7c1hXBm0J81KufSLLYiZ/gOw
Znks5v5RUSGcAXvLkBJeATbsbh6fKX0RgQ3fFTvqQaE/r8LxcTN1uehPX1g5AaRa
z/SNDHaFtQlE3XcqAAukyMn4N5kdNcuwF3GlQ+tJnJv8SstPkfQcZbTMUQ7I2KpJ
ajXnMxmBhV5fCN4rb0QUNCrk2/B+EUMBY4MnxIakqNxnN1kvgI7FBbFgrHUe6QvJ
AgMBAAGjIzAhMA4GA1UdDwEB/wQEAwICpDAPBgNVHRMBAf8EBTADAQH/MA0GCSqG
SIb3DQEBCwUAA4IBAQAYRV57LUsqznSLZHA77o9+0fQetIE115DYP7wea42PODJI
QJ+JETEfoCr0+YOMAbVmznP9GH5cMTKEWHExcIpbMBU7nMZp6A3htcJgF2fgPzOA
aTUtzkuVCSrV//mbbYVxoFOc6sR3Br0wBs5+5iz3dBSt7xmgpMzZvqsQl655i051
gGSTIY3z5EJmBZBjwuTjal9mMoPGA4eoTPqlITJDHQ2bdCV2oDbc7zqupGrUfZFA
qzgieEyGzdCSRwjr1/PibA3bpwHyhD9CGD0PRVVTLhw6h6L5kuN1jA20OfzWxf/o
XUsdmRaWiF+l4s6Dcd56SuRp5SGNa2+vP9Of/FX5
FAKECERTsdKgAwI...
-----END CERTIFICATE-----
manageiq_connection:
url: 'https://127.0.0.1'
@@ -551,22 +461,7 @@ EXAMPLES = '''
validate_certs: 'true'
certificate_authority: |
-----BEGIN CERTIFICATE-----
FAKECERTsdKgAwIBAgIBATANBgkqhkiG9w0BAQsFADAmMSQwIgYDVQQDDBtvcGVu
c2hpZnQtc2lnbmVyQDE1MDMzMjAxMTkwHhcNMTcwODIxMTI1NTE5WhcNMjIwODIw
MTI1NTIwWjAmMSQwIgYDVQQDDBtvcGVuc2hpZnQtc2lnbmVyQDE1MDMzMjAxMTkw
ggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDUDnL2tQ2xf/zO7F7hmZ4S
ZuwKENdI4IYuWSxye4i3hPhKg6eKPzGzmDNWkIMDOrDAj1EgVSNPtPwsOL8OWvJm
AaTjr070D7ZGWWnrrDrWEClBx9Rx/6JAM38RT8Pu7c1hXBm0J81KufSLLYiZ/gOw
Znks5v5RUSGcAXvLkBJeATbsbh6fKX0RgQ3fFTvqQaE/r8LxcTN1uehPX1g5AaRa
z/SNDHaFtQlE3XcqAAukyMn4N5kdNcuwF3GlQ+tJnJv8SstPkfQcZbTMUQ7I2KpJ
ajXnMxmBhV5fCN4rb0QUNCrk2/B+EUMBY4MnxIakqNxnN1kvgI7FBbFgrHUe6QvJ
AgMBAAGjIzAhMA4GA1UdDwEB/wQEAwICpDAPBgNVHRMBAf8EBTADAQH/MA0GCSqG
SIb3DQEBCwUAA4IBAQAYRV57LUsqznSLZHA77o9+0fQetIE115DYP7wea42PODJI
QJ+JETEfoCr0+YOMAbVmznP9GH5cMTKEWHExcIpbMBU7nMZp6A3htcJgF2fgPzOA
aTUtzkuVCSrV//mbbYVxoFOc6sR3Br0wBs5+5iz3dBSt7xmgpMzZvqsQl655i051
gGSTIY3z5EJmBZBjwuTjal9mMoPGA4eoTPqlITJDHQ2bdCV2oDbc7zqupGrUfZFA
qzgieEyGzdCSRwjr1/PibA3bpwHyhD9CGD0PRVVTLhw6h6L5kuN1jA20OfzWxf/o
XUsdmRaWiF+l4s6Dcd56SuRp5SGNa2+vP9Of/FX5
FAKECERTsdKgAwI...
-----END CERTIFICATE-----
ssh_keypair:
hostname: director.example.com
@@ -590,22 +485,7 @@ EXAMPLES = '''
validate_certs: 'true'
certificate_authority: |
-----BEGIN CERTIFICATE-----
FAKECERTsdKgAwIBAgIBATANBgkqhkiG9w0BAQsFADAmMSQwIgYDVQQDDBtvcGVu
c2hpZnQtc2lnbmVyQDE1MDMzMjAxMTkwHhcNMTcwODIxMTI1NTE5WhcNMjIwODIw
MTI1NTIwWjAmMSQwIgYDVQQDDBtvcGVuc2hpZnQtc2lnbmVyQDE1MDMzMjAxMTkw
ggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDUDnL2tQ2xf/zO7F7hmZ4S
ZuwKENdI4IYuWSxye4i3hPhKg6eKPzGzmDNWkIMDOrDAj1EgVSNPtPwsOL8OWvJm
AaTjr070D7ZGWWnrrDrWEClBx9Rx/6JAM38RT8Pu7c1hXBm0J81KufSLLYiZ/gOw
Znks5v5RUSGcAXvLkBJeATbsbh6fKX0RgQ3fFTvqQaE/r8LxcTN1uehPX1g5AaRa
z/SNDHaFtQlE3XcqAAukyMn4N5kdNcuwF3GlQ+tJnJv8SstPkfQcZbTMUQ7I2KpJ
ajXnMxmBhV5fCN4rb0QUNCrk2/B+EUMBY4MnxIakqNxnN1kvgI7FBbFgrHUe6QvJ
AgMBAAGjIzAhMA4GA1UdDwEB/wQEAwICpDAPBgNVHRMBAf8EBTADAQH/MA0GCSqG
SIb3DQEBCwUAA4IBAQAYRV57LUsqznSLZHA77o9+0fQetIE115DYP7wea42PODJI
QJ+JETEfoCr0+YOMAbVmznP9GH5cMTKEWHExcIpbMBU7nMZp6A3htcJgF2fgPzOA
aTUtzkuVCSrV//mbbYVxoFOc6sR3Br0wBs5+5iz3dBSt7xmgpMzZvqsQl655i051
gGSTIY3z5EJmBZBjwuTjal9mMoPGA4eoTPqlITJDHQ2bdCV2oDbc7zqupGrUfZFA
qzgieEyGzdCSRwjr1/PibA3bpwHyhD9CGD0PRVVTLhw6h6L5kuN1jA20OfzWxf/o
XUsdmRaWiF+l4s6Dcd56SuRp5SGNa2+vP9Of/FX5
FAKECERTsdKgAwI...
-----END CERTIFICATE-----
metrics:
role: amqp

View File

@@ -181,6 +181,7 @@ def api_validation(args=None):
https://www.memset.com/apidocs/methods_dns.html#dns.zone_record_create)
'''
failed_validation = False
error = None
# priority can only be integer 0 > 999
if not 0 <= args['priority'] <= 999:

View File

@@ -163,8 +163,9 @@ class Modprobe(object):
def create_module_file(self):
file_path = os.path.join(MODULES_LOAD_LOCATION,
self.name + '.conf')
with open(file_path, 'w') as file:
file.write(self.name + '\n')
if not self.check_mode:
with open(file_path, 'w') as file:
file.write(self.name + '\n')
@property
def module_options_file_content(self):
@@ -175,8 +176,9 @@ class Modprobe(object):
def create_module_options_file(self):
new_file_path = os.path.join(PARAMETERS_FILES_LOCATION,
self.name + '.conf')
with open(new_file_path, 'w') as file:
file.write(self.module_options_file_content)
if not self.check_mode:
with open(new_file_path, 'w') as file:
file.write(self.module_options_file_content)
def disable_old_params(self):
@@ -190,7 +192,7 @@ class Modprobe(object):
file_content[index] = '#' + line
content_changed = True
if content_changed:
if not self.check_mode and content_changed:
with open(modprobe_file, 'w') as file:
file.write('\n'.join(file_content))
@@ -206,7 +208,7 @@ class Modprobe(object):
file_content[index] = '#' + line
content_changed = True
if content_changed:
if not self.check_mode and content_changed:
with open(module_file, 'w') as file:
file.write('\n'.join(file_content))

View File

@@ -522,7 +522,7 @@ def create_service_and_operation(module, auth, template_id, service_name, owner_
if unique:
service = get_service_by_name(module, auth, service_name)
if not service:
if not service or service["TEMPLATE"]["BODY"]["state"] == "DONE":
if not module.check_mode:
service = create_service(module, auth, template_id, service_name, custom_attrs, unique, wait, wait_timeout)
changed = True
@@ -637,7 +637,6 @@ def get_service_id_by_name(module, auth, service_name):
def get_connection_info(module):
url = module.params.get('api_url')
username = module.params.get('api_username')
password = module.params.get('api_password')

View File

@@ -1,7 +1,7 @@
#!/usr/bin/python
# -*- coding: utf-8 -*-
#
# Copyright (c) 2021, Georg Gadinger <nilsding@nilsding.org>
# Copyright (c) 2021, Jyrki Gadinger <nilsding@nilsding.org>
# 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
@@ -60,7 +60,7 @@ extends_documentation_fragment:
- community.general.attributes
author:
- "Georg Gadinger (@nilsding)"
- "Jyrki Gadinger (@nilsding)"
'''
EXAMPLES = '''

View File

@@ -339,7 +339,7 @@ def main():
pass
# Move tempfile to newfile
module.atomic_move(nf.name, limits_conf)
module.atomic_move(os.path.abspath(nf.name), os.path.abspath(limits_conf))
try:
nf.close()

View File

@@ -27,6 +27,7 @@ options:
type: list
elements: path
requirements:
- pip >= 20.3b1 (necessary for the C(--format) option)
- The requested pip executables must be installed on the target.
author:
- Matthew Jones (@matburt)

View File

@@ -157,6 +157,17 @@ EXAMPLES = '''
community.general.pipx:
name: pycowsay
state: absent
- name: Install multiple packages from list
vars:
pipx_packages:
- pycowsay
- black
- tox
community.general.pipx:
name: "{{ item }}"
state: latest
with_items: "{{ pipx_packages }}"
'''

View File

@@ -326,7 +326,8 @@ EXAMPLES = r'''
password: 123456
hostname: example.org
ostemplate: 'local:vztmpl/ubuntu-14.04-x86_64.tar.gz'
netif: '{"net0":"name=eth0,ip=dhcp,ip6=dhcp,bridge=vmbr0"}'
netif:
net0: "name=eth0,ip=dhcp,ip6=dhcp,bridge=vmbr0"
- name: Create new container with minimal options defining network interface with static ip
community.general.proxmox:
@@ -338,7 +339,21 @@ EXAMPLES = r'''
password: 123456
hostname: example.org
ostemplate: 'local:vztmpl/ubuntu-14.04-x86_64.tar.gz'
netif: '{"net0":"name=eth0,gw=192.168.0.1,ip=192.168.0.2/24,bridge=vmbr0"}'
netif:
net0: "name=eth0,gw=192.168.0.1,ip=192.168.0.2/24,bridge=vmbr0"
- name: Create new container with more options defining network interface with static ip4 and ip6 with vlan-tag and mtu
community.general.proxmox:
vmid: 100
node: uk-mc02
api_user: root@pam
api_password: 1q2w3e
api_host: node1
password: 123456
hostname: example.org
ostemplate: 'local:vztmpl/ubuntu-14.04-x86_64.tar.gz'
netif:
net0: "name=eth0,gw=192.168.0.1,ip=192.168.0.2/24,ip6=fe80::1227/64,gw6=fe80::1,bridge=vmbr0,firewall=1,tag=934,mtu=1500"
- name: Create new container with minimal options defining a mount with 8GB
community.general.proxmox:
@@ -350,7 +365,8 @@ EXAMPLES = r'''
password: 123456
hostname: example.org
ostemplate: 'local:vztmpl/ubuntu-14.04-x86_64.tar.gz'
mounts: '{"mp0":"local:8,mp=/mnt/test/"}'
mounts:
mp0: "local:8,mp=/mnt/test/"
- name: Create new container with minimal options defining a cpu core limit
community.general.proxmox:
@@ -420,7 +436,8 @@ EXAMPLES = r'''
api_user: root@pam
api_password: 1q2w3e
api_host: node1
netif: '{"net0":"name=eth0,gw=192.168.0.1,ip=192.168.0.3/24,bridge=vmbr0"}'
netif:
net0: "name=eth0,gw=192.168.0.1,ip=192.168.0.3/24,bridge=vmbr0"
update: true
- name: Start container

View File

@@ -541,6 +541,7 @@ class ProxmoxDiskAnsible(ProxmoxAnsible):
# NOOP
return False, "Disk %s not found in VM %s and creation was disabled in parameters." % (disk, vmid)
timeout_str = "Reached timeout. Last line in task before timeout: %s"
if (create == 'regular' and disk not in vm_config) or (create == 'forced'):
# CREATE
playbook_config = self.get_create_attributes()

View File

@@ -163,6 +163,9 @@ options:
required: false
description:
- Setting dict of volume to be created.
- If C(CapacityBytes) key is not specified in this dictionary, the size of
the volume will be determined by the Redfish service. It is possible the
size will not be the maximum available size.
type: dict
default: {}
version_added: '7.5.0'

View File

@@ -307,6 +307,8 @@ def main():
if m_args['community'] is None:
module.fail_json(msg='Community not set when using snmp version 2')
integrity_proto = None
privacy_proto = None
if m_args['version'] == "v3":
if m_args['username'] is None:
module.fail_json(msg='Username not set when using snmp version 3')

View File

@@ -49,7 +49,8 @@ options:
aliases: [ rtc ]
choices: [ local, UTC ]
notes:
- On SmartOS the C(sm-set-timezone) utility (part of the smtools package) is required to set the zone timezone
- On Ubuntu 24.04 the C(util-linux-extra) package is required to provide the C(hwclock) command.
- On SmartOS the C(sm-set-timezone) utility (part of the smtools package) is required to set the zone timezone.
- On AIX only Olson/tz database timezones are usable (POSIX is not supported).
An OS reboot is also required on AIX for the new timezone setting to take effect.
Note that AIX 6.1+ is needed (OS level 61 or newer).
@@ -75,6 +76,7 @@ diff:
EXAMPLES = r'''
- name: Set timezone to Asia/Tokyo
become: true
community.general.timezone:
name: Asia/Tokyo
'''

View File

@@ -21,11 +21,11 @@ description:
server (UCS).
It uses the python API of the UCS to create a new object or edit it."
notes:
- This module does B(not) work with Python 3.13 or newer. It uses the deprecated L(crypt Python module,
https://docs.python.org/3.12/library/crypt.html) from the Python standard library, which was removed
from Python 3.13.
- This module requires the deprecated L(crypt Python module,
https://docs.python.org/3.12/library/crypt.html) library which was removed from Python 3.13.
For Python 3.13 or newer, you need to install L(legacycrypt, https://pypi.org/project/legacycrypt/).
requirements:
- Python 3.12 or earlier
- legacycrypt (on Python 3.13 or newer)
extends_documentation_fragment:
- community.general.attributes
attributes:
@@ -350,6 +350,17 @@ else:
HAS_CRYPT = True
CRYPT_IMPORT_ERROR = None
try:
import legacycrypt
if not HAS_CRYPT:
crypt = legacycrypt
except ImportError:
HAS_LEGACYCRYPT = False
LEGACYCRYPT_IMPORT_ERROR = traceback.format_exc()
else:
HAS_LEGACYCRYPT = True
LEGACYCRYPT_IMPORT_ERROR = None
def main():
expiry = date.strftime(date.today() + timedelta(days=365), "%Y-%m-%d")
@@ -467,10 +478,10 @@ def main():
])
)
if not HAS_CRYPT:
if not HAS_CRYPT and not HAS_LEGACYCRYPT:
module.fail_json(
msg=missing_required_lib('crypt (part of Python 3.13 standard library)'),
exception=CRYPT_IMPORT_ERROR,
msg=missing_required_lib('crypt (part of standard library up to Python 3.12) or legacycrypt (PyPI)'),
exception=LEGACYCRYPT_IMPORT_ERROR,
)
username = module.params['username']

View File

@@ -5,3 +5,4 @@
dependencies:
- setup_pkg_mgr
- setup_os_pkg_name

View File

@@ -9,17 +9,10 @@
suffix: .django_manage
register: tmp_django_root
- name: Install virtualenv on CentOS 8
- name: Install virtualenv
package:
name: virtualenv
name: "{{ os_package_name.virtualenv }}"
state: present
when: ansible_distribution == 'CentOS' and ansible_distribution_major_version == '8'
- name: Install virtualenv on Arch Linux
pip:
name: virtualenv
state: present
when: ansible_os_family == 'Archlinux'
- name: Install required library
pip:

View File

@@ -2,5 +2,4 @@
# 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
cloud/gandi
unsupported

View File

@@ -15,6 +15,11 @@
ignore_errors: true
- block:
- name: Install legacycrypt on Python 3.13+
pip:
name: legacycrypt
when: ansible_python_version is version("3.13", ">=")
- name: Check and start systemd-homed service
service:
name: systemd-homed.service

View File

@@ -6,4 +6,3 @@ azp/posix/2
destructive
skip/python2
skip/python3.5
disabled # TODO

View File

@@ -217,76 +217,76 @@
- "'tox' not in uninstall_tox_again.application"
##############################################################################
- name: ensure application ansible-lint is uninstalled
- name: ensure application pylint is uninstalled
community.general.pipx:
name: ansible-lint
name: pylint
state: absent
- name: install application ansible-lint
- name: install application pylint
community.general.pipx:
name: ansible-lint
register: install_ansible_lint
name: pylint
register: install_pylint
- name: inject packages
community.general.pipx:
state: inject
name: ansible-lint
name: pylint
inject_packages:
- licenses
register: inject_pkgs_ansible_lint
register: inject_pkgs_pylint
- name: inject packages with apps
community.general.pipx:
state: inject
name: ansible-lint
name: pylint
inject_packages:
- black
install_apps: true
register: inject_pkgs_apps_ansible_lint
register: inject_pkgs_apps_pylint
- name: cleanup ansible-lint
- name: cleanup pylint
community.general.pipx:
state: absent
name: ansible-lint
register: uninstall_ansible_lint
name: pylint
register: uninstall_pylint
- name: check assertions inject_packages
assert:
that:
- install_ansible_lint is changed
- inject_pkgs_ansible_lint is changed
- '"ansible-lint" in inject_pkgs_ansible_lint.application'
- '"licenses" in inject_pkgs_ansible_lint.application["ansible-lint"]["injected"]'
- inject_pkgs_apps_ansible_lint is changed
- '"ansible-lint" in inject_pkgs_apps_ansible_lint.application'
- '"black" in inject_pkgs_apps_ansible_lint.application["ansible-lint"]["injected"]'
- uninstall_ansible_lint is changed
- install_pylint is changed
- inject_pkgs_pylint is changed
- '"pylint" in inject_pkgs_pylint.application'
- '"licenses" in inject_pkgs_pylint.application["pylint"]["injected"]'
- inject_pkgs_apps_pylint is changed
- '"pylint" in inject_pkgs_apps_pylint.application'
- '"black" in inject_pkgs_apps_pylint.application["pylint"]["injected"]'
- uninstall_pylint is changed
##############################################################################
- name: install jupyter - not working smoothly in freebsd
when: ansible_system != 'FreeBSD'
# when: ansible_system != 'FreeBSD'
block:
- name: ensure application jupyter is uninstalled
- name: ensure application mkdocs is uninstalled
community.general.pipx:
name: jupyter
name: mkdocs
state: absent
- name: install application jupyter
- name: install application mkdocs
community.general.pipx:
name: jupyter
name: mkdocs
install_deps: true
register: install_jupyter
register: install_mkdocs
- name: cleanup jupyter
- name: cleanup mkdocs
community.general.pipx:
state: absent
name: jupyter
name: mkdocs
- name: check assertions
assert:
that:
- install_jupyter is changed
- '"ipython" in install_jupyter.stdout'
- install_mkdocs is changed
- '"markdown_py" in install_mkdocs.stdout'
##############################################################################
- name: ensure /opt/pipx

View File

@@ -6,4 +6,3 @@ azp/posix/3
destructive
skip/python2
skip/python3.5
disabled # TODO

View File

@@ -68,7 +68,7 @@
apps:
- name: tox
source: tox==3.24.0
- name: ansible-lint
- name: pylint
inject_packages:
- licenses
@@ -81,7 +81,7 @@
- name: install applications
community.general.pipx:
name: "{{ item.name }}"
source: "{{ item.source|default(omit) }}"
source: "{{ item.source | default(omit) }}"
loop: "{{ apps }}"
- name: inject packages
@@ -102,9 +102,9 @@
include_injected: true
register: info2_all_deps
- name: retrieve application ansible-lint
- name: retrieve application pylint
community.general.pipx_info:
name: ansible-lint
name: pylint
include_deps: true
include_injected: true
register: info2_lint
@@ -131,10 +131,10 @@
- "'injected' in all_apps_deps[0]"
- "'licenses' in all_apps_deps[0].injected"
- lint|length == 1
- lint | length == 1
- all_apps_deps|length == 2
- lint[0] == all_apps_deps[0]
vars:
all_apps: "{{ info2_all.application|sort(attribute='name') }}"
all_apps_deps: "{{ info2_all_deps.application|sort(attribute='name') }}"
lint: "{{ info2_lint.application|sort(attribute='name') }}"
all_apps_deps: "{{ info2_all_deps.application | sort(attribute='name') }}"
lint: "{{ info2_lint.application | sort(attribute='name') }}"

View File

@@ -0,0 +1,11 @@
---
# 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: Update OS Package name fact (alpine)
ansible.builtin.set_fact:
os_package_name: "{{ os_package_name | combine(specific_package_names) }}"
vars:
specific_package_names:
virtualenv: py3-virtualenv

View File

@@ -0,0 +1,11 @@
---
# 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: Update OS Package name fact (archlinux)
ansible.builtin.set_fact:
os_package_name: "{{ os_package_name | combine(specific_package_names) }}"
vars:
specific_package_names:
virtualenv: python-virtualenv

View File

@@ -0,0 +1,10 @@
---
# 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: Update OS Package name fact (debian)
ansible.builtin.set_fact:
os_package_name: "{{ os_package_name | combine(specific_package_names) }}"
vars:
specific_package_names: {}

View File

@@ -0,0 +1,11 @@
---
# 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: Update OS Package name fact (default)
ansible.builtin.set_fact:
os_package_name: "{{ os_package_name | combine(specific_package_names) }}"
vars:
specific_package_names:
virtualenv: virtualenv

View File

@@ -0,0 +1,26 @@
---
####################################################################
# WARNING: These are designed specifically for Ansible tests #
# and should not be used as examples of how to write Ansible roles #
####################################################################
# 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: Make sure we have the ansible_os_family and ansible_distribution_version facts
ansible.builtin.setup:
gather_subset: distribution
when: ansible_facts == {}
- name: Create OS Package name fact
ansible.builtin.set_fact:
os_package_name: {}
- name: Include the files setting the package names
ansible.builtin.include_tasks: "{{ file }}"
loop_control:
loop_var: file
loop:
- "default.yml"
- "{{ ansible_os_family | lower }}.yml"

View File

@@ -0,0 +1,10 @@
---
# 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: Update OS Package name fact (redhat)
ansible.builtin.set_fact:
os_package_name: "{{ os_package_name | combine(specific_package_names) }}"
vars:
specific_package_names: {}

View File

@@ -0,0 +1,11 @@
---
# 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: Update OS Package name fact (suse)
ansible.builtin.set_fact:
os_package_name: "{{ os_package_name | combine(specific_package_names) }}"
vars:
specific_package_names:
virtualenv: python3-virtualenv

View File

@@ -15,9 +15,8 @@
ansible.builtin.include_tasks: test.yml
- name: Include test_channel
ansible.builtin.include_tasks: test_channel.yml
# TODO: Find better package to download and install from sources - cider 1.6.0 takes over 35 seconds to install
# - name: Include test_dangerous
# ansible.builtin.include_tasks: test_dangerous.yml
- name: Include test_dangerous
ansible.builtin.include_tasks: test_dangerous.yml
- name: Include test_3dash
ansible.builtin.include_tasks: test_3dash.yml
- name: Include test_empty_list

View File

@@ -5,43 +5,48 @@
# NOTE This is currently disabled for performance reasons!
- name: Make sure package is not installed (cider)
- name: Make sure package is not installed (bpytop)
community.general.snap:
name: cider
name: bpytop
state: absent
- name: Download cider snap
ansible.builtin.get_url:
url: https://github.com/ciderapp/cider-releases/releases/download/v1.6.0/cider_1.6.0_amd64.snap
dest: "{{ remote_tmp_dir }}/cider_1.6.0_amd64.snap"
mode: "0644"
- name: Download bpytop snap
ansible.builtin.command:
cmd: snap download bpytop
chdir: "{{ remote_tmp_dir }}"
register: bpytop_download
# Test for https://github.com/ansible-collections/community.general/issues/5715
- name: Install package from file (check)
community.general.snap:
name: "{{ remote_tmp_dir }}/cider_1.6.0_amd64.snap"
dangerous: true
state: present
check_mode: true
register: install_dangerous_check
- name: Test block
vars:
snap_file: "{{ (bpytop_download.stdout_lines[-1] | split(' '))[-1] }}"
snap_path: "{{ remote_tmp_dir }}/{{ snap_file }}"
block:
# Test for https://github.com/ansible-collections/community.general/issues/5715
- name: Install package from file (check)
community.general.snap:
name: "{{ snap_path }}"
dangerous: true
state: present
check_mode: true
register: install_dangerous_check
- name: Install package from file
community.general.snap:
name: "{{ remote_tmp_dir }}/cider_1.6.0_amd64.snap"
dangerous: true
state: present
register: install_dangerous
- name: Install package from file
community.general.snap:
name: "{{ snap_path }}"
dangerous: true
state: present
register: install_dangerous
- name: Install package from file
community.general.snap:
name: "{{ remote_tmp_dir }}/cider_1.6.0_amd64.snap"
dangerous: true
state: present
register: install_dangerous_idempot
- name: Install package from file (again)
community.general.snap:
name: "{{ snap_path }}"
dangerous: true
state: present
register: install_dangerous_idempot
- name: Remove package
community.general.snap:
name: cider
name: bpytop
state: absent
register: remove_dangerous

View File

@@ -7,3 +7,4 @@ destructive
skip/aix
skip/osx
skip/macos
skip/rhel7.9 # TODO: '/bin/timedatectl set-local-rtc no' fails with 'Failed to set local RTC: Failed to set RTC to local/UTC: Input/output error'

View File

@@ -60,6 +60,14 @@
state: present
when: ansible_distribution == 'Alpine'
- name: make sure hwclock is installed in Ubuntu 24.04
package:
name: util-linux-extra
state: present
when:
- ansible_distribution == 'Ubuntu'
- ansible_facts.distribution_major_version is version('24', '>=')
- name: make sure the dbus service is started under systemd
systemd:
name: dbus

View File

@@ -146,7 +146,7 @@ def serialize_groups(groups):
return list(map(str, groups))
@ pytest.fixture(scope="module")
@pytest.fixture(scope="module")
def inventory():
r = InventoryModule()
r.inventory = InventoryData()

View File

@@ -7,7 +7,7 @@ from __future__ import (absolute_import, division, print_function)
__metaclass__ = type
from ansible_collections.community.general.plugins.modules.monitoring.datadog import datadog_downtime
from ansible_collections.community.general.plugins.modules import datadog_downtime
from ansible_collections.community.general.tests.unit.compat.mock import MagicMock, patch
from ansible_collections.community.general.tests.unit.plugins.modules.utils import (
AnsibleExitJson, AnsibleFailJson, ModuleTestCase, set_module_args
@@ -36,7 +36,7 @@ class TestDatadogDowntime(ModuleTestCase):
set_module_args({})
self.module.main()
@patch("ansible_collections.community.general.plugins.modules.monitoring.datadog.datadog_downtime.DowntimesApi")
@patch("ansible_collections.community.general.plugins.modules.datadog_downtime.DowntimesApi")
def test_create_downtime_when_no_id(self, downtimes_api_mock):
set_module_args({
"monitor_tags": ["foo:bar"],
@@ -60,10 +60,11 @@ class TestDatadogDowntime(ModuleTestCase):
downtime.end = 2222
downtime.timezone = "UTC"
downtime.recurrence = DowntimeRecurrence(
rrule="rrule"
rrule="rrule",
type="rrule"
)
create_downtime_mock = MagicMock(return_value=Downtime(id=12345))
create_downtime_mock = MagicMock(return_value=self.__downtime_with_id(12345))
downtimes_api_mock.return_value = MagicMock(create_downtime=create_downtime_mock)
with self.assertRaises(AnsibleExitJson) as result:
self.module.main()
@@ -71,7 +72,7 @@ class TestDatadogDowntime(ModuleTestCase):
self.assertEqual(result.exception.args[0]['downtime']['id'], 12345)
create_downtime_mock.assert_called_once_with(downtime)
@patch("ansible_collections.community.general.plugins.modules.monitoring.datadog.datadog_downtime.DowntimesApi")
@patch("ansible_collections.community.general.plugins.modules.datadog_downtime.DowntimesApi")
def test_create_downtime_when_id_and_disabled(self, downtimes_api_mock):
set_module_args({
"id": 1212,
@@ -96,11 +97,16 @@ class TestDatadogDowntime(ModuleTestCase):
downtime.end = 2222
downtime.timezone = "UTC"
downtime.recurrence = DowntimeRecurrence(
rrule="rrule"
rrule="rrule",
type="rrule"
)
create_downtime_mock = MagicMock(return_value=Downtime(id=12345))
get_downtime_mock = MagicMock(return_value=Downtime(id=1212, disabled=True))
disabled_downtime = Downtime()
disabled_downtime.disabled = True
disabled_downtime.id = 1212
create_downtime_mock = MagicMock(return_value=self.__downtime_with_id(12345))
get_downtime_mock = MagicMock(return_value=disabled_downtime)
downtimes_api_mock.return_value = MagicMock(
create_downtime=create_downtime_mock, get_downtime=get_downtime_mock
)
@@ -111,7 +117,7 @@ class TestDatadogDowntime(ModuleTestCase):
create_downtime_mock.assert_called_once_with(downtime)
get_downtime_mock.assert_called_once_with(1212)
@patch("ansible_collections.community.general.plugins.modules.monitoring.datadog.datadog_downtime.DowntimesApi")
@patch("ansible_collections.community.general.plugins.modules.datadog_downtime.DowntimesApi")
def test_update_downtime_when_not_disabled(self, downtimes_api_mock):
set_module_args({
"id": 1212,
@@ -136,11 +142,16 @@ class TestDatadogDowntime(ModuleTestCase):
downtime.end = 2222
downtime.timezone = "UTC"
downtime.recurrence = DowntimeRecurrence(
rrule="rrule"
rrule="rrule",
type="rrule"
)
update_downtime_mock = MagicMock(return_value=Downtime(id=1212))
get_downtime_mock = MagicMock(return_value=Downtime(id=1212, disabled=False))
enabled_downtime = Downtime()
enabled_downtime.disabled = False
enabled_downtime.id = 1212
update_downtime_mock = MagicMock(return_value=self.__downtime_with_id(1212))
get_downtime_mock = MagicMock(return_value=enabled_downtime)
downtimes_api_mock.return_value = MagicMock(
update_downtime=update_downtime_mock, get_downtime=get_downtime_mock
)
@@ -151,7 +162,7 @@ class TestDatadogDowntime(ModuleTestCase):
update_downtime_mock.assert_called_once_with(1212, downtime)
get_downtime_mock.assert_called_once_with(1212)
@patch("ansible_collections.community.general.plugins.modules.monitoring.datadog.datadog_downtime.DowntimesApi")
@patch("ansible_collections.community.general.plugins.modules.datadog_downtime.DowntimesApi")
def test_update_downtime_no_change(self, downtimes_api_mock):
set_module_args({
"id": 1212,
@@ -176,7 +187,8 @@ class TestDatadogDowntime(ModuleTestCase):
downtime.end = 2222
downtime.timezone = "UTC"
downtime.recurrence = DowntimeRecurrence(
rrule="rrule"
rrule="rrule",
type="rrule"
)
downtime_get = Downtime()
@@ -205,7 +217,7 @@ class TestDatadogDowntime(ModuleTestCase):
update_downtime_mock.assert_called_once_with(1212, downtime)
get_downtime_mock.assert_called_once_with(1212)
@patch("ansible_collections.community.general.plugins.modules.monitoring.datadog.datadog_downtime.DowntimesApi")
@patch("ansible_collections.community.general.plugins.modules.datadog_downtime.DowntimesApi")
def test_delete_downtime(self, downtimes_api_mock):
set_module_args({
"id": 1212,
@@ -215,12 +227,16 @@ class TestDatadogDowntime(ModuleTestCase):
})
cancel_downtime_mock = MagicMock()
get_downtime_mock = MagicMock(return_value=Downtime(id=1212))
downtimes_api_mock.return_value = MagicMock(
get_downtime=get_downtime_mock,
get_downtime=self.__downtime_with_id,
cancel_downtime=cancel_downtime_mock
)
with self.assertRaises(AnsibleExitJson) as result:
self.module.main()
self.assertTrue(result.exception.args[0]['changed'])
cancel_downtime_mock.assert_called_once_with(1212)
def __downtime_with_id(self, id):
downtime = Downtime()
downtime.id = id
return downtime

View File

@@ -23,7 +23,7 @@ from ansible.module_utils.six import StringIO
@contextmanager
def patch_keycloak_api(get_identity_provider, create_identity_provider=None, update_identity_provider=None, delete_identity_provider=None,
get_identity_provider_mappers=None, create_identity_provider_mapper=None, update_identity_provider_mapper=None,
delete_identity_provider_mapper=None):
delete_identity_provider_mapper=None, get_realm_by_id=None):
"""Mock context manager for patching the methods in PwPolicyIPAClient that contact the IPA server
Patches the `login` and `_post_json` methods
@@ -55,9 +55,11 @@ def patch_keycloak_api(get_identity_provider, create_identity_provider=None, upd
as mock_update_identity_provider_mapper:
with patch.object(obj, 'delete_identity_provider_mapper', side_effect=delete_identity_provider_mapper) \
as mock_delete_identity_provider_mapper:
yield mock_get_identity_provider, mock_create_identity_provider, mock_update_identity_provider, \
mock_delete_identity_provider, mock_get_identity_provider_mappers, mock_create_identity_provider_mapper, \
mock_update_identity_provider_mapper, mock_delete_identity_provider_mapper
with patch.object(obj, 'get_realm_by_id', side_effect=get_realm_by_id) \
as mock_get_realm_by_id:
yield mock_get_identity_provider, mock_create_identity_provider, mock_update_identity_provider, \
mock_delete_identity_provider, mock_get_identity_provider_mappers, mock_create_identity_provider_mapper, \
mock_update_identity_provider_mapper, mock_delete_identity_provider_mapper, mock_get_realm_by_id
def get_response(object_with_future_response, method, get_id_call_count):
@@ -200,6 +202,38 @@ class TestKeycloakIdentityProvider(ModuleTestCase):
"name": "last_name"
}]
]
return_value_realm_get = [
{
'id': 'realm-name',
'realm': 'realm-name',
'enabled': True,
'identityProviders': [
{
"addReadTokenRoleOnCreate": False,
"alias": "oidc-idp",
"authenticateByDefault": False,
"config": {
"authorizationUrl": "https://idp.example.com/auth",
"clientAuthMethod": "client_secret_post",
"clientId": "my-client",
"clientSecret": "secret",
"issuer": "https://idp.example.com",
"syncMode": "FORCE",
"tokenUrl": "https://idp.example.com/token",
"userInfoUrl": "https://idp.example.com/userinfo"
},
"displayName": "OpenID Connect IdP",
"enabled": True,
"firstBrokerLoginFlowAlias": "first broker login",
"internalId": "7ab437d5-f2bb-4ecc-91a8-315349454da6",
"linkOnly": False,
"providerId": "oidc",
"storeToken": False,
"trustEmail": False,
}
]
},
]
return_value_idp_created = [None]
return_value_mapper_created = [None, None]
changed = True
@@ -210,15 +244,17 @@ class TestKeycloakIdentityProvider(ModuleTestCase):
with mock_good_connection():
with patch_keycloak_api(get_identity_provider=return_value_idp_get, get_identity_provider_mappers=return_value_mappers_get,
create_identity_provider=return_value_idp_created, create_identity_provider_mapper=return_value_mapper_created) \
create_identity_provider=return_value_idp_created, create_identity_provider_mapper=return_value_mapper_created,
get_realm_by_id=return_value_realm_get) \
as (mock_get_identity_provider, mock_create_identity_provider, mock_update_identity_provider, mock_delete_identity_provider,
mock_get_identity_provider_mappers, mock_create_identity_provider_mapper, mock_update_identity_provider_mapper,
mock_delete_identity_provider_mapper):
mock_delete_identity_provider_mapper, mock_get_realm_by_id):
with self.assertRaises(AnsibleExitJson) as exec_info:
self.module.main()
self.assertEqual(len(mock_get_identity_provider.mock_calls), 2)
self.assertEqual(len(mock_get_identity_provider_mappers.mock_calls), 1)
self.assertEqual(len(mock_get_realm_by_id.mock_calls), 1)
self.assertEqual(len(mock_create_identity_provider.mock_calls), 1)
self.assertEqual(len(mock_create_identity_provider_mapper.mock_calls), 2)
@@ -444,6 +480,68 @@ class TestKeycloakIdentityProvider(ModuleTestCase):
"name": "last_name"
}]
]
return_value_realm_get = [
{
'id': 'realm-name',
'realm': 'realm-name',
'enabled': True,
'identityProviders': [
{
"addReadTokenRoleOnCreate": False,
"alias": "oidc-idp",
"authenticateByDefault": False,
"config": {
"authorizationUrl": "https://idp.example.com/auth",
"clientAuthMethod": "client_secret_post",
"clientId": "my-client",
"clientSecret": "secret",
"issuer": "https://idp.example.com",
"syncMode": "FORCE",
"tokenUrl": "https://idp.example.com/token",
"userInfoUrl": "https://idp.example.com/userinfo"
},
"displayName": "OpenID Connect IdP",
"enabled": True,
"firstBrokerLoginFlowAlias": "first broker login",
"internalId": "7ab437d5-f2bb-4ecc-91a8-315349454da6",
"linkOnly": False,
"providerId": "oidc",
"storeToken": False,
"trustEmail": False,
}
]
},
{
'id': 'realm-name',
'realm': 'realm-name',
'enabled': True,
'identityProviders': [
{
"addReadTokenRoleOnCreate": False,
"alias": "oidc-idp",
"authenticateByDefault": False,
"config": {
"authorizationUrl": "https://idp.example.com/auth",
"clientAuthMethod": "client_secret_post",
"clientId": "my-client",
"clientSecret": "secret",
"issuer": "https://idp.example.com",
"syncMode": "FORCE",
"tokenUrl": "https://idp.example.com/token",
"userInfoUrl": "https://idp.example.com/userinfo"
},
"displayName": "OpenID Connect IdP",
"enabled": True,
"firstBrokerLoginFlowAlias": "first broker login",
"internalId": "7ab437d5-f2bb-4ecc-91a8-315349454da6",
"linkOnly": False,
"providerId": "oidc",
"storeToken": False,
"trustEmail": False,
}
]
},
]
return_value_idp_updated = [None]
return_value_mapper_updated = [None]
return_value_mapper_created = [None]
@@ -456,15 +554,16 @@ class TestKeycloakIdentityProvider(ModuleTestCase):
with mock_good_connection():
with patch_keycloak_api(get_identity_provider=return_value_idp_get, get_identity_provider_mappers=return_value_mappers_get,
update_identity_provider=return_value_idp_updated, update_identity_provider_mapper=return_value_mapper_updated,
create_identity_provider_mapper=return_value_mapper_created) \
create_identity_provider_mapper=return_value_mapper_created, get_realm_by_id=return_value_realm_get) \
as (mock_get_identity_provider, mock_create_identity_provider, mock_update_identity_provider, mock_delete_identity_provider,
mock_get_identity_provider_mappers, mock_create_identity_provider_mapper, mock_update_identity_provider_mapper,
mock_delete_identity_provider_mapper):
mock_delete_identity_provider_mapper, mock_get_realm_by_id):
with self.assertRaises(AnsibleExitJson) as exec_info:
self.module.main()
self.assertEqual(len(mock_get_identity_provider.mock_calls), 2)
self.assertEqual(len(mock_get_identity_provider_mappers.mock_calls), 5)
self.assertEqual(len(mock_get_realm_by_id.mock_calls), 2)
self.assertEqual(len(mock_update_identity_provider.mock_calls), 1)
self.assertEqual(len(mock_update_identity_provider_mapper.mock_calls), 1)
self.assertEqual(len(mock_create_identity_provider_mapper.mock_calls), 1)
@@ -472,6 +571,156 @@ class TestKeycloakIdentityProvider(ModuleTestCase):
# Verify that the module's changed status matches what is expected
self.assertIs(exec_info.exception.args[0]['changed'], changed)
def test_no_change_when_present(self):
"""Update existing identity provider"""
module_args = {
'auth_keycloak_url': 'http://keycloak.url/auth',
'auth_password': 'admin',
'auth_realm': 'master',
'auth_username': 'admin',
'auth_client_id': 'admin-cli',
"addReadTokenRoleOnCreate": False,
"alias": "oidc-idp",
"authenticateByDefault": False,
"config": {
"authorizationUrl": "https://idp.example.com/auth",
"clientAuthMethod": "client_secret_post",
"clientId": "my-client",
"clientSecret": "secret",
"issuer": "https://idp.example.com",
"syncMode": "FORCE",
"tokenUrl": "https://idp.example.com/token",
"userInfoUrl": "https://idp.example.com/userinfo"
},
"displayName": "OpenID Connect IdP changeme",
"enabled": True,
"firstBrokerLoginFlowAlias": "first broker login",
"linkOnly": False,
"providerId": "oidc",
"storeToken": False,
"trustEmail": False,
'mappers': [{
'name': "username",
'identityProviderAlias': "oidc-idp",
'identityProviderMapper': "oidc-user-attribute-idp-mapper",
'config': {
'claim': "username",
'user.attribute': "username",
'syncMode': "INHERIT",
}
}]
}
return_value_idp_get = [
{
"addReadTokenRoleOnCreate": False,
"alias": "oidc-idp",
"authenticateByDefault": False,
"config": {
"authorizationUrl": "https://idp.example.com/auth",
"clientAuthMethod": "client_secret_post",
"clientId": "my-client",
"clientSecret": "**********",
"issuer": "https://idp.example.com",
"syncMode": "FORCE",
"tokenUrl": "https://idp.example.com/token",
"userInfoUrl": "https://idp.example.com/userinfo"
},
"displayName": "OpenID Connect IdP changeme",
"enabled": True,
"firstBrokerLoginFlowAlias": "first broker login",
"internalId": "7ab437d5-f2bb-4ecc-91a8-315349454da6",
"linkOnly": False,
"providerId": "oidc",
"storeToken": False,
"trustEmail": False,
},
]
return_value_mappers_get = [
[{
'config': {
'claim': "username",
'syncMode': "INHERIT",
'user.attribute': "username"
},
"id": "616f11ba-b9ae-42ae-bd1b-bc618741c10b",
'identityProviderAlias': "oidc-idp",
'identityProviderMapper': "oidc-user-attribute-idp-mapper",
'name': "username"
}],
[{
'config': {
'claim': "username",
'syncMode': "INHERIT",
'user.attribute': "username"
},
"id": "616f11ba-b9ae-42ae-bd1b-bc618741c10b",
'identityProviderAlias': "oidc-idp",
'identityProviderMapper': "oidc-user-attribute-idp-mapper",
'name': "username"
}]
]
return_value_realm_get = [
{
'id': 'realm-name',
'realm': 'realm-name',
'enabled': True,
'identityProviders': [
{
"addReadTokenRoleOnCreate": False,
"alias": "oidc-idp",
"authenticateByDefault": False,
"config": {
"authorizationUrl": "https://idp.example.com/auth",
"clientAuthMethod": "client_secret_post",
"clientId": "my-client",
"clientSecret": "secret",
"issuer": "https://idp.example.com",
"syncMode": "FORCE",
"tokenUrl": "https://idp.example.com/token",
"userInfoUrl": "https://idp.example.com/userinfo"
},
"displayName": "OpenID Connect IdP",
"enabled": True,
"firstBrokerLoginFlowAlias": "first broker login",
"internalId": "7ab437d5-f2bb-4ecc-91a8-315349454da6",
"linkOnly": False,
"providerId": "oidc",
"storeToken": False,
"trustEmail": False,
}
]
}
]
return_value_idp_updated = [None]
return_value_mapper_updated = [None]
return_value_mapper_created = [None]
changed = False
set_module_args(module_args)
# Run the module
with mock_good_connection():
with patch_keycloak_api(get_identity_provider=return_value_idp_get, get_identity_provider_mappers=return_value_mappers_get,
update_identity_provider=return_value_idp_updated, update_identity_provider_mapper=return_value_mapper_updated,
create_identity_provider_mapper=return_value_mapper_created, get_realm_by_id=return_value_realm_get) \
as (mock_get_identity_provider, mock_create_identity_provider, mock_update_identity_provider, mock_delete_identity_provider,
mock_get_identity_provider_mappers, mock_create_identity_provider_mapper, mock_update_identity_provider_mapper,
mock_delete_identity_provider_mapper, mock_get_realm_by_id):
with self.assertRaises(AnsibleExitJson) as exec_info:
self.module.main()
self.assertEqual(len(mock_get_identity_provider.mock_calls), 1)
self.assertEqual(len(mock_get_identity_provider_mappers.mock_calls), 2)
self.assertEqual(len(mock_get_realm_by_id.mock_calls), 1)
self.assertEqual(len(mock_update_identity_provider.mock_calls), 0)
self.assertEqual(len(mock_update_identity_provider_mapper.mock_calls), 0)
self.assertEqual(len(mock_create_identity_provider_mapper.mock_calls), 0)
# Verify that the module's changed status matches what is expected
self.assertIs(exec_info.exception.args[0]['changed'], changed)
def test_delete_when_absent(self):
"""Remove an absent identity provider"""
@@ -497,7 +746,7 @@ class TestKeycloakIdentityProvider(ModuleTestCase):
with patch_keycloak_api(get_identity_provider=return_value_idp_get) \
as (mock_get_identity_provider, mock_create_identity_provider, mock_update_identity_provider, mock_delete_identity_provider,
mock_get_identity_provider_mappers, mock_create_identity_provider_mapper, mock_update_identity_provider_mapper,
mock_delete_identity_provider_mapper):
mock_delete_identity_provider_mapper, mock_get_realm_by_id):
with self.assertRaises(AnsibleExitJson) as exec_info:
self.module.main()
@@ -560,6 +809,38 @@ class TestKeycloakIdentityProvider(ModuleTestCase):
"name": "email"
}]
]
return_value_realm_get = [
{
'id': 'realm-name',
'realm': 'realm-name',
'enabled': True,
'identityProviders': [
{
"alias": "oidc",
"displayName": "",
"internalId": "2bca4192-e816-4beb-bcba-190164eb55b8",
"providerId": "oidc",
"enabled": True,
"updateProfileFirstLoginMode": "on",
"trustEmail": False,
"storeToken": False,
"addReadTokenRoleOnCreate": False,
"authenticateByDefault": False,
"linkOnly": False,
"config": {
"validateSignature": "false",
"pkceEnabled": "false",
"tokenUrl": "https://localhost:8000",
"clientId": "asdf",
"authorizationUrl": "https://localhost:8000",
"clientAuthMethod": "client_secret_post",
"clientSecret": "real_secret",
"guiOrder": "0"
}
},
]
},
]
return_value_idp_deleted = [None]
changed = True
@@ -569,15 +850,16 @@ class TestKeycloakIdentityProvider(ModuleTestCase):
with mock_good_connection():
with patch_keycloak_api(get_identity_provider=return_value_idp_get, get_identity_provider_mappers=return_value_mappers_get,
delete_identity_provider=return_value_idp_deleted) \
delete_identity_provider=return_value_idp_deleted, get_realm_by_id=return_value_realm_get) \
as (mock_get_identity_provider, mock_create_identity_provider, mock_update_identity_provider, mock_delete_identity_provider,
mock_get_identity_provider_mappers, mock_create_identity_provider_mapper, mock_update_identity_provider_mapper,
mock_delete_identity_provider_mapper):
mock_delete_identity_provider_mapper, mock_get_realm_by_id):
with self.assertRaises(AnsibleExitJson) as exec_info:
self.module.main()
self.assertEqual(len(mock_get_identity_provider.mock_calls), 1)
self.assertEqual(len(mock_get_identity_provider_mappers.mock_calls), 1)
self.assertEqual(len(mock_get_realm_by_id.mock_calls), 1)
self.assertEqual(len(mock_delete_identity_provider.mock_calls), 1)
# Verify that the module's changed status matches what is expected

View File

@@ -0,0 +1,380 @@
# -*- coding: utf-8 -*-
# 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 absolute_import, division, print_function
__metaclass__ = type
from contextlib import contextmanager
from ansible_collections.community.general.tests.unit.compat import unittest
from ansible_collections.community.general.tests.unit.compat.mock import patch
from ansible_collections.community.general.tests.unit.plugins.modules.utils import AnsibleExitJson, ModuleTestCase, set_module_args
from ansible_collections.community.general.plugins.modules import keycloak_realm_key
from itertools import count
from ansible.module_utils.six import StringIO
@contextmanager
def patch_keycloak_api(get_components=None, get_component=None, create_component=None, update_component=None, delete_component=None):
"""Mock context manager for patching the methods in KeycloakAPI
"""
obj = keycloak_realm_key.KeycloakAPI
with patch.object(obj, 'get_components', side_effect=get_components) \
as mock_get_components:
with patch.object(obj, 'get_component', side_effect=get_component) \
as mock_get_component:
with patch.object(obj, 'create_component', side_effect=create_component) \
as mock_create_component:
with patch.object(obj, 'update_component', side_effect=update_component) \
as mock_update_component:
with patch.object(obj, 'delete_component', side_effect=delete_component) \
as mock_delete_component:
yield mock_get_components, mock_get_component, mock_create_component, mock_update_component, mock_delete_component
def get_response(object_with_future_response, method, get_id_call_count):
if callable(object_with_future_response):
return object_with_future_response()
if isinstance(object_with_future_response, dict):
return get_response(
object_with_future_response[method], method, get_id_call_count)
if isinstance(object_with_future_response, list):
call_number = next(get_id_call_count)
return get_response(
object_with_future_response[call_number], method, get_id_call_count)
return object_with_future_response
def build_mocked_request(get_id_user_count, response_dict):
def _mocked_requests(*args, **kwargs):
url = args[0]
method = kwargs['method']
future_response = response_dict.get(url, None)
return get_response(future_response, method, get_id_user_count)
return _mocked_requests
def create_wrapper(text_as_string):
"""Allow to mock many times a call to one address.
Without this function, the StringIO is empty for the second call.
"""
def _create_wrapper():
return StringIO(text_as_string)
return _create_wrapper
def mock_good_connection():
token_response = {
'http://keycloak.url/auth/realms/master/protocol/openid-connect/token': create_wrapper('{"access_token": "alongtoken"}'), }
return patch(
'ansible_collections.community.general.plugins.module_utils.identity.keycloak.keycloak.open_url',
side_effect=build_mocked_request(count(), token_response),
autospec=True
)
class TestKeycloakRealmKeys(ModuleTestCase):
def setUp(self):
super(TestKeycloakRealmKeys, self).setUp()
self.module = keycloak_realm_key
def test_create_when_absent(self):
"""Add a new realm key"""
module_args = {
'auth_keycloak_url': 'http://keycloak.url/auth',
'auth_realm': 'master',
'auth_username': 'admin',
'auth_password': 'admin',
'parent_id': 'realm-name',
'name': 'testkey',
'state': 'present',
'provider_id': 'rsa',
'config': {
'priority': 0,
'enabled': True,
'private_key': 'privatekey',
'algorithm': 'RS256',
'certificate': 'foo',
},
}
return_value_component_create = [
{
"id": "ebb7d999-60cc-4dfe-ab79-48f7bbd9d4d9",
"name": "testkey",
"providerId": "rsa",
"parentId": "90c8fef9-15f8-4d5b-8b22-44e2e1cdcd09",
"config": {
"privateKey": [
"**********"
],
"certificate": [
"foo"
],
"active": [
"true"
],
"priority": [
"122"
],
"enabled": [
"true"
],
"algorithm": [
"RS256"
]
}
}
]
# get before_comp, get default_mapper, get after_mapper
return_value_components_get = [
[], [], []
]
changed = True
set_module_args(module_args)
# Run the module
with mock_good_connection():
with patch_keycloak_api(get_components=return_value_components_get, create_component=return_value_component_create) \
as (mock_get_components, mock_get_component, mock_create_component, mock_update_component, mock_delete_component):
with self.assertRaises(AnsibleExitJson) as exec_info:
self.module.main()
self.assertEqual(len(mock_get_components.mock_calls), 1)
self.assertEqual(len(mock_get_component.mock_calls), 0)
self.assertEqual(len(mock_create_component.mock_calls), 1)
self.assertEqual(len(mock_update_component.mock_calls), 0)
self.assertEqual(len(mock_delete_component.mock_calls), 0)
# must not contain parent_id
mock_create_component.assert_called_once_with({
'name': 'testkey',
'providerId': 'rsa',
'providerType': 'org.keycloak.keys.KeyProvider',
'config': {
'priority': ['0'],
'enabled': ['true'],
'privateKey': ['privatekey'],
'algorithm': ['RS256'],
'certificate': ['foo'],
'active': ['true'],
},
}, 'realm-name')
# Verify that the module's changed status matches what is expected
self.assertIs(exec_info.exception.args[0]['changed'], changed)
def test_create_when_present(self):
"""Update existing realm key"""
module_args = {
'auth_keycloak_url': 'http://keycloak.url/auth',
'auth_realm': 'master',
'auth_username': 'admin',
'auth_password': 'admin',
'parent_id': 'realm-name',
'name': 'testkey',
'state': 'present',
'provider_id': 'rsa',
'config': {
'priority': 0,
'enabled': True,
'private_key': 'privatekey',
'algorithm': 'RS256',
'certificate': 'foo',
},
}
return_value_components_get = [
[
{
"id": "c1a957aa-3df0-4f70-9418-44202bf4ae1f",
"name": "testkey",
"providerId": "rsa",
"providerType": "org.keycloak.keys.KeyProvider",
"parentId": "90c8fef9-15f8-4d5b-8b22-44e2e1cdcd09",
"config": {
"privateKey": [
"**********"
],
"certificate": [
"foo"
],
"active": [
"true"
],
"priority": [
"122"
],
"enabled": [
"true"
],
"algorithm": [
"RS256"
]
}
},
],
[],
[]
]
return_value_component_update = [
None
]
changed = True
set_module_args(module_args)
# Run the module
with mock_good_connection():
with patch_keycloak_api(get_components=return_value_components_get,
update_component=return_value_component_update) \
as (mock_get_components, mock_get_component, mock_create_component, mock_update_component, mock_delete_component):
with self.assertRaises(AnsibleExitJson) as exec_info:
self.module.main()
self.assertEqual(len(mock_get_components.mock_calls), 1)
self.assertEqual(len(mock_get_component.mock_calls), 0)
self.assertEqual(len(mock_create_component.mock_calls), 0)
self.assertEqual(len(mock_update_component.mock_calls), 1)
self.assertEqual(len(mock_delete_component.mock_calls), 0)
# Verify that the module's changed status matches what is expected
self.assertIs(exec_info.exception.args[0]['changed'], changed)
def test_delete_when_absent(self):
"""Remove an absent realm key"""
module_args = {
'auth_keycloak_url': 'http://keycloak.url/auth',
'auth_realm': 'master',
'auth_username': 'admin',
'auth_password': 'admin',
'parent_id': 'realm-name',
'name': 'testkey',
'state': 'absent',
'provider_id': 'rsa',
'config': {
'priority': 0,
'enabled': True,
'private_key': 'privatekey',
'algorithm': 'RS256',
'certificate': 'foo',
},
}
return_value_components_get = [
[]
]
changed = False
set_module_args(module_args)
# Run the module
with mock_good_connection():
with patch_keycloak_api(get_components=return_value_components_get) \
as (mock_get_components, mock_get_component, mock_create_component, mock_update_component, mock_delete_component):
with self.assertRaises(AnsibleExitJson) as exec_info:
self.module.main()
self.assertEqual(len(mock_get_components.mock_calls), 1)
self.assertEqual(len(mock_get_component.mock_calls), 0)
self.assertEqual(len(mock_create_component.mock_calls), 0)
self.assertEqual(len(mock_update_component.mock_calls), 0)
self.assertEqual(len(mock_delete_component.mock_calls), 0)
# Verify that the module's changed status matches what is expected
self.assertIs(exec_info.exception.args[0]['changed'], changed)
def test_delete_when_present(self):
"""Remove an existing realm key"""
module_args = {
'auth_keycloak_url': 'http://keycloak.url/auth',
'auth_realm': 'master',
'auth_username': 'admin',
'auth_password': 'admin',
'parent_id': 'realm-name',
'name': 'testkey',
'state': 'absent',
'provider_id': 'rsa',
'config': {
'priority': 0,
'enabled': True,
'private_key': 'privatekey',
'algorithm': 'RS256',
'certificate': 'foo',
},
}
return_value_components_get = [
[
{
"id": "c1a957aa-3df0-4f70-9418-44202bf4ae1f",
"name": "testkey",
"providerId": "rsa",
"providerType": "org.keycloak.keys.KeyProvider",
"parentId": "90c8fef9-15f8-4d5b-8b22-44e2e1cdcd09",
"config": {
"privateKey": [
"**********"
],
"certificate": [
"foo"
],
"active": [
"true"
],
"priority": [
"122"
],
"enabled": [
"true"
],
"algorithm": [
"RS256"
]
}
},
],
[],
[]
]
return_value_component_delete = [
None
]
changed = True
set_module_args(module_args)
# Run the module
with mock_good_connection():
with patch_keycloak_api(get_components=return_value_components_get, delete_component=return_value_component_delete) \
as (mock_get_components, mock_get_component, mock_create_component, mock_update_component, mock_delete_component):
with self.assertRaises(AnsibleExitJson) as exec_info:
self.module.main()
self.assertEqual(len(mock_get_components.mock_calls), 1)
self.assertEqual(len(mock_get_component.mock_calls), 0)
self.assertEqual(len(mock_create_component.mock_calls), 0)
self.assertEqual(len(mock_update_component.mock_calls), 0)
self.assertEqual(len(mock_delete_component.mock_calls), 1)
# Verify that the module's changed status matches what is expected
self.assertIs(exec_info.exception.args[0]['changed'], changed)
if __name__ == '__main__':
unittest.main()

View File

@@ -144,8 +144,9 @@ class TestKeycloakUserFederation(ModuleTestCase):
}
}
]
# get before_comp, get default_mapper, get after_mapper
return_value_components_get = [
[], []
[], [], []
]
changed = True
@@ -159,7 +160,7 @@ class TestKeycloakUserFederation(ModuleTestCase):
with self.assertRaises(AnsibleExitJson) as exec_info:
self.module.main()
self.assertEqual(len(mock_get_components.mock_calls), 1)
self.assertEqual(len(mock_get_components.mock_calls), 3)
self.assertEqual(len(mock_get_component.mock_calls), 0)
self.assertEqual(len(mock_create_component.mock_calls), 1)
self.assertEqual(len(mock_update_component.mock_calls), 0)
@@ -228,6 +229,7 @@ class TestKeycloakUserFederation(ModuleTestCase):
}
}
],
[],
[]
]
return_value_component_get = [
@@ -281,7 +283,7 @@ class TestKeycloakUserFederation(ModuleTestCase):
with self.assertRaises(AnsibleExitJson) as exec_info:
self.module.main()
self.assertEqual(len(mock_get_components.mock_calls), 2)
self.assertEqual(len(mock_get_components.mock_calls), 3)
self.assertEqual(len(mock_get_component.mock_calls), 1)
self.assertEqual(len(mock_create_component.mock_calls), 0)
self.assertEqual(len(mock_update_component.mock_calls), 1)
@@ -344,7 +346,47 @@ class TestKeycloakUserFederation(ModuleTestCase):
]
}
return_value_components_get = [
[], []
[],
# exemplary default mapper created by keylocak
[
{
"config": {
"always.read.value.from.ldap": "false",
"is.mandatory.in.ldap": "false",
"ldap.attribute": "mail",
"read.only": "true",
"user.model.attribute": "email"
},
"id": "77e1763f-c51a-4286-bade-75577d64803c",
"name": "email",
"parentId": "e5f48aa3-b56b-4983-a8ad-2c7b8b5e77cb",
"providerId": "user-attribute-ldap-mapper",
"providerType": "org.keycloak.storage.ldap.mappers.LDAPStorageMapper"
},
],
[
{
"id": "2dfadafd-8b34-495f-a98b-153e71a22311",
"name": "full name",
"providerId": "full-name-ldap-mapper",
"providerType": "org.keycloak.storage.ldap.mappers.LDAPStorageMapper",
"parentId": "eb691537-b73c-4cd8-b481-6031c26499d8",
"config": {
"ldap.full.name.attribute": [
"cn"
],
"read.only": [
"true"
],
"write.only": [
"false"
]
}
}
]
]
return_value_component_delete = [
None
]
return_value_component_create = [
{
@@ -462,11 +504,11 @@ class TestKeycloakUserFederation(ModuleTestCase):
with self.assertRaises(AnsibleExitJson) as exec_info:
self.module.main()
self.assertEqual(len(mock_get_components.mock_calls), 2)
self.assertEqual(len(mock_get_components.mock_calls), 3)
self.assertEqual(len(mock_get_component.mock_calls), 0)
self.assertEqual(len(mock_create_component.mock_calls), 2)
self.assertEqual(len(mock_update_component.mock_calls), 0)
self.assertEqual(len(mock_delete_component.mock_calls), 0)
self.assertEqual(len(mock_delete_component.mock_calls), 1)
# Verify that the module's changed status matches what is expected
self.assertIs(exec_info.exception.args[0]['changed'], changed)