Compare commits

..

75 Commits

Author SHA1 Message Date
Felix Fontein
f88b8c85d7 Release 12.4.0. 2026-02-23 17:50:05 +01:00
patchback[bot]
6385fbe038 [PR #11534/e118b23b backport][stable-12] Simplify and extend from_ini tests (#11535)
Simplify and extend from_ini tests (#11534)

Simplify and extend from_ini tests.

(cherry picked from commit e118b23ba0)

Co-authored-by: Felix Fontein <felix@fontein.de>
2026-02-23 06:30:35 +01:00
patchback[bot]
4b6cd41512 [PR #11462/ce7cb4e9 backport][stable-12] New module icinga2_downtime (#11532)
New module icinga2_downtime (#11462)

* feat: Icinga 2 downtime module added allowing to schedule and remove downtimes through its REST API.



* ensure compatibility with ModuleTestCase

feat: errors raised from MH now contain the changed flag
ref: move module exit out of the decorated run method



* revised module

ref: module refactored using StateModuleHelper now
ref: suggested changes by reviewer added



* revert change regarding changed flag in MH



* refactoring and set changed flag explicitly on error



* Check whether there was a state change on module failure removed.



* ref: test cases migrated to the new feature that allows passing through exceptions



* Update plugins/module_utils/icinga2.py



* Update plugins/module_utils/icinga2.py



* Update plugins/modules/icinga2_downtime.py



* ref: make module helper private



* fix: ensure that all non-null values are added to the request otherwise a `false` value is dropped



* ref: module description extended with the note that check mode is not supported



* Update plugins/modules/icinga2_downtime.py



* fix: documentation updated



* ref: documentation updated
ref: doc fragment added



* Update plugins/doc_fragments/icinga2_api.py



* ref: doc fragment renamed to `_icinga2_api.py`



* ref: maintainer to doc fragment in BOTMETA.yml added



* Update plugins/modules/icinga2_downtime.py



* Update plugins/modules/icinga2_downtime.py



* Update plugins/modules/icinga2_downtime.py



---------





(cherry picked from commit ce7cb4e914)

Signed-off-by: Fiehe Christoph  <c.fiehe@eurodata.de>
Co-authored-by: Christoph Fiehe <cfiehe@users.noreply.github.com>
Co-authored-by: Fiehe Christoph <c.fiehe@eurodata.de>
Co-authored-by: Felix Fontein <felix@fontein.de>
Co-authored-by: Alexei Znamensky <103110+russoz@users.noreply.github.com>
2026-02-23 06:17:51 +01:00
patchback[bot]
8c429ac69d [PR #11485/cb91ff42 backport][stable-12] Fix: avoid deprecated callback. (#11531)
Fix: avoid deprecated callback. (#11485)

* Fix: avoid deprecated callback.

* addition of changelog

* Improve changelog fragment.

---------



(cherry picked from commit cb91ff424f)

Co-authored-by: Tom Uijldert <155556120+TomUijldert@users.noreply.github.com>
Co-authored-by: tom uijldert <tom.uijldert@gmail.com>
Co-authored-by: Felix Fontein <felix@fontein.de>
2026-02-23 06:17:28 +01:00
patchback[bot]
30eb35cb95 [PR #11512/aec0e61b backport][stable-12] adds parameter delimiters to from_ini filter (#11533)
adds parameter delimiters to from_ini filter (#11512)

* adds parameter delimiters to from_ini filter

fixes issue #11506

* adds changelog fragment

* fixes pylint dangerous-default-value / W0102

* does not assume default delimiters

let that be decided in the super class

* Update plugins/filter/from_ini.py

verbose description



* Update changelogs/fragments/11512-from_ini-delimiters.yaml



* adds input validation

* adss check for delimiters not None

* adds missing import

* removes the negation

* adds suggestions from russoz

* adds ruff format suggestion

---------


(cherry picked from commit aec0e61ba1)

Co-authored-by: Robert Sander <github@gurubert.de>
Co-authored-by: Felix Fontein <felix@fontein.de>
2026-02-23 06:17:00 +01:00
Felix Fontein
33f3e7172b Prepare 12.4.0. 2026-02-22 16:39:25 +01:00
patchback[bot]
c2751dd6f5 [PR #11513/0e184d24 backport][stable-12] add support for localizationTexts in keycloak_realm.py (#11530)
add support for localizationTexts in keycloak_realm.py (#11513)

* add support for localizationTexts in keycloak_realm.py

* add changelog fragment

* change version added to next minor release

* Update changelogs/fragments/11513-keycloak-realm-localizationTexts-support.yml



* Update plugins/modules/keycloak_realm.py



---------


(cherry picked from commit 0e184d24cf)

Co-authored-by: nwintering <33374766+nwintering@users.noreply.github.com>
Co-authored-by: Alexei Znamensky <103110+russoz@users.noreply.github.com>
2026-02-21 23:07:08 +01:00
patchback[bot]
d3dd685ad4 [PR #11515/7cd75945 backport][stable-12] #11502 Fix mapping of config of keycloak_user_federation (#11529)
#11502 Fix mapping of config of keycloak_user_federation (#11515)

* #11502 Fix mapping of config

Fix mapping of config

Fix diff for mappers

* Fix formatting with nox

* Update changelogs/fragments/11502-keycloak-config-mapper.yaml



* Remove duplicate comment
https://github.com/ansible-collections/community.general/pull/11515#discussion_r2821444756

---------


(cherry picked from commit 7cd75945b2)

Co-authored-by: mixman68 <greg.djg13@gmail.com>
Co-authored-by: Felix Fontein <felix@fontein.de>
2026-02-21 12:11:19 +01:00
patchback[bot]
696b6e737a [PR #11523/1ae058db backport][stable-12] reduce collection build time with build_ignore (#11528)
reduce collection build time with build_ignore (#11523)

* reduce build time with build_ignore



* just ignore .nox



---------


(cherry picked from commit 1ae058db63)

Signed-off-by: Thomas Sjögren <konstruktoid@users.noreply.github.com>
Co-authored-by: Thomas Sjögren <konstruktoid@users.noreply.github.com>
2026-02-21 11:43:25 +01:00
patchback[bot]
45d16053ee [PR #10306/38f93c80 backport][stable-12] New Callback plugin: loganalytics_ingestion adding Azure Log Analytics Ingestion (#11527)
New Callback plugin: `loganalytics_ingestion` adding Azure Log Analytics Ingestion (#10306)

* Add Azure Log Analytics Ingestion API plugin

The Ingestion API allows sending data to a Log Analytics workspace in
Azure Monitor.

* Fix LogAnalytics Ingestion shebang

* Fix Log Analytics Ingestion pep8 tests

* Fix Log Analytics Ingestion pylint tests

* Fix Log Analytics Ingestion import tests

* Fix Log Analytics Ingestion pylint test

* Add Log Analytics Ingestion auth timeout

Previous behavior was to use the 'request' module's default timeout;
this makes auth timeout value consistent with the task submission
timeout value.

* Display Log Analytics Ingestion event data as JSON

Previous behavior was to display the data as a Python dictionary.
The new behavior makes it easier to generate a sample JSON file in order
to import into Azure when creating the table.

* Add Azure Log Analytics Ingestion timeout param

This parameter controls how long the plugin will wait for an HTTP response
from the Azure Log Analytics API before considering the request a failure.
Previous behavior was hardcoded to 2 seconds.

* Fix Azure Log Ingestion unit test

The class instantiation was missing an additional argument that was added
in a previous patch; add it.  Converting to JSON also caused the Mock
TaskResult object to throw a serialization error; override the function
for JSON conversion to just return bogus data instead.

* Fix loganalytics_ingestion linter errors

* Fix LogAnalytics Ingestion env vars

Prefix the LogAnalytics Ingestion plugin's environment variable names
with 'ANSIBLE_' in order to align with plugin best practices.

* Remove LogAnalytics 'requests' dep from docs

The LogAnalytics callback plugin does not actually require 'requests',
so remove it from the documented dependencies.

* Refactor LogAnalytics Ingestion to use URL utils

This replaces the previous behavior of depending on the external
'requests' library.

* Simplify LogAnalytics Ingestion token valid check



* Remove LogAnalytics Ingestion extra arg validation

Argument validation should be handled by ansible-core, so remove the
extra argument validation in the plugin itself.

* Update LogAnalytics Ingestion version added

* Remove LogAnalytics Ingestion coding marker

The marker is no longer needed as Python2 is no longer supported.

* Fix some LogAnalytics Ingestion grammar errors

* Refactor LogAnalytics Ingestion plugin messages

Consistently use "plugin" instead of module, and refer to the module by
its FQCN instead of its prose name.

* Remove LogAnalytics Ingestion extra logic

A few unused vars were being set; stop setting them.

* Fix LogAnalytics Ingestion nox sanity tests

* Fix LogAnalytics Ingestion unit tests

The refactor to move away from the 'requests' dependency to use
module_utils broke the plugin's unit tests; re-write the plugin's unit
tests for module_utils.

* Add nox formatting to LogAnalytics Ingestion

* Fix Log Analytics Ingestion urllib import

Remove the compatibility import via 'six' for 'urllib' since Python 2
support is no longer supported.

* Bump LogAnalytics Ingestion plugin version added

* Remove LogAnalytics Ingestion required: false docs

Required being false is the default, so no need to explicitly add it.

* Simplify LogAnalytics Ingestion role name logic

* Clean LogAnalytics Ingestion redundant comments

* Clean LogAnalytics Ingestion unit test code

Rename all Mock objects to use snake_case and consistently use '_mock'
as a suffix instead of sometimes using it as a prefix and sometimes
using it as a suffix.

* Refactor LogAnalytics Ingestion unit tests

Move all of the tests outside of the 'setUp' method.

* Refactor LogAnalytics Ingestion test

Add a test to validate that part of the contents sent match what was
supposed to be sent.

* Refactor LogAnalytics Ingestion test

Make the names consistent again.

* Add LogAnalytics Ingestion sample data docs

* Apply suggestions from code review



---------


(cherry picked from commit 38f93c80f1)

Co-authored-by: wtcline-intc <wade.cline@intel.com>
Co-authored-by: Felix Fontein <felix@fontein.de>
2026-02-21 11:43:16 +01:00
patchback[bot]
1d4fd21702 [PR #11471/34938ca1 backport][stable-12] keycloak_user_rolemapping: handle None response for client role lookup (#11522)
keycloak_user_rolemapping: handle None response for client role lookup (#11471)

* fix(keycloak_user_rolemapping): handle None response for client role lookup

When adding a client role to a user who has no existing roles for that
client, get_client_user_rolemapping_by_id() returns None. The existing
code indexed directly into the result causing a TypeError. Add the same
None check that already existed for realm roles since PR #11256.

Fixes #10960

* fix(tests): use dict format for task vars in keycloak_user_rolemapping tests

Task-level vars requires a YAML mapping, not a sequence. The leading
dash (- roles:) produced a list instead of a dict, which ansible-core
2.20 rejects with "Vars in a Task must be specified as a dictionary".

* Update changelogs/fragments/keycloak-user-rolemapping-client-none-check.yml



---------


(cherry picked from commit 34938ca1ef)

Co-authored-by: Ivan Kokalovic <67540157+koke1997@users.noreply.github.com>
Co-authored-by: Felix Fontein <felix@fontein.de>
2026-02-18 20:50:15 +01:00
patchback[bot]
bfcdeeab91 [PR #11468/80d21f2a backport][stable-12] keycloak_realm_key: add full support for all Keycloak key providers (#11519)
keycloak_realm_key: add full support for all Keycloak key providers (#11468)

* feat(keycloak_realm_key): add support for auto-generated key providers

Add support for Keycloak's auto-generated key providers where Keycloak
manages the key material automatically:

- rsa-generated: Auto-generates RSA signing keys
- hmac-generated: Auto-generates HMAC signing keys
- aes-generated: Auto-generates AES encryption keys
- ecdsa-generated: Auto-generates ECDSA signing keys

New algorithms:
- HMAC: HS256, HS384, HS512
- ECDSA: ES256, ES384, ES512
- AES: AES (no algorithm parameter needed)

New config options:
- secret_size: For HMAC/AES providers (key size in bytes)
- key_size: For RSA-generated provider (key size in bits)
- elliptic_curve: For ECDSA-generated provider (P-256, P-384, P-521)

Changes:
- Make private_key/certificate optional (only required for rsa/rsa-enc)
- Add provider-algorithm validation with clear error messages
- Fix KeyError when managing default realm keys (issue #11459)
- Maintain backward compatibility: RS256 default works for rsa/rsa-generated

Fixes: #11459

* fix: address sanity test failures

- Add 'default: RS256' to algorithm documentation to match spec
- Add no_log=True to secret_size parameter per sanity check

* feat(keycloak_realm_key): extend support for all Keycloak key providers

Add support for remaining auto-generated key providers:
- rsa-enc-generated (RSA encryption keys with RSA1_5, RSA-OAEP, RSA-OAEP-256)
- ecdh-generated (ECDH key exchange with ECDH_ES, ECDH_ES_A128KW/A192KW/A256KW)
- eddsa-generated (EdDSA signing with Ed25519, Ed448 curves)

Changes:
- Add provider-specific elliptic curve config key mapping
  (ecdsaEllipticCurveKey, ecdhEllipticCurveKey, eddsaEllipticCurveKey)
- Add PROVIDERS_WITHOUT_ALGORITHM constant for providers that don't need algorithm
- Add elliptic curve validation per provider type
- Update documentation with all supported algorithms and examples
- Add comprehensive integration tests for all new providers

This completes full coverage of all Keycloak key provider types.

* style: apply ruff formatting

* feat(keycloak_realm_key): add java-keystore provider and update_password

Add support for java-keystore provider to import keys from Java
Keystore (JKS or PKCS12) files on the Keycloak server filesystem.

Add update_password parameter to control password handling for
java-keystore provider:
- always (default): Always send passwords to Keycloak
- on_create: Only send passwords when creating, preserve existing
  passwords when updating (enables idempotent playbooks)

The on_create mode sends the masked value ("**********") that Keycloak
recognizes as "preserve existing password", matching the behavior when
re-importing an exported realm.

Replace password_checksum with update_password - the checksum approach
was complex and error-prone. The update_password parameter is simpler
and follows the pattern used by ansible.builtin.user module.

Also adds key_info return value containing kid, certificate fingerprint,
status, and expiration for java-keystore keys.

* address PR review feedback

- Remove no_log=True from secret_size (just an int, not sensitive)
- Add version_added: 12.4.0 to new parameters and return values
- Remove "Added in community.general 12.4.0" from description text
- Consolidate changelog entries into 4 focused entries
- Remove bugfix from changelog (now in separate PR #11470)

* address review feedback from russoz and felixfontein

- remove docstrings from module-local helpers
- remove line-by-line comments and unnecessary null guard
- use specific exceptions instead of bare except Exception
- use module.params["key"] instead of .get("key")
- consolidate changelog into single entry
- avoid "complete set" claim, reference Keycloak 26 instead

* address round 2 review feedback

- Extract remove_sensitive_config_keys() helper (DRY refactor)
- Simplify RS256 validation to single code path
- Add TypeError to inner except in compute_certificate_fingerprint()
- Remove redundant comments (L812, L1031)
- Switch .get() to direct dict access for module.params

(cherry picked from commit 80d21f2a0d)

Co-authored-by: Ivan Kokalovic <67540157+koke1997@users.noreply.github.com>
2026-02-18 18:36:48 +01:00
patchback[bot]
5dcb3b8f59 [PR #10841/986118c0 backport][stable-12] keycloak_realm_localization: new module - realm localization control (#11517)
keycloak_realm_localization: new module - realm localization control (#10841)

* add support for management of keycloak localizations

* unit test for keycloak localization support

* keycloak_realm_localization botmeta record

* rev: improvements after code review

(cherry picked from commit 986118c0af)

Co-authored-by: Jakub Danek <danekja@users.noreply.github.com>
2026-02-18 07:44:44 +01:00
patchback[bot]
42c20a754b [PR #11488/5e0fd120 backport][stable-12] ModuleHelper: ensure compatibility with ModuleTestCase (#11518)
ModuleHelper: ensure compatibility with `ModuleTestCase` (#11488)

* ModuleHelper: ensure compatibility with `ModuleTestCase`.

This change allows to configure the `module_fails_on_exception` decorator by passing a tuple of exception types that should not be handled by the decorator itself. In the context of `ModuleTestCase`, use `(AnsibleExitJson, AnsibleFailJson)` to let them pass through the decorator without modification.



* Another approach allowing user-defined exception types to pass through the decorator. When the decorator should have no arguments at all, we must hard code the name of the attribute that is looked up on self.



* Approach that removes decorator parametrization and relies on an object/class variable named `unhandled_exceptions`.



* context manager implemented that allows to pass through some exception types



* Update changelogs/fragments/11488-mh-ensure-compatibiliy-with-module-tests.yml



* Exception placeholder added



---------




(cherry picked from commit 5e0fd1201c)

Signed-off-by: Fiehe Christoph  <c.fiehe@eurodata.de>
Co-authored-by: Christoph Fiehe <cfiehe@users.noreply.github.com>
Co-authored-by: Fiehe Christoph <c.fiehe@eurodata.de>
Co-authored-by: Felix Fontein <felix@fontein.de>
2026-02-18 07:26:47 +01:00
patchback[bot]
75b6b4d792 [PR #11461/4bbedfd7 backport][stable-12] nsupdate: fix missing keyring initialization without TSIG auth (#11516)
nsupdate: fix missing keyring initialization without TSIG auth (#11461)

* nsupdate: fix missing keyring initialization without TSIG auth

* Update changelogs/fragments/fix-nsupdate-keyring.yml



---------


(cherry picked from commit 4bbedfd7df)

Co-authored-by: Pascal <pascal.guinet@free.fr>
Co-authored-by: Felix Fontein <felix@fontein.de>
2026-02-18 06:57:33 +01:00
patchback[bot]
a0c4308bed [PR #11503/85a0deee backport][stable-12] keycloak module utils: group search optimization (#11511)
keycloak module utils: group search optimization (#11503)

* Updated get_group_by_name with a query based lookup for improved speed

* Add changelog fragment for keycloak group search optimization

* Address review feedback: update changelog text and reformat code with ruff

* improved changelog fragment

* Update changelogs/fragments/11503-keycloak-group-search-optimization.yml



---------


(cherry picked from commit 85a0deeeba)

Co-authored-by: Andreas Wegmann <andreas.we9mann@gmail.com>
Co-authored-by: Felix Fontein <felix@fontein.de>
2026-02-14 21:14:52 +01:00
patchback[bot]
6437fe15c8 [PR #11486/c05c3133 backport][stable-12] seport: Add support for dccp and sctp protocols (#11509)
seport: Add support for dccp and sctp protocols (#11486)

Support for dccp and sctp protocols were added to SELinux userspace
python libraries in 3.0 version release in November 2019.

(cherry picked from commit c05c31334b)

Co-authored-by: Petr Lautrbach <lautrbach@redhat.com>
2026-02-14 21:14:44 +01:00
patchback[bot]
baddfa5a80 [PR #11501/ed7ccbe3 backport][stable-12] maven_artifact: resolve SNAPSHOT to latest using snapshot metadata block (#11508)
maven_artifact: resolve SNAPSHOT to latest using snapshot metadata block (#11501)

* fix(maven_artifact): resolve SNAPSHOT to latest using snapshot metadata block

Prefer the <snapshot> block (timestamp + buildNumber) from maven-metadata.xml
which always points to the latest build, instead of scanning <snapshotVersions>
and returning on the first match. Repositories like GitHub Packages keep all
historical entries in <snapshotVersions> (oldest first), causing the module to
resolve to the oldest snapshot instead of the latest.

Fixes #5117
Fixes #11489

* fix(maven_artifact): address review feedback

- Check both timestamp and buildNumber before using snapshot block,
  preventing IndexError when buildNumber is missing
- Remove unreliable snapshotVersions scanning fallback; use literal
  -SNAPSHOT version for non-unique snapshot repos instead
- Add tests for incomplete snapshot block and non-SNAPSHOT versions

* fix(maven_artifact): restore snapshotVersions scanning with last-match

Restore <snapshotVersions> scanning as primary resolution (needed for
per-extension accuracy per MNG-5459), but collect the last match instead
of returning on the first. Fall back to <snapshot> block when no
<snapshotVersions> match is found, then to literal -SNAPSHOT version.

* docs: update changelog fragment to match final implementation

* fix(maven_artifact): use updated timestamp for snapshot resolution

Use the <updated> attribute to select the newest snapshotVersion entry
instead of relying on list order. This works independently of how the
repository manager sorts entries in maven-metadata.xml.

Also fix test docstring and update changelog fragment per reviewer
feedback.

* test(maven_artifact): shuffle entries to verify updated timestamp sorting

Reorder snapshotVersion entries so the newest JAR is in the middle,
not at the end. This ensures the test actually validates that resolution
uses the <updated> timestamp rather than relying on list position.

(cherry picked from commit ed7ccbe3d4)

Co-authored-by: Adam R. <ariwk@protonmail.com>
2026-02-14 21:14:36 +01:00
patchback[bot]
b7d1483a08 [PR #11500/c9313af9 backport][stable-12] keycloak_identity_provider: add claims example for oidc-advanced-group-idp-mapper (#11507)
keycloak_identity_provider: add claims example for oidc-advanced-group-idp-mapper (#11500)

Add claims example for oidc-advanced-group-idp-mapper

For me it wasn't clear how to create claims using oidc-advanced-group-idp-mapper, perhaps other people can benefit from the following example.

(cherry picked from commit c9313af971)

Co-authored-by: David Filipe <68902816+daveopz@users.noreply.github.com>
2026-02-14 21:14:17 +01:00
patchback[bot]
b87121e1eb [PR #11504/8729f563 backport][stable-12] Update check_availability_service to return data instead of boolean (#11510)
Update check_availability_service to return data instead of boolean (#11504)

* Update check_availability_service to return data instead of boolean

* Add changelog fragment

(cherry picked from commit 8729f563b3)

Co-authored-by: Scott Seekamp <13857911+sseekamp@users.noreply.github.com>
2026-02-14 21:14:07 +01:00
patchback[bot]
cb17703c36 [PR #11495/88adca3f backport][stable-12] python_requirements_info: use importlib.metadata when available (#11496)
python_requirements_info: use importlib.metadata when available (#11495)

Use importlib.metadata when available.

(cherry picked from commit 88adca3fb4)

Co-authored-by: Felix Fontein <felix@fontein.de>
2026-02-11 07:12:04 +01:00
patchback[bot]
05d457dca7 [PR #11484/63ddca7f backport][stable-12] supervisorctl: remove unstable tag from integration tests (#11494)
supervisorctl: remove unstable tag from integration tests (#11484)

(cherry picked from commit 63ddca7f21)

Co-authored-by: Alexei Znamensky <103110+russoz@users.noreply.github.com>
2026-02-10 21:51:31 +01:00
patchback[bot]
7fce59fbc6 [PR #11479/476f2bf6 backport][stable-12] Integration tests: replace ansible_xxx with ansible_facts.xxx (#11480)
Integration tests: replace ansible_xxx with ansible_facts.xxx (#11479)

Replace ansible_xxx with ansible_facts.xxx.

(cherry picked from commit 476f2bf641)

Co-authored-by: Felix Fontein <felix@fontein.de>
2026-02-07 18:43:49 +01:00
patchback[bot]
de6967d3ff [PR #11473/df6d6269 backport][stable-12] keycloak_client: add valid_post_logout_redirect_uris and backchannel_logout_url (#11475)
keycloak_client: add valid_post_logout_redirect_uris and backchannel_logout_url (#11473)

* feat(keycloak_client): add valid_post_logout_redirect_uris and backchannel_logout_url

Add two new convenience parameters that map to client attributes:

- valid_post_logout_redirect_uris: sets post.logout.redirect.uris
  attribute (list items joined with ##)
- backchannel_logout_url: sets backchannel.logout.url attribute

These fields are not top-level in the Keycloak REST API but are stored
as client attributes. The new parameters provide a user-friendly
interface without requiring users to know the internal attribute names
and ##-separator format.

Fixes #6812, fixes #4892

* consolidate changelog and add PR link per review feedback

(cherry picked from commit df6d6269a6)

Co-authored-by: Ivan Kokalovic <67540157+koke1997@users.noreply.github.com>
2026-02-07 16:34:46 +01:00
patchback[bot]
bbb9b03b5e [PR #11464/8b0ce3e2 backport][stable-12] community.general.copr: clarify includepkgs/excludepkgs (#11476)
community.general.copr: clarify includepkgs/excludepkgs (#11464)

At first glance, includepkgs seems to be something that would install
the package name from the given copr repo.  This isn't helped by the
example that says "Install caddy" which very much looks like it is
installing the package from the repo.  Not only did I, a human,
hallucinate this behaviour, so did a large search engine's AI
responses to related queries.

In fact these are labels to vary what packages DNF sees.  Clarify this
by using wording and examples closer to the upstream documentation [1]

[1] https://dnf.readthedocs.io/en/latest/conf_ref.html

(cherry picked from commit 8b0ce3e28f)

Co-authored-by: Ian Wienand <ian@wienand.org>
2026-02-07 16:34:38 +01:00
patchback[bot]
a0d6487f6d [PR #11455/af4dbafe backport][stable-12] keycloak_client: fix diff for keycloak client auth flow overrides (#11477)
keycloak_client: fix diff for keycloak client auth flow overrides (#11455)

* 11430: fix diff for keycloak client auth flow overrides

* 11430: add changelog fragment

* 11430: move util function merge_settings_without_absent_nulls to the util functions file _keycloak_utils

* 11443: code cleanup

---------


(cherry picked from commit af4dbafe86)

Co-authored-by: thomasbargetz <thomas.bargetz@gmail.com>
Co-authored-by: Thomas Bargetz <thomas.bargetz@rise-world.com>
2026-02-07 16:34:29 +01:00
patchback[bot]
88bfb6dda3 [PR #11470/10681731 backport][stable-12] keycloak_realm_key: handle missing config fields for default keys (#11478)
keycloak_realm_key: handle missing config fields for default keys (#11470)

* fix(keycloak_realm_key): handle missing config fields for default keys

Keycloak API may not return 'active', 'enabled', or 'algorithm' fields
in the config response for default/auto-generated realm keys. This caused
a KeyError when the module tried to compare these fields during state
detection.

Use .get() with the expected value as default to handle missing fields
gracefully, treating them as unchanged if not present in the API response.

Fixes: #11459

* add PR link to changelog entry per review feedback

(cherry picked from commit 106817316d)

Co-authored-by: Ivan Kokalovic <67540157+koke1997@users.noreply.github.com>
2026-02-07 16:34:22 +01:00
patchback[bot]
d637db7623 [PR #11472/c41de53d backport][stable-12] keycloak: URL-encode query parameters for usernames with special characters (#11474)
keycloak: URL-encode query parameters for usernames with special characters (#11472)

* fix(keycloak): URL-encode query params for usernames with special chars

get_user_by_username() concatenates the username directly into the URL
query string. When the username contains a +, it is interpreted as a
space by the server, returning no match and causing a TypeError.

Use urllib.parse.quote() (already imported) for the username parameter.
Also replace three fragile .replace(' ', '%20') calls in the authz
search methods with proper quote() calls.

Fixes #10305

* Update changelogs/fragments/keycloak-url-encode-query-params.yml



---------


(cherry picked from commit c41de53dbb)

Co-authored-by: Ivan Kokalovic <67540157+koke1997@users.noreply.github.com>
Co-authored-by: Alexei Znamensky <103110+russoz@users.noreply.github.com>
2026-02-06 20:36:02 +01:00
patchback[bot]
2198588afa [PR #11454/b236772e backport][stable-12] keycloak_client: remove id's as change from diff for protocol mappers (#11469)
keycloak_client: remove id's as change from diff for protocol mappers (#11454)

* 11453 remove id's as change from diff for protocol mappers

* Update changelogs/fragments/11453-keycloak-client-protocol-mapper-ids.yml



---------


(cherry picked from commit b236772e57)

Co-authored-by: Simon Moosbrugger <707958+simonmoosbrugger@users.noreply.github.com>
Co-authored-by: Felix Fontein <felix@fontein.de>
2026-02-05 17:29:29 +01:00
Felix Fontein
9d6db6002c Add latest commit to .git-blame-ignore-revs.
(cherry picked from commit bce87a2a77)
2026-02-04 09:04:37 +01:00
patchback[bot]
dd9c86dfc0 [PR #11465/24098cd6 backport][stable-12] Reformat code (#11466)
Reformat code (#11465)

Reformat code.

(cherry picked from commit 24098cd638)

Co-authored-by: Felix Fontein <felix@fontein.de>
2026-02-04 09:04:00 +01:00
patchback[bot]
a266ba1d6e [PR #11457/95b24ac3 backport][stable-12] jboss: deprecation (#11458)
jboss: deprecation (#11457)

(cherry picked from commit 95b24ac3fe)

Co-authored-by: Alexei Znamensky <103110+russoz@users.noreply.github.com>
2026-01-31 10:03:36 +01:00
Felix Fontein
4167d8ebeb The next expected release will be 12.4.0. 2026-01-26 19:00:03 +01:00
Felix Fontein
e9064bbf97 Release 12.3.0. 2026-01-26 18:23:14 +01:00
patchback[bot]
79a5e6745b [PR #11444/ccf61224 backport][stable-12] keycloak_client: 11443: Fix false change detection for null client attributes (#11451)
keycloak_client: 11443: Fix false change detection for null client attributes (#11444)

* 11443: fix diff for keycloak_client module for non existing client attributes

* 11443: code cleanup

* 11443: add changelog fragment

* Adjust changelog fragment.

---------



(cherry picked from commit ccf61224f1)

Co-authored-by: thomasbargetz <thomas.bargetz@gmail.com>
Co-authored-by: Thomas Bargetz <thomas.bargetz@rise-world.com>
Co-authored-by: Felix Fontein <felix@fontein.de>
2026-01-26 17:43:17 +01:00
patchback[bot]
b5d57a35d6 [PR #11442/72220a2b backport][stable-12] fix gem module compatibility with ruby-4-rubygems (#11452)
fix gem module compatibility with ruby-4-rubygems (#11442)

* fix gem module compatibility with ruby-4-rubygems

rubygem's `query` command has recently been removed, see ruby/rubygems#9083.
address this by using the `list` command instead.

resolves #11397

* add changelog

* Adjust changelog fragment.

---------


(cherry picked from commit 72220a2b15)

Co-authored-by: glaszig <mail+github@glasz.org>
Co-authored-by: Felix Fontein <felix@fontein.de>
2026-01-26 17:43:07 +01:00
patchback[bot]
44dfe9e1ab [PR #11440/53e1e86b backport][stable-12] Logstash plugin version fix (#11450)
Logstash plugin version fix (#11440)

* logstash_plugin: fix argument order when using version parameter

* logstash_plugin: add integration tests

* logstash_plugin: add changelog fragment

(cherry picked from commit 53e1e86bcc)

Co-authored-by: Nicolas Boutet <amd3002@gmail.com>
2026-01-26 06:29:35 +01:00
patchback[bot]
4d05149b6c [PR #11368/aada8647 backport][stable-12] Adding 'project' parameter to Scaleway IP module. (#11447)
Adding 'project' parameter to Scaleway IP module. (#11368)

* Adding 'project' parameter to Scaleway IP module.

* Adding changelog fragment.

* Incrementing version.



* Updating docs to show both org and project ID options.

* Moving deprecated example to the end.

---------


(cherry picked from commit aada864718)

Co-authored-by: Greg Harvey <greg.harvey@gmail.com>
Co-authored-by: Felix Fontein <felix@fontein.de>
2026-01-25 21:05:27 +00:00
patchback[bot]
31bab91c31 [PR #11366/c0df3664 backport][stable-12] Adding 'project' parameter support for the Scaleway SG module. (#11448)
Adding 'project' parameter support for the Scaleway SG module. (#11366)

* Adding 'project' parameter support for the Scaleway SG module.

* Adding changelog fragment.

* Fixing documentation, organization is deprecated (although still available).

* Updating docs to show both org and project ID options.

* Incrementing version.



* Moving deprecated example to the end.

---------


(cherry picked from commit c0df366471)

Co-authored-by: Greg Harvey <greg.harvey@gmail.com>
Co-authored-by: Felix Fontein <felix@fontein.de>
2026-01-25 21:05:10 +00:00
patchback[bot]
ccdf82f163 [PR #11445/f9334656 backport][stable-12] Cleanup (#11446)
Cleanup (#11445)

* Correctly position BOTMETA entry.

* Standardize to 'import typing as t'.

* Remove platform attribute.

(cherry picked from commit f933465658)

Co-authored-by: Felix Fontein <felix@fontein.de>
2026-01-25 18:56:23 +01:00
patchback[bot]
1670f8693a [PR #11322/7a18af80 backport][stable-12] Handle @Redfish.Settings when setting ComputerSystem boot attributes (#11441)
Handle @Redfish.Settings  when setting ComputerSystem boot attributes (#11322)

* set_boot_override function now uses Redfish Settings URI if available in ComputerSystem resource

* Follows code formatting rules

* Add changelogs fragments file

* Update changelogs/fragments/11322-handle-redfish-settings-in-setbootoverride.yml



* Explicit rewriting as a workaround to keep the "good" path clean.

* Adjust changelog fragment.

---------




(cherry picked from commit 7a18af80ce)

Co-authored-by: Pierre-yves Fontaniere <pyfontan@cc.in2p3.fr>
Co-authored-by: Pierre-yves FONTANIERE <pyf@cc.in2p3.fr>
Co-authored-by: Alexei Znamensky <103110+russoz@users.noreply.github.com>
Co-authored-by: Felix Fontein <felix@fontein.de>
2026-01-23 06:44:37 +01:00
patchback[bot]
d58777ff5e [PR #11423/864695f8 backport][stable-12] Add to_toml filter (#11438)
Add `to_toml` filter (#11423)

* Add to_toml filter

This is based heavily on the to_yaml filter, but
with a pared-down feature set.

* Protect import

* Don't quote datetime as a string

* Use Ansible error types

* Import correct error types

* Don't use AnsibleTypeError

It doesn't seem to be available on older Ansible
core versions.

* Fix antsibull-nox errors

* Install dependencies for to_toml integration test



* Reduce author list to main contributor



* Update version added for to_toml



* Use AnsibleError for missing import



* Use AnsibleFilterError for runtime type check



* Move common code to plugin_utils/_tags.py

* Mark module util as private



* Update BOTMETA for to_toml



* Fix typo

* Correct version number



* Use to_text for to_toml dict key conversions



* Add tomlkit requirement to docs



* Add missing import

* Add aliases for for to_toml integration test

---------


(cherry picked from commit 864695f898)

Co-authored-by: Matt Williams <matt@milliams.com>
Co-authored-by: Felix Fontein <felix@fontein.de>
2026-01-22 07:40:51 +01:00
patchback[bot]
68f2433577 [PR #11425/9fcd9338 backport][stable-12] nsupdate: add server FQDN and GSS-TSIG support (#11439)
nsupdate: add server FQDN and GSS-TSIG support (#11425)

* nsupdate: support server FQDN

Right now, the server has to be specified as an IPv4/IPv6 address. This
adds support for specifing the server as a FQDN as well.

* nsupdate: support GSS-TSIG/Kerberos

Add support for GSS-TSIG (Kerberos) keys to nsupdate. This makes life
easier when working with Windows DNS servers or Bind in a Kerberos
environment.

Inspiration taken from here:
https://github.com/rthalley/dnspython/pull/530#issuecomment-1363265732

Closes: #5730

* nsupdate: introduce query helper function

This simplifies the code by moving the protocol checks, etc, into a
single place.

* nsupdate: try all server IP addresses

Change resolve_server() to generate a list of IPv[46] addresses, then
try all of them in a round-robin fashion in query().

* nsupdate: some more cleanups

As suggested in the PR review.

* nsupdate: apply suggestions from code review



---------


(cherry picked from commit 9fcd9338b1)

Co-authored-by: David Härdeman <david@hardeman.nu>
Co-authored-by: Felix Fontein <felix@fontein.de>
2026-01-22 07:38:12 +01:00
Felix Fontein
0f6dfd1ebb Prepare 12.3.0. 2026-01-20 22:42:03 +01:00
patchback[bot]
43f0152969 [PR #11421/9611dc25 backport][stable-12] time-command.py: make sure seconds is an int (#11436)
time-command.py: make sure seconds is an int (#11421)

Make sure seconds is an int.

(cherry picked from commit 9611dc258a)

Co-authored-by: Felix Fontein <felix@fontein.de>
2026-01-20 22:41:12 +01:00
patchback[bot]
68bd8babf7 [PR #11114/a8378a4e backport][stable-12] nmcli idempotency connection check (#11437)
nmcli idempotency connection check (#11114)

* nmcli idempotency connection check

* Changelog fragment and ruff reformat

* Fix : change error handling

* Remove odd conditions

* Refactor nmcli: fix error handling and remove redundant logic

* Fix code format

* Fix error message to handle

(cherry picked from commit a8378a4eb0)

Co-authored-by: Seddik Alaoui Ismaili <32570331+saibug@users.noreply.github.com>
2026-01-20 22:21:14 +01:00
patchback[bot]
ca805badc0 [PR #11413/4b0aeede backport][stable-12] feat(nmcli): Add support for IPv6 routing rules (#11432)
feat(nmcli): Add support for IPv6 routing rules (#11413)

* feat(nmcli): Add support for IPv6 routing rules

Closes #7094



* Add changelog fragment



* Fixing doc



* Add issue link to changelog fragment



* Fix version



---------




(cherry picked from commit 4b0aeede69)

Signed-off-by: Rémy Jacquin <remy@remyj.fr>
Co-authored-by: Rémy Jacquin <1536771+remyj38@users.noreply.github.com>
Co-authored-by: Felix Fontein <felix@fontein.de>
Co-authored-by: Alexei Znamensky <103110+russoz@users.noreply.github.com>
2026-01-16 21:32:52 +01:00
patchback[bot]
5b571fd53f [PR #11308/4b67afc2 backport][stable-12] Add option for wsl_shell_type, protect wsl.exe arguments if SSH shell is Powershell (#11433)
Add option for wsl_shell_type, protect wsl.exe arguments if SSH shell is Powershell (#11308)

* feat(wsl): add option for wsl_shell_type, protect wsl arguments if SSH shell is Powershell

* docs(wsl): add changelog fragment

* docs(wsl): fix changelog fragment syntax, add issue link



* feat(wsl): improve new option documentation



* refactor(wsl): put integrasion test flag into a variable for convenience

* feat(wsl): rename option to wsl_remote_ssh_shell_type

* feat(wsl): escape "%" if shell is cmd, raise AnsibleError if powershell

* test(wsl): fix unit tests for wsl

- remove redundant check - moved to a separate function
- fix check for cmd escaping of "%"
- fix formatting / whitespace

* test(wsl): fix expected error message

* test(wsl): fix test - position of stop-parsing token changed



---------


(cherry picked from commit 4b67afc2b0)

Co-authored-by: fizmat <fizmat.r66@gmail.com>
Co-authored-by: Felix Fontein <felix@fontein.de>
2026-01-16 21:26:29 +01:00
patchback[bot]
68b2385efd [PR #11427/0a702167 backport][stable-12] Update ignore.txt (#11429)
Update ignore.txt (#11427)

Update ignore.txt.

(cherry picked from commit 0a70216763)

Co-authored-by: Felix Fontein <felix@fontein.de>
2026-01-15 22:17:43 +01:00
Felix Fontein
b5c965939f Make sure stable-12 CI runs in cron.
(cherry picked from commit 28b16eab66)
2026-01-11 00:43:09 +01:00
patchback[bot]
136c7debe3 [PR #11417/a689bb8e backport][stable-12] CI: Arch Linux switched to Python 3.14 (#11420)
CI: Arch Linux switched to Python 3.14 (#11417)

Arch Linux switched to Python 3.14.

(cherry picked from commit a689bb8e8d)

Co-authored-by: Felix Fontein <felix@fontein.de>
2026-01-11 00:42:54 +01:00
patchback[bot]
5d16a88298 [PR #11347/e790b950 backport][stable-12] incus connection: fix regex (#11415)
* incus connection: fix regex (#11347)

* incus connection: fix regex

* updates

* Apply suggestions from code review

* expand regexp capture

* add changelog frag

* Update plugins/connection/incus.py

* split arguments after command option

* Update plugins/connection/incus.py

* remove *() and split from the last command

* add tests, make small adjustments

* remove redundant strip()

* add more tests

* adjusted changelog fragment

(cherry picked from commit e790b95067)

* Order imports.

(cherry picked from commit 76d51db8d0)

---------

Co-authored-by: Alexei Znamensky <103110+russoz@users.noreply.github.com>
Co-authored-by: Felix Fontein <felix@fontein.de>
2026-01-09 21:22:29 +01:00
Felix Fontein
02ed21b2a6 [stable-12] Configure sorting imports in CI and formatting (#11414)
Configure sorting imports in CI and formatting (#11410)

* Add reformat commit to .git-blame-ignore-revs.

* Make ruff also check the import order.

* Add ruff check --fix for imports to the nox formatting session.

(cherry picked from commit 91efa27cb9)
2026-01-09 19:41:54 +00:00
patchback[bot]
b769b0bc01 [PR #11400/236b9c0e backport][stable-12] Sort imports with ruff check --fix (#11409)
Sort imports with ruff check --fix (#11400)

Sort imports with ruff check --fix.

(cherry picked from commit 236b9c0e04)

Co-authored-by: Felix Fontein <felix@fontein.de>
2026-01-09 19:36:52 +01:00
patchback[bot]
ebaf2e71d5 [PR #11401/0e6ba072 backport][stable-12] Update CI pipelines (#11405)
Update CI pipelines (#11401)

Update CI pipelines:
- Fedora 42 -> 43 for devel
- RHEL 10.0 -> 10.1 for all ansible-core branches
- FreeBSD 13.5 -> 15.0 for devel
- Alpine 3.22 -> 3.23 for devel

(cherry picked from commit 0e6ba07261)

Co-authored-by: Felix Fontein <felix@fontein.de>
2026-01-08 12:28:46 +01:00
patchback[bot]
e3535de323 [PR #11396/c8356981 backport][stable-12] move imports from functions to the top of the file (#11399)
move imports from functions to the top of the file (#11396)

* move imports from functions to the top of the file

* add changelog frag

* Apply suggestions from code review



---------


(cherry picked from commit c8356981bb)

Co-authored-by: Alexei Znamensky <103110+russoz@users.noreply.github.com>
Co-authored-by: Felix Fontein <felix@fontein.de>
2026-01-07 21:27:49 +01:00
patchback[bot]
6169699b24 [PR #11388/defd1560 backport][stable-12] pmem: remove redundant use of regexp (#11398)
pmem: remove redundant use of regexp (#11388)

* pmem: remove redundant use of regexp

* add changelog frag

* add bugfixes extry

* Update plugins/modules/pmem.py



* Update plugins/modules/pmem.py



---------


(cherry picked from commit defd15609c)

Co-authored-by: Alexei Znamensky <103110+russoz@users.noreply.github.com>
Co-authored-by: Felix Fontein <felix@fontein.de>
2026-01-07 20:50:56 +01:00
patchback[bot]
e714d15891 [PR #11390/996b7469 backport][stable-12] slackpkg: simplify function query_package() (#11395)
slackpkg: simplify function `query_package()` (#11390)

* slackpkg: simplify function query_package()

* add changelog frag

(cherry picked from commit 996b7469e5)

Co-authored-by: Alexei Znamensky <103110+russoz@users.noreply.github.com>
2026-01-06 18:46:27 +01:00
patchback[bot]
dda90768f5 [PR #11391/b67c94fc backport][stable-12] fix ruff cases UP024,UP041 (#11394)
fix ruff cases UP024,UP041 (#11391)

* fix ruff cases UP024,UP041

* add changelog frag

(cherry picked from commit b67c94fc3f)

Co-authored-by: Alexei Znamensky <103110+russoz@users.noreply.github.com>
2026-01-06 18:18:08 +01:00
patchback[bot]
cd548f779a [PR #11385/d1352702 backport][stable-12] CI: Let the Python formatters and linters apply to all files in the collection (#11386)
CI: Let the Python formatters and linters apply to all files in the collection (#11385)

Let the Python formatters and linters apply to all files in the collection.

(cherry picked from commit d1352702f9)

Co-authored-by: Felix Fontein <felix@fontein.de>
2026-01-06 17:02:36 +01:00
patchback[bot]
c1ba162ec0 [PR #11387/d4089ca2 backport][stable-12] Update RHEL 9.x to 9.7 in CI (#11389)
Update RHEL 9.x to 9.7 in CI (#11387)

* Update RHEL 9.x to 9.7 in CI.

* Add skips.

(cherry picked from commit d4089ca29a)

Co-authored-by: Felix Fontein <felix@fontein.de>
2026-01-06 17:02:28 +01:00
patchback[bot]
2d99eb92de [PR #11376/75234597 backport][stable-12] Support diff mode for netcup-dns module (#11378)
Support diff mode for netcup-dns module (#11376)

* support diff mode for netcup-dns module

* Fix issue with yaml encoding after testing

* Add changelog fragment

* Fixed: proper and robust yaml import

* Remove need for yaml import

* Show whole zone in diff for context

* Update changelogs/fragments/11376-netcup-dns-diff-mode.yml



* Update plugins/modules/netcup_dns.py



---------


(cherry picked from commit 75234597bc)

Co-authored-by: mqus <8398165+mqus@users.noreply.github.com>
Co-authored-by: Felix Fontein <felix@fontein.de>
2026-01-05 18:58:17 +01:00
patchback[bot]
e0bd7e334e [PR #11379/b3dc06a7 backport][stable-12] Clean up other Python files (#11382)
Clean up other Python files (#11379)

* Address issues found by ruff check.

* Make mypy happy; remove some Python 2 compat code.

* Also declare port1.

(cherry picked from commit b3dc06a7dd)

Co-authored-by: Felix Fontein <felix@fontein.de>
2026-01-05 18:57:50 +01:00
Felix Fontein
1d09a36e0f Fix version number.
(cherry picked from commit 00d2785794)
2026-01-05 18:57:41 +01:00
patchback[bot]
bb6d5fb735 [PR #11377/c00fb4fb backport][stable-12] cloudflare_dns: also allow 128 as a value for flag (#11383)
cloudflare_dns: also allow 128 as a value for flag (#11377)

* Also allow 128 as a value for flag.

* Forgot to add changelog fragment.

(cherry picked from commit c00fb4fb5c)

Co-authored-by: Felix Fontein <felix@fontein.de>
2026-01-05 18:57:22 +01:00
patchback[bot]
8242f6fa46 [PR #11301/13035e2a backport][stable-12] Add support for multiple managers to get_manager_attributes command in idrac_redfish_info module (#11375)
Add support for multiple managers to get_manager_attributes command in idrac_redfish_info module (#11301)

* Update get_manager_attributes method to support systems with multiple managers present

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

* Add changelog fragment
Pre-define reponse for get_manager_attributes method

* Update changelogs/fragments/11301-idrac-info-multi-manager.yml

Update per suggestion!



* Update plugins/modules/idrac_redfish_info.py
Remove extra manager quantity check



---------


(cherry picked from commit 13035e2a2c)

Co-authored-by: Scott Seekamp <13857911+sseekamp@users.noreply.github.com>
Co-authored-by: Felix Fontein <felix@fontein.de>
2026-01-02 19:29:33 +01:00
patchback[bot]
88eee5fbb4 [PR #11357/ddf05104 backport][stable-12] Add missing integration test aliases files (#11372)
Add missing integration test aliases files (#11357)

* Add missing aliases files.

* Fix directory name.

* Add another missing aliases file.

* Adjust test to also work with newer jsonpatch versions.

(cherry picked from commit ddf05104f3)

Co-authored-by: Felix Fontein <felix@fontein.de>
2026-01-02 15:03:07 +01:00
patchback[bot]
5945c56b4c [PR #11369/20ba59cc backport][stable-12] Added "See Also" section (#11374)
Added "See Also" section (#11369)

* Added "See Also" section

* Corrected seealso documentation

* Update ini_file.py

Removed seealso descriptions

* Update to_ini.py

Removed seealso descriptions

* Update from_ini.py

Removed seealso descriptions

(cherry picked from commit 20ba59cce6)

Co-authored-by: daomah <129229601+daomah@users.noreply.github.com>
2026-01-02 15:02:56 +01:00
patchback[bot]
4514e271af [PR #11346/61d794f1 backport][stable-12] incus conn plugin: improve readability (was ruff: set target-python 3.7) (#11353)
incus conn plugin: improve readability (was ruff: set target-python 3.7) (#11346)

* incus connection plugin: improve readability

* add changelog frag

* Update plugins/connection/incus.py



* Update plugins/connection/incus.py

* Update plugins/connection/incus.py



---------


(cherry picked from commit 61d794f171)

Co-authored-by: Alexei Znamensky <103110+russoz@users.noreply.github.com>
Co-authored-by: Felix Fontein <felix@fontein.de>
2025-12-31 08:40:42 +01:00
patchback[bot]
f49c5f79a7 [PR #11343/e8f2b135 backport][stable-12] batch 3 - update Python idiom to 3.7 using pyupgrade (#11352)
batch 3 - update Python idiom to 3.7 using pyupgrade (#11343)

* batch 3 - update Python idiom to 3.7 using pyupgrade

* add changelog frag

* bring back sanity

* adjust test

* Apply suggestions from code review

(cherry picked from commit e8f2b135ba)

Co-authored-by: Alexei Znamensky <103110+russoz@users.noreply.github.com>
2025-12-30 22:43:24 +01:00
patchback[bot]
2d07481e64 [PR #11341/5b5f7e9e backport][stable-12] batch 1 - update Python idiom to 3.7 using pyupgrade (#11349)
batch 1 - update Python idiom to 3.7 using pyupgrade (#11341)

* batch 1 - update Python idiom to 3.7 using pyupgrade

* add changelog frag

* add changelog frag

(cherry picked from commit 5b5f7e9e64)

Co-authored-by: Alexei Znamensky <103110+russoz@users.noreply.github.com>
2025-12-30 16:47:11 +01:00
patchback[bot]
41f815be57 [PR #11344/543329ce backport][stable-12] batch 4 - update Python idiom to 3.7 using pyupgrade (#11350)
batch 4 - update Python idiom to 3.7 using pyupgrade (#11344)

* batch 4 - update Python idiom to 3.7 using pyupgrade

* add changelog frag

* bring back sanity

* remove unused import

(cherry picked from commit 543329cecb)

Co-authored-by: Alexei Znamensky <103110+russoz@users.noreply.github.com>
2025-12-30 16:31:29 +01:00
patchback[bot]
8d4e702d89 [PR #11340/a0d3bac8 backport][stable-12] cronvar: simplify exception raise - remove import sys (#11348)
cronvar: simplify exception raise - remove import sys (#11340)

* cronvar: simplify exception raise - remove import sys

* add changelog frag

(cherry picked from commit a0d3bac88c)

Co-authored-by: Alexei Znamensky <103110+russoz@users.noreply.github.com>
2025-12-30 16:20:46 +01:00
patchback[bot]
303bac630a [PR #11342/266d9d3f backport][stable-12] batch 2 - update Python idiom to 3.7 using pyupgrade (#11345)
batch 2 - update Python idiom to 3.7 using pyupgrade (#11342)

* batch 2 - update Python idiom to 3.7 using pyupgrade

* Apply suggestions from code review

(cherry picked from commit 266d9d3fb0)

Co-authored-by: Alexei Znamensky <103110+russoz@users.noreply.github.com>
2025-12-30 16:00:22 +01:00
Felix Fontein
213dc22217 The next expected release will be 12.3.0. 2025-12-29 15:27:28 +01:00
1066 changed files with 8669 additions and 3046 deletions

View File

@@ -29,6 +29,7 @@ schedules:
always: true
branches:
include:
- stable-12
- stable-11
- cron: 0 11 * * 0
displayName: Weekly (old stable branches)
@@ -170,10 +171,10 @@ stages:
parameters:
testFormat: devel/{0}
targets:
- name: Alpine 3.22
test: alpine/3.22
# - name: Fedora 42
# test: fedora/42
- name: Alpine 3.23
test: alpine/3.23
# - name: Fedora 43
# test: fedora/43
- name: Ubuntu 22.04
test: ubuntu/22.04
- name: Ubuntu 24.04
@@ -190,14 +191,15 @@ stages:
targets:
- name: macOS 15.3
test: macos/15.3
- name: RHEL 10.0
test: rhel/10.0
- name: RHEL 9.6
test: rhel/9.6
- name: RHEL 10.1
test: rhel/10.1
- name: RHEL 9.7
test: rhel/9.7
# TODO: enable this ASAP!
# - name: FreeBSD 15.0
# test: freebsd/15.0
- name: FreeBSD 14.3
test: freebsd/14.3
- name: FreeBSD 13.5
test: freebsd/13.5
groups:
- 1
- 2
@@ -210,8 +212,8 @@ stages:
parameters:
testFormat: 2.20/{0}
targets:
- name: RHEL 10.0
test: rhel/10.0
- name: RHEL 10.1
test: rhel/10.1
- name: FreeBSD 14.3
test: freebsd/14.3
groups:
@@ -226,10 +228,8 @@ stages:
parameters:
testFormat: 2.19/{0}
targets:
- name: RHEL 9.5
test: rhel/9.5
- name: RHEL 10.0
test: rhel/10.0
- name: RHEL 10.1
test: rhel/10.1
- name: FreeBSD 14.2
test: freebsd/14.2
groups:
@@ -246,8 +246,6 @@ stages:
targets:
- name: macOS 14.3
test: macos/14.3
- name: RHEL 9.4
test: rhel/9.4
- name: FreeBSD 14.1
test: freebsd/14.1
groups:
@@ -264,10 +262,10 @@ stages:
parameters:
testFormat: devel/linux/{0}
targets:
- name: Fedora 42
test: fedora42
- name: Alpine 3.22
test: alpine322
- name: Fedora 43
test: fedora43
- name: Alpine 3.23
test: alpine323
- name: Ubuntu 22.04
test: ubuntu2204
- name: Ubuntu 24.04
@@ -343,7 +341,7 @@ stages:
- name: Debian 13 Trixie
test: debian-13-trixie/3.13
- name: ArchLinux
test: archlinux/3.13
test: archlinux/3.14
groups:
- 1
- 2

View File

@@ -43,20 +43,20 @@ def main():
jobs[label] = max(attempt, jobs.get(label, 0))
for label, attempt in jobs.items():
name = "Coverage {attempt} {label}".format(label=label, attempt=attempt)
name = f"Coverage {attempt} {label}"
source = os.path.join(source_directory, name)
source_files = os.listdir(source)
for source_file in source_files:
source_path = os.path.join(source, source_file)
destination_path = os.path.join(destination_directory, source_file + "." + label)
print('"%s" -> "%s"' % (source_path, destination_path))
print(f'"{source_path}" -> "{destination_path}"')
shutil.copyfile(source_path, destination_path)
count += 1
print("Coverage file count: %d" % count)
print("##vso[task.setVariable variable=coverageFileCount]%d" % count)
print("##vso[task.setVariable variable=outputPath]%s" % output_path)
print(f"Coverage file count: {count}")
print(f"##vso[task.setVariable variable=coverageFileCount]{count}")
print(f"##vso[task.setVariable variable=outputPath]{output_path}")
if __name__ == "__main__":

View File

@@ -15,7 +15,6 @@ import pathlib
import shutil
import subprocess
import tempfile
import typing as t
import urllib.request
@@ -23,7 +22,7 @@ import urllib.request
class CoverageFile:
name: str
path: pathlib.Path
flags: t.List[str]
flags: list[str]
@dataclasses.dataclass(frozen=True)
@@ -46,7 +45,7 @@ def parse_args() -> Args:
return Args(**kwargs)
def process_files(directory: pathlib.Path) -> t.Tuple[CoverageFile, ...]:
def process_files(directory: pathlib.Path) -> tuple[CoverageFile, ...]:
processed = []
for file in directory.joinpath("reports").glob("coverage*.xml"):
name = file.stem.replace("coverage=", "")
@@ -62,7 +61,7 @@ def process_files(directory: pathlib.Path) -> t.Tuple[CoverageFile, ...]:
return tuple(processed)
def upload_files(codecov_bin: pathlib.Path, files: t.Tuple[CoverageFile, ...], dry_run: bool = False) -> None:
def upload_files(codecov_bin: pathlib.Path, files: tuple[CoverageFile, ...], dry_run: bool = False) -> None:
for file in files:
cmd = [
str(codecov_bin),

View File

@@ -19,8 +19,8 @@ def main():
sys.stdout.reconfigure(errors="surrogateescape")
for line in sys.stdin:
seconds = time.time() - start
sys.stdout.write("%02d:%02d %s" % (seconds // 60, seconds % 60, line))
seconds = int(time.time() - start)
sys.stdout.write(f"{seconds // 60:02}:{seconds % 60:02} {line}")
sys.stdout.flush()

View File

@@ -11,3 +11,5 @@ eaa5e07b2866e05b6c7b5628ca92e9cb1142d008
# Code reformatting
340ff8586d4f1cb6a0f3c934eb42589bcc29c0ea
e530d2906a1f61df89861286ac57c951a247f32c
b769b0bc01520d12699d3911e1fc290b813cde40
dd9c86dfc094131f223ffb59e5a3d9f2dfc5875d

21
.github/BOTMETA.yml vendored
View File

@@ -65,6 +65,9 @@ files:
$callbacks/log_plays.py: {}
$callbacks/loganalytics.py:
maintainers: zhcli
$callbacks/loganalytics_ingestion.py:
ignore: zhcli
maintainers: pboushy vsh47 wtcline-intc
$callbacks/logdna.py: {}
$callbacks/logentries.py: {}
$callbacks/logstash.py:
@@ -133,6 +136,8 @@ files:
$doc_fragments/hwc.py:
labels: hwc
maintainers: $team_huawei
$doc_fragments/_icinga2_api.py:
maintainers: cfiehe
$doc_fragments/nomad.py:
maintainers: chris93111 apecnascimento
$doc_fragments/pipx.py:
@@ -216,6 +221,10 @@ files:
maintainers: resmo
$filters/to_time_unit.yml:
maintainers: resmo
$filters/to_toml.py:
maintainers: milliams
$filters/to_toml.yml:
maintainers: milliams
$filters/to_weeks.yml:
maintainers: resmo
$filters/to_yaml.py:
@@ -358,6 +367,8 @@ files:
keywords: cloud huawei hwc
labels: huawei hwc_utils networking
maintainers: $team_huawei
$module_utils/_icinga2.py:
maintainers: cfiehe
$module_utils/identity/keycloak/keycloak.py:
maintainers: $team_keycloak
$module_utils/identity/keycloak/keycloak_clientsecret.py:
@@ -709,6 +720,8 @@ files:
maintainers: $team_huawei huaweicloud
$modules/ibm_sa_:
maintainers: tzure
$modules/icinga2_downtime.py:
maintainers: cfiehe
$modules/icinga2_feature.py:
maintainers: nerzhul
$modules/icinga2_host.py:
@@ -853,6 +866,8 @@ files:
maintainers: fynncfchen
$modules/keycloak_realm_key.py:
maintainers: mattock
$modules/keycloak_realm_localization.py:
maintainers: danekja
$modules/keycloak_role.py:
maintainers: laurpaum
$modules/keycloak_user.py:
@@ -1333,6 +1348,8 @@ files:
maintainers: farhan7500 gautamphegde
$modules/ssh_config.py:
maintainers: gaqzi Akasurde
$modules/sssd_info.py:
maintainers: a-gabidullin
$modules/stacki_host.py:
labels: stacki_host
maintainers: bsanders bbyhuy
@@ -1498,14 +1515,14 @@ files:
maintainers: vbotka
$plugin_utils/unsafe.py:
maintainers: felixfontein
$plugin_utils/_tags.py:
maintainers: felixfontein
$tests/a_module.py:
maintainers: felixfontein
$tests/ansible_type.py:
maintainers: vbotka
$tests/fqdn_valid.py:
maintainers: vbotka
$modules/sssd_info.py:
maintainers: a-gabidullin
#########################
docs/docsite/rst/filter_guide.rst: {}
docs/docsite/rst/filter_guide_abstract_informations.rst: {}

View File

@@ -14,6 +14,8 @@ warn_redundant_casts = True
# warn_return_any = True
warn_unreachable = True
exclude = tests/integration/targets/django_.*/files/.*
[mypy-ansible.*]
# ansible-core has partial typing information
follow_untyped_imports = True
@@ -24,6 +26,10 @@ follow_untyped_imports = True
# 3. That have no types and type stubs.
[mypy-aerospike.*]
ignore_missing_imports = True
[mypy-antsibull_nox.*]
ignore_missing_imports = True
[mypy-asyncore.*]
ignore_missing_imports = True
[mypy-boto3.*]
ignore_missing_imports = True
[mypy-bs4.*]
@@ -38,6 +44,8 @@ ignore_missing_imports = True
ignore_missing_imports = True
[mypy-crypt.*]
ignore_missing_imports = True
[mypy-daemon.*]
ignore_missing_imports = True
[mypy-datadog.*]
ignore_missing_imports = True
[mypy-dbus.*]
@@ -62,6 +70,8 @@ ignore_missing_imports = True
ignore_missing_imports = True
[mypy-github3.*]
ignore_missing_imports = True
[mypy-gssapi.*]
ignore_missing_imports = True
[mypy-hashids.*]
ignore_missing_imports = True
[mypy-heroku3.*]
@@ -122,6 +132,10 @@ ignore_missing_imports = True
ignore_missing_imports = True
[mypy-nomad.*]
ignore_missing_imports = True
[mypy-nopackagewiththisname.*]
ignore_missing_imports = True
[mypy-nox.*]
ignore_missing_imports = True
[mypy-oci.*]
ignore_missing_imports = True
[mypy-oneandone.*]
@@ -144,6 +158,8 @@ ignore_missing_imports = True
ignore_missing_imports = True
[mypy-pingdom.*]
ignore_missing_imports = True
[mypy-pkg_resources.*]
ignore_missing_imports = True
[mypy-portage.*]
ignore_missing_imports = True
[mypy-potatoes_that_will_never_be_there.*]
@@ -174,6 +190,8 @@ ignore_missing_imports = True
ignore_missing_imports = True
[mypy-rpm.*]
ignore_missing_imports = True
[mypy-ruamel.yaml.*]
ignore_missing_imports = True
[mypy-salt.*]
ignore_missing_imports = True
[mypy-selinux.*]
@@ -186,6 +204,10 @@ ignore_missing_imports = True
ignore_missing_imports = True
[mypy-sha.*]
ignore_missing_imports = True
[mypy-smtpd.*]
ignore_missing_imports = True
[mypy-smtpd_tls.*]
ignore_missing_imports = True
[mypy-SoftLayer.*]
ignore_missing_imports = True
[mypy-spotinst_sdk.*]
@@ -198,10 +220,14 @@ ignore_missing_imports = True
ignore_missing_imports = True
[mypy-thycotic.*]
ignore_missing_imports = True
[mypy-tomlkit.*]
ignore_missing_imports = True
[mypy-univention.*]
ignore_missing_imports = True
[mypy-vexatapi.*]
ignore_missing_imports = True
[mypy-voluptuous.*]
ignore_missing_imports = True
[mypy-websocket.*]
ignore_missing_imports = True
[mypy-XenAPI.*]

File diff suppressed because one or more lines are too long

View File

@@ -6,6 +6,181 @@ Community General Release Notes
This changelog describes changes after version 11.0.0.
v12.4.0
=======
Release Summary
---------------
Regular bugfix and feature release.
Minor Changes
-------------
- ModuleHelper module utils - allow to ignore specific exceptions in ``module_fails_on_exception`` decorator (https://github.com/ansible-collections/community.general/pull/11488).
- from_ini filter plugin - add ``delimiters`` parameter to allow correctly parsing more INI documents (https://github.com/ansible-collections/community.general/issues/11506, https://github.com/ansible-collections/community.general/pull/11512).
- keycloak_client - add ``valid_post_logout_redirect_uris`` option to configure post logout redirect URIs for a client, and ``backchannel_logout_url`` option to configure the backchannel logout URL for a client (https://github.com/ansible-collections/community.general/issues/6812, https://github.com/ansible-collections/community.general/issues/4892, https://github.com/ansible-collections/community.general/pull/11473).
- keycloak_client_rolemapping, keycloak_realm_rolemapping, keycloak_group - optimize retrieval of groups by name to use Keycloak search API with exact matching instead of fetching all groups (https://github.com/ansible-collections/community.general/pull/11503).
- keycloak_realm - add support for ``localizationTexts`` option in Keycloak realms (https://github.com/ansible-collections/community.general/pull/11513).
- keycloak_realm_key - add support for auto-generated key providers (``rsa-generated``, ``rsa-enc-generated``, ``hmac-generated``, ``aes-generated``, ``ecdsa-generated``, ``ecdh-generated``, ``eddsa-generated``), ``java-keystore`` provider, additional algorithms (HMAC, ECDSA, ECDH, EdDSA, AES), and new config options (``secret_size``, ``key_size``, ``elliptic_curve``, ``keystore``, ``keystore_password``, ``key_alias``, ``key_password``). Also makes ``config.private_key`` and ``config.certificate`` optional as they are only required for imported key providers (https://github.com/ansible-collections/community.general/pull/11468).
- redfish_info - add Redfish Root data to results of successful ``CheckAvailability`` command (https://github.com/ansible-collections/community.general/pull/11504).
- seport - adds support for DCCP and SCTP protocols (https://github.com/ansible-collections/community.general/pull/11486).
Bugfixes
--------
- keycloak module utils - fix ``TypeError`` crash when managing users whose username or email contains special characters such as ``+`` (https://github.com/ansible-collections/community.general/issues/10305, https://github.com/ansible-collections/community.general/pull/11472).
- keycloak module utils - use proper URL encoding (``urllib.parse.quote``) for query parameters in authorization permission name searches, replacing fragile manual space replacement (https://github.com/ansible-collections/community.general/pull/11472).
- keycloak_client - fix idempotency bug caused by ``null`` flow overrides value differences for non-existing flow overrides (https://github.com/ansible-collections/community.general/issues/11430, https://github.com/ansible-collections/community.general/pull/11455).
- keycloak_client - remove IDs as change from diff result for protocol mappers (https://github.com/ansible-collections/community.general/issues/11453, https://github.com/ansible-collections/community.general/pull/11454).
- keycloak_realm_key - fix ``KeyError`` crash when managing realm keys where Keycloak does not return ``active``, ``enabled``, or ``algorithm`` fields in the config response (https://github.com/ansible-collections/community.general/issues/11459, https://github.com/ansible-collections/community.general/pull/11470).
- keycloak_user_federation - mapper config item can be an array (https://github.com/ansible-collections/community.general/issues/11502, https://github.com/ansible-collections/community.general/pull/11515).
- keycloak_user_rolemapping - fix ``TypeError`` crash when adding a client role to a user who has no existing roles for that client (https://github.com/ansible-collections/community.general/issues/10960, https://github.com/ansible-collections/community.general/pull/11471).
- maven_artifact - fix SNAPSHOT version resolution to pick the newest matching ``<snapshotVersion>`` entry by ``<updated>`` timestamp instead of the first. Repositories like GitHub Packages keep all historical entries in ``<snapshotVersions>`` (oldest first), causing the module to resolve to the oldest snapshot instead of the latest (https://github.com/ansible-collections/community.general/issues/5117, https://github.com/ansible-collections/community.general/issues/11489, https://github.com/ansible-collections/community.general/pull/11501).
- nsupdate - fix ``AttributeError`` when using the module without TSIG authentication (https://github.com/ansible-collections/community.general/issues/11460, https://github.com/ansible-collections/community.general/pull/11461).
- python_requirements_info - use ``importlib.metadata`` if ``pkg_resources`` from ``setuptools`` cannot be imported. That module has been removed from setuptools 82.0.0 (https://github.com/ansible-collections/community.general/issues/11491, https://github.com/ansible-collections/community.general/pull/11492).
- splunk callback plugin - replace deprecated callback function (https://github.com/ansible-collections/community.general/pull/11485).
New Plugins
-----------
Callback
~~~~~~~~
- community.general.loganalytics_ingestion - Posts task results to an Azure Log Analytics workspace using the new Logs Ingestion API.
New Modules
-----------
- community.general.icinga2_downtime - Manages Icinga 2 downtimes.
- community.general.keycloak_realm_localization - Allows management of Keycloak realm localization overrides via the Keycloak API.
v12.3.0
=======
Release Summary
---------------
Regular feature and bugfix release.
Minor Changes
-------------
- alicloud_ecs module utils - update to Python 3.7 idioms (https://github.com/ansible-collections/community.general/pull/11341).
- android_sdk - update to Python 3.7 idioms (https://github.com/ansible-collections/community.general/pull/11343).
- archive - update to Python 3.7 idioms (https://github.com/ansible-collections/community.general/pull/11343).
- bitbucket_pipeline_known_host - update to Python 3.7 idioms (https://github.com/ansible-collections/community.general/pull/11343).
- chroot connection plugin - update to Python 3.7 idioms (https://github.com/ansible-collections/community.general/pull/11341).
- cobbler inventory plugin - update to Python 3.7 idioms (https://github.com/ansible-collections/community.general/pull/11341).
- copr - update to Python 3.7 idioms (https://github.com/ansible-collections/community.general/pull/11343).
- cronvar - simplify handling unknown exceptions (https://github.com/ansible-collections/community.general/pull/11340).
- cronvar - update to Python 3.7 idioms (https://github.com/ansible-collections/community.general/pull/11343).
- crypttab - update to Python 3.7 idioms (https://github.com/ansible-collections/community.general/pull/11343).
- elasticsearch_plugin - update to Python 3.7 idioms (https://github.com/ansible-collections/community.general/pull/11343).
- gitlab_group - update to Python 3.7 idioms (https://github.com/ansible-collections/community.general/pull/11343).
- gitlab_issue - update to Python 3.7 idioms (https://github.com/ansible-collections/community.general/pull/11343).
- gitlab_merge_request - update to Python 3.7 idioms (https://github.com/ansible-collections/community.general/pull/11343).
- gitlab_project - update to Python 3.7 idioms (https://github.com/ansible-collections/community.general/pull/11343).
- gunicorn - update to Python 3.7 idioms (https://github.com/ansible-collections/community.general/pull/11343).
- htpasswd - update to Python 3.7 idioms (https://github.com/ansible-collections/community.general/pull/11343).
- idrac_redfish_info - add multiple manager support to ``GetManagerAttributes`` command (https://github.com/ansible-collections/community.general/pull/11294).
- imc_rest - update to Python 3.7 idioms (https://github.com/ansible-collections/community.general/pull/11343).
- incus connection plugin - improve code readability (https://github.com/ansible-collections/community.general/pull/11346).
- incus connection plugin - simplify regular expression matching commands (https://github.com/ansible-collections/community.general/pull/11347).
- ini_file - update to Python 3.7 idioms (https://github.com/ansible-collections/community.general/pull/11343).
- interfaces_file - update to Python 3.7 idioms (https://github.com/ansible-collections/community.general/pull/11343).
- iptables_state - update to Python 3.7 idioms (https://github.com/ansible-collections/community.general/pull/11343).
- jail connection plugin - update to Python 3.7 idioms (https://github.com/ansible-collections/community.general/pull/11341).
- jenkins_credential - update to Python 3.7 idioms (https://github.com/ansible-collections/community.general/pull/11343).
- jenkins_plugin - update to Python 3.7 idioms (https://github.com/ansible-collections/community.general/pull/11343).
- jenkins_script - move ``import`` statemetns to the top of the file (https://github.com/ansible-collections/community.general/pull/11396).
- kdeconfig - update to Python 3.7 idioms (https://github.com/ansible-collections/community.general/pull/11343).
- known_hosts module utils - update to Python 3.7 idioms (https://github.com/ansible-collections/community.general/pull/11341).
- layman - update to Python 3.7 idioms (https://github.com/ansible-collections/community.general/pull/11343).
- linode - move ``import`` statemetns to the top of the file (https://github.com/ansible-collections/community.general/pull/11396).
- linode inventory plugin - update to Python 3.7 idioms (https://github.com/ansible-collections/community.general/pull/11341).
- listen_ports_facts - update to Python 3.7 idioms (https://github.com/ansible-collections/community.general/pull/11343).
- locale_gen - update to Python 3.7 idioms (https://github.com/ansible-collections/community.general/pull/11343).
- logentries callback plugin - update to Python 3.7 idioms (https://github.com/ansible-collections/community.general/pull/11341).
- lvm_pv - update to Python 3.7 idioms (https://github.com/ansible-collections/community.general/pull/11343).
- lxc connection plugin - update to Python 3.7 idioms (https://github.com/ansible-collections/community.general/pull/11341).
- lxd inventory plugin - update to Python 3.7 idioms (https://github.com/ansible-collections/community.general/pull/11341).
- lxd module utils - update to Python 3.7 idioms (https://github.com/ansible-collections/community.general/pull/11341).
- manageiq module utils - update to Python 3.7 idioms (https://github.com/ansible-collections/community.general/pull/11341).
- manageiq_alert_profiles - update to Python 3.7 idioms (https://github.com/ansible-collections/community.general/pull/11344).
- modprobe - update to Python 3.7 idioms (https://github.com/ansible-collections/community.general/pull/11344).
- mssql_db - update to Python 3.7 idioms (https://github.com/ansible-collections/community.general/pull/11344).
- nagios - update to Python 3.7 idioms (https://github.com/ansible-collections/community.general/pull/11344).
- netcup_dns - support diff mode (https://github.com/ansible-collections/community.general/pull/11376).
- nmcli - add idempotency check (https://github.com/ansible-collections/community.general/pull/11114).
- nmcli - add support for IPv6 routing rules (https://github.com/ansible-collections/community.general/issues/7094, https://github.com/ansible-collections/community.general/pull/11413).
- nosh - update to Python 3.7 idioms (https://github.com/ansible-collections/community.general/pull/11344).
- nsupdate - add support for server FQDN and the GSS-TSIG key algorithm (https://github.com/ansible-collections/community.general/issues/5730, https://github.com/ansible-collections/community.general/pull/11425).
- nsupdate modules plugin - replace aliased errors with proper Python error (https://github.com/ansible-collections/community.general/pull/11391).
- oci_utils module utils - update to Python 3.7 idioms (https://github.com/ansible-collections/community.general/pull/11341).
- omapi_host - update to Python 3.7 idioms (https://github.com/ansible-collections/community.general/pull/11344).
- one_image - move ``import`` statemetns to the top of the file (https://github.com/ansible-collections/community.general/pull/11396).
- one_image_info - move ``import`` statemetns to the top of the file (https://github.com/ansible-collections/community.general/pull/11396).
- one_service - move ``import`` statemetns to the top of the file (https://github.com/ansible-collections/community.general/pull/11396).
- one_vm - move ``import`` statemetns to the top of the file (https://github.com/ansible-collections/community.general/pull/11396).
- one_vm - update to Python 3.7 idioms (https://github.com/ansible-collections/community.general/pull/11344).
- opennebula inventory plugin - update to Python 3.7 idioms (https://github.com/ansible-collections/community.general/pull/11341).
- pam_limits - update to Python 3.7 idioms (https://github.com/ansible-collections/community.general/pull/11344).
- pamd - update to Python 3.7 idioms (https://github.com/ansible-collections/community.general/pull/11344).
- parted - update to Python 3.7 idioms (https://github.com/ansible-collections/community.general/pull/11344).
- pmem - simplify text tests without using regular expression (https://github.com/ansible-collections/community.general/pull/11388).
- pubnub_blocks - update to Python 3.7 idioms (https://github.com/ansible-collections/community.general/pull/11344).
- pulp_repo - update to Python 3.7 idioms (https://github.com/ansible-collections/community.general/pull/11344).
- read_csv - update to Python 3.7 idioms (https://github.com/ansible-collections/community.general/pull/11344).
- redfish_utils module utils - adds support of ``@Redfish.Settings`` in ``ComputerSystem`` attributes for ``set_boot_override`` function (https://github.com/ansible-collections/community.general/issues/11297, https://github.com/ansible-collections/community.general/pull/11322).
- redhat_subscription - update to Python 3.7 idioms (https://github.com/ansible-collections/community.general/pull/11344).
- rhsm_repository - update to Python 3.7 idioms (https://github.com/ansible-collections/community.general/pull/11344).
- runit - update to Python 3.7 idioms (https://github.com/ansible-collections/community.general/pull/11344).
- scaleway_ip - added ``project`` parameter (https://github.com/ansible-collections/community.general/issues/11367, https://github.com/ansible-collections/community.general/pull/11368).
- scaleway_security_group - added ``project`` parameter (https://github.com/ansible-collections/community.general/issues/11364, https://github.com/ansible-collections/community.general/pull/11366).
- sensu_check - update to Python 3.7 idioms (https://github.com/ansible-collections/community.general/pull/11344).
- sensu_client - update to Python 3.7 idioms (https://github.com/ansible-collections/community.general/pull/11344).
- sensu_handler - update to Python 3.7 idioms (https://github.com/ansible-collections/community.general/pull/11344).
- sensu_subscription - update to Python 3.7 idioms (https://github.com/ansible-collections/community.general/pull/11344).
- seport - update to Python 3.7 idioms (https://github.com/ansible-collections/community.general/pull/11344).
- serverless - update to Python 3.7 idioms (https://github.com/ansible-collections/community.general/pull/11344).
- slackpkg - refactor function ``query_packages()`` (https://github.com/ansible-collections/community.general/pull/11390).
- solaris_zone - update to Python 3.7 idioms (https://github.com/ansible-collections/community.general/pull/11344).
- sorcery - update to Python 3.7 idioms (https://github.com/ansible-collections/community.general/pull/11344).
- spotinst_aws_elastigroup - update to Python 3.7 idioms (https://github.com/ansible-collections/community.general/pull/11344).
- sudoers - update to Python 3.7 idioms (https://github.com/ansible-collections/community.general/pull/11344).
- svc - update to Python 3.7 idioms (https://github.com/ansible-collections/community.general/pull/11344).
- timestamp callback plugin - update to Python 3.7 idioms (https://github.com/ansible-collections/community.general/pull/11341).
- timezone - update to Python 3.7 idioms (https://github.com/ansible-collections/community.general/pull/11344).
- univention_umc module utils - update to Python 3.7 idioms (https://github.com/ansible-collections/community.general/pull/11341).
- wakeonlan - update to Python 3.7 idioms (https://github.com/ansible-collections/community.general/pull/11344).
- wsl connection plugin - add option ``wsl_remote_ssh_shell_type``. Support PowerShell in addition to cmd as the Windows shell (https://github.com/ansible-collections/community.general/issues/11307, https://github.com/ansible-collections/community.general/pull/11308).
- wsl connection plugin - replace aliased errors with proper Python error (https://github.com/ansible-collections/community.general/pull/11391).
- wsl connection plugin - update to Python 3.7 idioms (https://github.com/ansible-collections/community.general/pull/11341).
- xfs_quota - update to Python 3.7 idioms (https://github.com/ansible-collections/community.general/pull/11344).
- yaml cache plugin - update to Python 3.7 idioms (https://github.com/ansible-collections/community.general/pull/11341).
- zone connection plugin - update to Python 3.7 idioms (https://github.com/ansible-collections/community.general/pull/11341).
- zypper - update to Python 3.7 idioms (https://github.com/ansible-collections/community.general/pull/11344).
- zypper_repository - update to Python 3.7 idioms (https://github.com/ansible-collections/community.general/pull/11344).
Bugfixes
--------
- cloudflare_dns - also allow ``flag=128`` for CAA records (https://github.com/ansible-collections/community.general/issues/11355, https://github.com/ansible-collections/community.general/pull/11377).
- gem - add compatibility with Ruby 4 rubygems (https://github.com/ansible-collections/community.general/issues/11397, https://github.com/ansible-collections/community.general/pull/11442).
- incus connection plugin - fix parsing of commands for Windows, enforcing a ``\`` after the drive letter and colon symbol (https://github.com/ansible-collections/community.general/pull/11347).
- keycloak_client - fix idempotency bug caused by ``null`` client attribute value differences for non-existing client attributes (https://github.com/ansible-collections/community.general/issues/11443, https://github.com/ansible-collections/community.general/pull/11444).
- logstash_plugin - fix argument order when using ``version`` parameter. The plugin name must come after options like ``--version`` for the ``logstash-plugin`` CLI to work correctly (https://github.com/ansible-collections/community.general/issues/10745, https://github.com/ansible-collections/community.general/pull/11440).
- pmem - fix test for invalid data input (https://github.com/ansible-collections/community.general/pull/11388).
New Plugins
-----------
Filter
~~~~~~
- community.general.to_toml - Convert variable to TOML string.
v12.2.0
=======

View File

@@ -20,8 +20,15 @@ stable_branches = [ "stable-*" ]
[sessions]
[sessions.lint]
code_files = ["."] # consider all Python files in the collection
run_isort = false
run_black = false
run_ruff_autofix = true
ruff_autofix_config = "ruff.toml"
ruff_autofix_select = [
"I",
"RUF022",
]
run_ruff_check = true
ruff_check_config = "ruff.toml"
run_ruff_format = true

View File

@@ -1627,3 +1627,262 @@ releases:
name: sssd_info
namespace: ''
release_date: '2025-12-29'
12.3.0:
changes:
bugfixes:
- cloudflare_dns - also allow ``flag=128`` for CAA records (https://github.com/ansible-collections/community.general/issues/11355,
https://github.com/ansible-collections/community.general/pull/11377).
- gem - add compatibility with Ruby 4 rubygems (https://github.com/ansible-collections/community.general/issues/11397,
https://github.com/ansible-collections/community.general/pull/11442).
- 'incus connection plugin - fix parsing of commands for Windows, enforcing
a ``\`` after the drive letter and colon symbol (https://github.com/ansible-collections/community.general/pull/11347).
'
- keycloak_client - fix idempotency bug caused by ``null`` client attribute
value differences for non-existing client attributes (https://github.com/ansible-collections/community.general/issues/11443,
https://github.com/ansible-collections/community.general/pull/11444).
- logstash_plugin - fix argument order when using ``version`` parameter. The
plugin name must come after options like ``--version`` for the ``logstash-plugin``
CLI to work correctly (https://github.com/ansible-collections/community.general/issues/10745,
https://github.com/ansible-collections/community.general/pull/11440).
- pmem - fix test for invalid data input (https://github.com/ansible-collections/community.general/pull/11388).
minor_changes:
- alicloud_ecs module utils - update to Python 3.7 idioms (https://github.com/ansible-collections/community.general/pull/11341).
- android_sdk - update to Python 3.7 idioms (https://github.com/ansible-collections/community.general/pull/11343).
- archive - update to Python 3.7 idioms (https://github.com/ansible-collections/community.general/pull/11343).
- bitbucket_pipeline_known_host - update to Python 3.7 idioms (https://github.com/ansible-collections/community.general/pull/11343).
- chroot connection plugin - update to Python 3.7 idioms (https://github.com/ansible-collections/community.general/pull/11341).
- cobbler inventory plugin - update to Python 3.7 idioms (https://github.com/ansible-collections/community.general/pull/11341).
- copr - update to Python 3.7 idioms (https://github.com/ansible-collections/community.general/pull/11343).
- cronvar - simplify handling unknown exceptions (https://github.com/ansible-collections/community.general/pull/11340).
- cronvar - update to Python 3.7 idioms (https://github.com/ansible-collections/community.general/pull/11343).
- crypttab - update to Python 3.7 idioms (https://github.com/ansible-collections/community.general/pull/11343).
- elasticsearch_plugin - update to Python 3.7 idioms (https://github.com/ansible-collections/community.general/pull/11343).
- gitlab_group - update to Python 3.7 idioms (https://github.com/ansible-collections/community.general/pull/11343).
- gitlab_issue - update to Python 3.7 idioms (https://github.com/ansible-collections/community.general/pull/11343).
- gitlab_merge_request - update to Python 3.7 idioms (https://github.com/ansible-collections/community.general/pull/11343).
- gitlab_project - update to Python 3.7 idioms (https://github.com/ansible-collections/community.general/pull/11343).
- gunicorn - update to Python 3.7 idioms (https://github.com/ansible-collections/community.general/pull/11343).
- htpasswd - update to Python 3.7 idioms (https://github.com/ansible-collections/community.general/pull/11343).
- idrac_redfish_info - add multiple manager support to ``GetManagerAttributes``
command (https://github.com/ansible-collections/community.general/pull/11294).
- imc_rest - update to Python 3.7 idioms (https://github.com/ansible-collections/community.general/pull/11343).
- incus connection plugin - improve code readability (https://github.com/ansible-collections/community.general/pull/11346).
- incus connection plugin - simplify regular expression matching commands
(https://github.com/ansible-collections/community.general/pull/11347).
- ini_file - update to Python 3.7 idioms (https://github.com/ansible-collections/community.general/pull/11343).
- interfaces_file - update to Python 3.7 idioms (https://github.com/ansible-collections/community.general/pull/11343).
- iptables_state - update to Python 3.7 idioms (https://github.com/ansible-collections/community.general/pull/11343).
- jail connection plugin - update to Python 3.7 idioms (https://github.com/ansible-collections/community.general/pull/11341).
- jenkins_credential - update to Python 3.7 idioms (https://github.com/ansible-collections/community.general/pull/11343).
- jenkins_plugin - update to Python 3.7 idioms (https://github.com/ansible-collections/community.general/pull/11343).
- jenkins_script - move ``import`` statemetns to the top of the file (https://github.com/ansible-collections/community.general/pull/11396).
- kdeconfig - update to Python 3.7 idioms (https://github.com/ansible-collections/community.general/pull/11343).
- known_hosts module utils - update to Python 3.7 idioms (https://github.com/ansible-collections/community.general/pull/11341).
- layman - update to Python 3.7 idioms (https://github.com/ansible-collections/community.general/pull/11343).
- linode - move ``import`` statemetns to the top of the file (https://github.com/ansible-collections/community.general/pull/11396).
- linode inventory plugin - update to Python 3.7 idioms (https://github.com/ansible-collections/community.general/pull/11341).
- listen_ports_facts - update to Python 3.7 idioms (https://github.com/ansible-collections/community.general/pull/11343).
- locale_gen - update to Python 3.7 idioms (https://github.com/ansible-collections/community.general/pull/11343).
- logentries callback plugin - update to Python 3.7 idioms (https://github.com/ansible-collections/community.general/pull/11341).
- lvm_pv - update to Python 3.7 idioms (https://github.com/ansible-collections/community.general/pull/11343).
- lxc connection plugin - update to Python 3.7 idioms (https://github.com/ansible-collections/community.general/pull/11341).
- lxd inventory plugin - update to Python 3.7 idioms (https://github.com/ansible-collections/community.general/pull/11341).
- lxd module utils - update to Python 3.7 idioms (https://github.com/ansible-collections/community.general/pull/11341).
- manageiq module utils - update to Python 3.7 idioms (https://github.com/ansible-collections/community.general/pull/11341).
- manageiq_alert_profiles - update to Python 3.7 idioms (https://github.com/ansible-collections/community.general/pull/11344).
- modprobe - update to Python 3.7 idioms (https://github.com/ansible-collections/community.general/pull/11344).
- mssql_db - update to Python 3.7 idioms (https://github.com/ansible-collections/community.general/pull/11344).
- nagios - update to Python 3.7 idioms (https://github.com/ansible-collections/community.general/pull/11344).
- netcup_dns - support diff mode (https://github.com/ansible-collections/community.general/pull/11376).
- nmcli - add idempotency check (https://github.com/ansible-collections/community.general/pull/11114).
- nmcli - add support for IPv6 routing rules (https://github.com/ansible-collections/community.general/issues/7094,
https://github.com/ansible-collections/community.general/pull/11413).
- nosh - update to Python 3.7 idioms (https://github.com/ansible-collections/community.general/pull/11344).
- nsupdate - add support for server FQDN and the GSS-TSIG key algorithm (https://github.com/ansible-collections/community.general/issues/5730,
https://github.com/ansible-collections/community.general/pull/11425).
- nsupdate modules plugin - replace aliased errors with proper Python error
(https://github.com/ansible-collections/community.general/pull/11391).
- oci_utils module utils - update to Python 3.7 idioms (https://github.com/ansible-collections/community.general/pull/11341).
- omapi_host - update to Python 3.7 idioms (https://github.com/ansible-collections/community.general/pull/11344).
- one_image - move ``import`` statemetns to the top of the file (https://github.com/ansible-collections/community.general/pull/11396).
- one_image_info - move ``import`` statemetns to the top of the file (https://github.com/ansible-collections/community.general/pull/11396).
- one_service - move ``import`` statemetns to the top of the file (https://github.com/ansible-collections/community.general/pull/11396).
- one_vm - move ``import`` statemetns to the top of the file (https://github.com/ansible-collections/community.general/pull/11396).
- one_vm - update to Python 3.7 idioms (https://github.com/ansible-collections/community.general/pull/11344).
- opennebula inventory plugin - update to Python 3.7 idioms (https://github.com/ansible-collections/community.general/pull/11341).
- pam_limits - update to Python 3.7 idioms (https://github.com/ansible-collections/community.general/pull/11344).
- pamd - update to Python 3.7 idioms (https://github.com/ansible-collections/community.general/pull/11344).
- parted - update to Python 3.7 idioms (https://github.com/ansible-collections/community.general/pull/11344).
- pmem - simplify text tests without using regular expression (https://github.com/ansible-collections/community.general/pull/11388).
- pubnub_blocks - update to Python 3.7 idioms (https://github.com/ansible-collections/community.general/pull/11344).
- pulp_repo - update to Python 3.7 idioms (https://github.com/ansible-collections/community.general/pull/11344).
- read_csv - update to Python 3.7 idioms (https://github.com/ansible-collections/community.general/pull/11344).
- redfish_utils module utils - adds support of ``@Redfish.Settings`` in ``ComputerSystem``
attributes for ``set_boot_override`` function (https://github.com/ansible-collections/community.general/issues/11297,
https://github.com/ansible-collections/community.general/pull/11322).
- redhat_subscription - update to Python 3.7 idioms (https://github.com/ansible-collections/community.general/pull/11344).
- rhsm_repository - update to Python 3.7 idioms (https://github.com/ansible-collections/community.general/pull/11344).
- runit - update to Python 3.7 idioms (https://github.com/ansible-collections/community.general/pull/11344).
- scaleway_ip - added ``project`` parameter (https://github.com/ansible-collections/community.general/issues/11367,
https://github.com/ansible-collections/community.general/pull/11368).
- scaleway_security_group - added ``project`` parameter (https://github.com/ansible-collections/community.general/issues/11364,
https://github.com/ansible-collections/community.general/pull/11366).
- sensu_check - update to Python 3.7 idioms (https://github.com/ansible-collections/community.general/pull/11344).
- sensu_client - update to Python 3.7 idioms (https://github.com/ansible-collections/community.general/pull/11344).
- sensu_handler - update to Python 3.7 idioms (https://github.com/ansible-collections/community.general/pull/11344).
- sensu_subscription - update to Python 3.7 idioms (https://github.com/ansible-collections/community.general/pull/11344).
- seport - update to Python 3.7 idioms (https://github.com/ansible-collections/community.general/pull/11344).
- serverless - update to Python 3.7 idioms (https://github.com/ansible-collections/community.general/pull/11344).
- slackpkg - refactor function ``query_packages()`` (https://github.com/ansible-collections/community.general/pull/11390).
- solaris_zone - update to Python 3.7 idioms (https://github.com/ansible-collections/community.general/pull/11344).
- sorcery - update to Python 3.7 idioms (https://github.com/ansible-collections/community.general/pull/11344).
- spotinst_aws_elastigroup - update to Python 3.7 idioms (https://github.com/ansible-collections/community.general/pull/11344).
- sudoers - update to Python 3.7 idioms (https://github.com/ansible-collections/community.general/pull/11344).
- svc - update to Python 3.7 idioms (https://github.com/ansible-collections/community.general/pull/11344).
- timestamp callback plugin - update to Python 3.7 idioms (https://github.com/ansible-collections/community.general/pull/11341).
- timezone - update to Python 3.7 idioms (https://github.com/ansible-collections/community.general/pull/11344).
- univention_umc module utils - update to Python 3.7 idioms (https://github.com/ansible-collections/community.general/pull/11341).
- wakeonlan - update to Python 3.7 idioms (https://github.com/ansible-collections/community.general/pull/11344).
- wsl connection plugin - add option ``wsl_remote_ssh_shell_type``. Support
PowerShell in addition to cmd as the Windows shell (https://github.com/ansible-collections/community.general/issues/11307,
https://github.com/ansible-collections/community.general/pull/11308).
- wsl connection plugin - replace aliased errors with proper Python error
(https://github.com/ansible-collections/community.general/pull/11391).
- wsl connection plugin - update to Python 3.7 idioms (https://github.com/ansible-collections/community.general/pull/11341).
- xfs_quota - update to Python 3.7 idioms (https://github.com/ansible-collections/community.general/pull/11344).
- yaml cache plugin - update to Python 3.7 idioms (https://github.com/ansible-collections/community.general/pull/11341).
- zone connection plugin - update to Python 3.7 idioms (https://github.com/ansible-collections/community.general/pull/11341).
- zypper - update to Python 3.7 idioms (https://github.com/ansible-collections/community.general/pull/11344).
- zypper_repository - update to Python 3.7 idioms (https://github.com/ansible-collections/community.general/pull/11344).
release_summary: Regular feature and bugfix release.
fragments:
- 11114-nmcli-idempotency.yml
- 11301-idrac-info-multi-manager.yml
- 11308-wsl-shell-type.yml
- 11322-handle-redfish-settings-in-setbootoverride.yml
- 11340-cronvar-simplify-exc.yml
- 11341-pyupgrade-1.yml
- 11343-pyupgrade-3.yml
- 11344-pyupgrade-4.yml
- 11346-incus-readability.yml
- 11347-incus-regex.yml
- 11366-scaleway-sg-project-param.yml
- 11368-scaleway-ip-project-param.yml
- 11376-netcup-dns-diff-mode.yml
- 11377-cloudflare_dns-caa.yml
- 11388-pmem-redundant-regexps.yml
- 11390-slackpkg-query.yml
- 11391-ruff-cases-11.yml
- 11396-in-def-imports.yml
- 11413-nmcli-routing-rules6.yml
- 11425-nsupdate-gss-tsig.yml
- 11440-logstash-plugin-fix-version-argument-order.yml
- 11442-gem-module-ruby-4.yml
- 11443-fix-keycloak-client-diff-for-null-attributes.yml
- 12.3.0.yml
plugins:
filter:
- description: Convert variable to TOML string.
name: to_toml
namespace: null
release_date: '2026-01-26'
12.4.0:
changes:
bugfixes:
- keycloak module utils - fix ``TypeError`` crash when managing users whose
username or email contains special characters such as ``+`` (https://github.com/ansible-collections/community.general/issues/10305,
https://github.com/ansible-collections/community.general/pull/11472).
- keycloak module utils - use proper URL encoding (``urllib.parse.quote``)
for query parameters in authorization permission name searches, replacing
fragile manual space replacement (https://github.com/ansible-collections/community.general/pull/11472).
- keycloak_client - fix idempotency bug caused by ``null`` flow overrides
value differences for non-existing flow overrides (https://github.com/ansible-collections/community.general/issues/11430,
https://github.com/ansible-collections/community.general/pull/11455).
- keycloak_client - remove IDs as change from diff result for protocol mappers
(https://github.com/ansible-collections/community.general/issues/11453,
https://github.com/ansible-collections/community.general/pull/11454).
- keycloak_realm_key - fix ``KeyError`` crash when managing realm keys where
Keycloak does not return ``active``, ``enabled``, or ``algorithm`` fields
in the config response (https://github.com/ansible-collections/community.general/issues/11459,
https://github.com/ansible-collections/community.general/pull/11470).
- keycloak_user_federation - mapper config item can be an array (https://github.com/ansible-collections/community.general/issues/11502,
https://github.com/ansible-collections/community.general/pull/11515).
- keycloak_user_rolemapping - fix ``TypeError`` crash when adding a client
role to a user who has no existing roles for that client (https://github.com/ansible-collections/community.general/issues/10960,
https://github.com/ansible-collections/community.general/pull/11471).
- maven_artifact - fix SNAPSHOT version resolution to pick the newest matching
``<snapshotVersion>`` entry by ``<updated>`` timestamp instead of the first.
Repositories like GitHub Packages keep all historical entries in ``<snapshotVersions>``
(oldest first), causing the module to resolve to the oldest snapshot instead
of the latest (https://github.com/ansible-collections/community.general/issues/5117,
https://github.com/ansible-collections/community.general/issues/11489, https://github.com/ansible-collections/community.general/pull/11501).
- nsupdate - fix ``AttributeError`` when using the module without TSIG authentication
(https://github.com/ansible-collections/community.general/issues/11460,
https://github.com/ansible-collections/community.general/pull/11461).
- python_requirements_info - use ``importlib.metadata`` if ``pkg_resources``
from ``setuptools`` cannot be imported. That module has been removed from
setuptools 82.0.0 (https://github.com/ansible-collections/community.general/issues/11491,
https://github.com/ansible-collections/community.general/pull/11492).
- splunk callback plugin - replace deprecated callback function (https://github.com/ansible-collections/community.general/pull/11485).
minor_changes:
- ModuleHelper module utils - allow to ignore specific exceptions in ``module_fails_on_exception``
decorator (https://github.com/ansible-collections/community.general/pull/11488).
- from_ini filter plugin - add ``delimiters`` parameter to allow correctly
parsing more INI documents (https://github.com/ansible-collections/community.general/issues/11506,
https://github.com/ansible-collections/community.general/pull/11512).
- keycloak_client - add ``valid_post_logout_redirect_uris`` option to configure
post logout redirect URIs for a client, and ``backchannel_logout_url`` option
to configure the backchannel logout URL for a client (https://github.com/ansible-collections/community.general/issues/6812,
https://github.com/ansible-collections/community.general/issues/4892, https://github.com/ansible-collections/community.general/pull/11473).
- keycloak_client_rolemapping, keycloak_realm_rolemapping, keycloak_group
- optimize retrieval of groups by name to use Keycloak search API with exact
matching instead of fetching all groups (https://github.com/ansible-collections/community.general/pull/11503).
- keycloak_realm - add support for ``localizationTexts`` option in Keycloak
realms (https://github.com/ansible-collections/community.general/pull/11513).
- keycloak_realm_key - add support for auto-generated key providers (``rsa-generated``,
``rsa-enc-generated``, ``hmac-generated``, ``aes-generated``, ``ecdsa-generated``,
``ecdh-generated``, ``eddsa-generated``), ``java-keystore`` provider, additional
algorithms (HMAC, ECDSA, ECDH, EdDSA, AES), and new config options (``secret_size``,
``key_size``, ``elliptic_curve``, ``keystore``, ``keystore_password``, ``key_alias``,
``key_password``). Also makes ``config.private_key`` and ``config.certificate``
optional as they are only required for imported key providers (https://github.com/ansible-collections/community.general/pull/11468).
- redfish_info - add Redfish Root data to results of successful ``CheckAvailability``
command (https://github.com/ansible-collections/community.general/pull/11504).
- seport - adds support for DCCP and SCTP protocols (https://github.com/ansible-collections/community.general/pull/11486).
release_summary: Regular bugfix and feature release.
fragments:
- 11430-fix-keycloak-client-diff-for-flow-overrides.yml
- 11453-keycloak-client-protocol-mapper-ids.yml
- 11485-avoid-deprected-callback.yml
- 11486-seport-dccp-sctp.yaml
- 11488-mh-ensure-compatibiliy-with-module-tests.yml
- 11492-python_requires_info.yml
- 11502-keycloak-config-mapper.yaml
- 11503-keycloak-group-search-optimization.yml
- 11504-redfish-info-add-results-to-return.yml
- 11512-from_ini-delimiters.yaml
- 11513-keycloak-realm-localizationTexts-support.yml
- 12.4.0.yml
- 5117-maven-artifact-snapshot-resolution.yml
- fix-nsupdate-keyring.yml
- keycloak-client-add-missing-fields.yml
- keycloak-realm-key-generated-providers.yml
- keycloak-realm-key-keyerror-bugfix.yml
- keycloak-url-encode-query-params.yml
- keycloak-user-rolemapping-client-none-check.yml
modules:
- description: Manages Icinga 2 downtimes.
name: icinga2_downtime
namespace: ''
- description: Allows management of Keycloak realm localization overrides via
the Keycloak API.
name: keycloak_realm_localization
namespace: ''
plugins:
callback:
- description: Posts task results to an Azure Log Analytics workspace using
the new Logs Ingestion API.
name: loganalytics_ingestion
namespace: null
release_date: '2026-02-23'

View File

@@ -6,7 +6,7 @@
import sys
from io import StringIO
from ruamel.yaml import YAML
from ruamel.yaml import YAML # type: ignore[import-not-found]
def main() -> None:

View File

@@ -5,7 +5,7 @@
namespace: community
name: general
version: 12.2.0
version: 12.4.0
readme: README.md
authors:
- Ansible (https://github.com/ansible)
@@ -19,3 +19,5 @@ repository: https://github.com/ansible-collections/community.general
documentation: https://docs.ansible.com/projects/ansible/latest/collections/community/general/
homepage: https://github.com/ansible-collections/community.general
issues: https://github.com/ansible-collections/community.general/issues
build_ignore:
- .nox

View File

@@ -40,6 +40,7 @@ action_groups:
- keycloak_realm
- keycloak_realm_key
- keycloak_realm_keys_metadata_info
- keycloak_realm_localization
- keycloak_realm_rolemapping
- keycloak_role
- keycloak_user
@@ -378,6 +379,10 @@ plugin_routing:
warning_text: Use community.general.idrac_redfish_info instead.
idrac_server_config_profile:
redirect: dellemc.openmanage.idrac_server_config_profile
jboss:
deprecation:
removal_version: 14.0.0
warning_text: Use role middleware_automation.wildfly.wildfly_app_deploy instead.
jenkins_job_facts:
tombstone:
removal_version: 3.0.0

View File

@@ -9,14 +9,14 @@
import os
import sys
import nox
import nox # type: ignore[import-not-found]
# Whether the noxfile is running in CI:
IN_CI = os.environ.get("CI") == "true"
try:
import antsibull_nox
import antsibull_nox # type: ignore[import-not-found]
except ImportError:
print("You need to install antsibull-nox in the same Python environment as nox.")
sys.exit(1)

View File

@@ -7,10 +7,10 @@ from __future__ import annotations
import time
import typing as t
from ansible.plugins.action import ActionBase
from ansible.errors import AnsibleActionFail, AnsibleConnectionFailure
from ansible.utils.vars import merge_hash
from ansible.plugins.action import ActionBase
from ansible.utils.display import Display
from ansible.utils.vars import merge_hash
display = Display()

View File

@@ -6,12 +6,11 @@
from __future__ import annotations
import typing as t
from ansible.errors import AnsibleError, AnsibleConnectionFailure
from ansible.module_utils.common.text.converters import to_native, to_text
from ansible.errors import AnsibleConnectionFailure, AnsibleError
from ansible.module_utils.common.collections import is_string
from ansible.module_utils.common.text.converters import to_native, to_text
from ansible.plugins.action import ActionBase
from ansible.utils.display import Display

View File

@@ -92,9 +92,8 @@ EXAMPLES = r"""
from re import compile as re_compile
from ansible.plugins.become import BecomeBase
from ansible.module_utils.common.text.converters import to_bytes
from ansible.plugins.become import BecomeBase
ansi_color_codes = re_compile(to_bytes(r"\x1B\[[0-9;]+m"))

View File

@@ -59,6 +59,7 @@ notes:
"""
from shlex import quote as shlex_quote
from ansible.plugins.become import BecomeBase

View File

@@ -4,7 +4,6 @@
from __future__ import annotations
DOCUMENTATION = r"""
name: run0
short_description: Systemd's run0
@@ -78,8 +77,8 @@ EXAMPLES = r"""
from re import compile as re_compile
from ansible.plugins.become import BecomeBase
from ansible.module_utils.common.text.converters import to_bytes
from ansible.plugins.become import BecomeBase
ansi_color_codes = re_compile(to_bytes(r"\x1B\[[0-9;]+m"))

View File

@@ -49,11 +49,11 @@ options:
import collections
import os
import time
from multiprocessing import Lock
from collections.abc import MutableSet
from itertools import chain
from multiprocessing import Lock
from ansible.errors import AnsibleError
from collections.abc import MutableSet
from ansible.plugins.cache import BaseCacheModule
from ansible.utils.display import Display

View File

@@ -66,17 +66,17 @@ options:
section: defaults
"""
import json
import re
import time
import json
from ansible.errors import AnsibleError
from ansible.parsing.ajson import AnsibleJSONEncoder, AnsibleJSONDecoder
from ansible.parsing.ajson import AnsibleJSONDecoder, AnsibleJSONEncoder
from ansible.plugins.cache import BaseCacheModule
from ansible.utils.display import Display
try:
from redis import StrictRedis, VERSION
from redis import VERSION, StrictRedis
HAS_REDIS = True
except ImportError:

View File

@@ -46,9 +46,8 @@ options:
import os
import yaml
from ansible.parsing.yaml.loader import AnsibleLoader
from ansible.parsing.yaml.dumper import AnsibleDumper
from ansible.parsing.yaml.loader import AnsibleLoader
from ansible.plugins.cache import BaseFileCacheModule
@@ -58,7 +57,7 @@ class CacheModule(BaseFileCacheModule):
"""
def _load(self, filepath):
with open(os.path.abspath(filepath), "r", encoding="utf-8") as f:
with open(os.path.abspath(filepath), encoding="utf-8") as f:
return AnsibleLoader(f).get_single_data()
def _dump(self, value, filepath):

View File

@@ -41,8 +41,8 @@ options:
key: cur_mem_file
"""
import time
import threading
import time
from ansible.plugins.callback import CallbackBase

View File

@@ -23,9 +23,9 @@ requirements:
"""
from ansible import constants as C
from ansible.playbook.task_include import TaskInclude
from ansible.plugins.callback import CallbackBase
from ansible.utils.color import colorize, hostcolor
from ansible.playbook.task_include import TaskInclude
class CallbackModule(CallbackBase):

View File

@@ -27,13 +27,13 @@ try:
except ImportError:
pass
import sys
from collections.abc import MutableMapping, MutableSequence
from ansible.plugins.callback.default import CallbackModule as CallbackModule_default
from ansible.utils.color import colorize, hostcolor
from ansible.utils.display import Display
import sys
display = Display()

View File

@@ -778,10 +778,11 @@ playbook.yml: >-
import sys
from contextlib import contextmanager
from ansible.module_utils.common.text.converters import to_text
from ansible.plugins.callback.default import CallbackModule as Default
from ansible.template import Templar
from ansible.vars.manager import VariableManager
from ansible.plugins.callback.default import CallbackModule as Default
from ansible.module_utils.common.text.converters import to_text
try:
from ansible.template import trust_as_template # noqa: F401, pylint: disable=unused-import

View File

@@ -81,7 +81,6 @@ import getpass
import socket
import time
import uuid
from collections import OrderedDict
from contextlib import closing
from os.path import basename
@@ -92,7 +91,7 @@ from ansible.plugins.callback import CallbackBase
ELASTIC_LIBRARY_IMPORT_ERROR: ImportError | None
try:
from elasticapm import Client, capture_span, trace_parent_from_string, instrument, label
from elasticapm import Client, capture_span, instrument, label, trace_parent_from_string
except ImportError as imp_exc:
ELASTIC_LIBRARY_IMPORT_ERROR = imp_exc
else:

View File

@@ -27,16 +27,15 @@ options:
key: log_folder
"""
import json
import os
import time
import json
from ansible.utils.path import makedirs_safe
from ansible.module_utils.common.text.converters import to_bytes
from collections.abc import MutableMapping
from ansible.module_utils.common.text.converters import to_bytes
from ansible.parsing.ajson import AnsibleJSONEncoder
from ansible.plugins.callback import CallbackBase
from ansible.utils.path import makedirs_safe
# NOTE: in Ansible 1.2 or later general logging is available without
# this plugin, just set ANSIBLE_LOG_PATH as an environment variable

View File

@@ -51,14 +51,13 @@ examples: |-
shared_key = dZD0kCbKl3ehZG6LHFMuhtE0yHiFCmetzFMc2u+roXIUQuatqU924SsAAAAPemhjbGlAemhjbGktTUJQAQIDBA==
"""
import base64
import getpass
import hashlib
import hmac
import base64
import json
import uuid
import socket
import getpass
import uuid
from os.path import basename
from ansible.module_utils.ansible_release import __version__ as ansible_version

View File

@@ -0,0 +1,340 @@
#!/usr/bin/env python
# Copyright (c) Ansible project
# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
# SPDX-License-Identifier: GPL-3.0-or-later
DOCUMENTATION = """
name: loganalytics_ingestion
type: notification
short_description: Posts task results to an Azure Log Analytics workspace using the new Logs Ingestion API
author:
- Wade Cline (@wtcline-intc) <wade.cline@intel.com>
- Sriramoju Vishal Bharath (@vsh47) <sriramoju.vishal.bharath@intel.com>
- Cyrus Li (@zhcli) <cyrus1006@gmail.com>
description:
- This callback plugin will post task results in JSON format to an Azure Log Analytics workspace using the new Logs Ingestion API.
version_added: "12.4.0"
requirements:
- The callback plugin has been enabled.
- An Azure Log Analytics workspace has been established.
- A Data Collection Rule (DCR) and custom table are created.
options:
dce_url:
description: URL of the Data Collection Endpoint (DCE) for Azure Logs Ingestion API.
type: str
required: true
env:
- name: ANSIBLE_LOGANALYTICS_DCE_URL
ini:
- section: callback_loganalytics
key: dce_url
dcr_id:
description: Data Collection Rule (DCR) ID for the Azure Log Ingestion API.
type: str
required: true
env:
- name: ANSIBLE_LOGANALYTICS_DCR_ID
ini:
- section: callback_loganalytics
key: dcr_id
disable_attempts:
description:
- When O(disable_on_failure=true), number of plugin failures that must occur before the plugin is disabled.
- This helps prevent outright plugin failure from a single, transient network issue.
type: int
default: 3
env:
- name: ANSIBLE_LOGANALYTICS_DISABLE_ATTEMPTS
ini:
- section: callback_loganalytics
key: disable_attempts
disable_on_failure:
description: Stop trying to send data on plugin failure.
type: bool
default: true
env:
- name: ANSIBLE_LOGANALYTICS_DISABLE_ON_FAILURE
ini:
- section: callback_loganalytics
key: disable_on_failure
client_id:
description: Client ID of the Azure App registration for OAuth2 authentication ("Modern Authentication").
type: str
required: true
env:
- name: ANSIBLE_LOGANALYTICS_CLIENT_ID
ini:
- section: callback_loganalytics
key: client_id
client_secret:
description: Client Secret of the Azure App registration.
type: str
required: true
env:
- name: ANSIBLE_LOGANALYTICS_CLIENT_SECRET
ini:
- section: callback_loganalytics
key: client_secret
include_content:
description: Send the content to the Azure Log Analytics workspace.
type: bool
default: false
env:
- name: ANSIBLE_LOGANALYTICS_INCLUDE_CONTENT
ini:
- section: callback_loganalytics
key: include_content
include_task_args:
description: Send the task args to the Azure Log Analytics workspace.
type: bool
default: false
env:
- name: ANSIBLE_LOGANALYTICS_INCLUDE_TASK_ARGS
ini:
- section: callback_loganalytics
key: include_task_args
stream_name:
description: The name of the stream used to send the logs to the Azure Log Analytics workspace.
type: str
required: true
env:
- name: ANSIBLE_LOGANALYTICS_STREAM_NAME
ini:
- section: callback_loganalytics
key: stream_name
tenant_id:
description: Tenant ID for the Azure Active Directory.
type: str
required: true
env:
- name: ANSIBLE_LOGANALYTICS_TENANT_ID
ini:
- section: callback_loganalytics
key: tenant_id
timeout:
description: Timeout for the HTTP requests to the Azure Log Analytics API.
type: int
default: 2
env:
- name: ANSIBLE_LOGANALYTICS_TIMEOUT
ini:
- section: callback_loganalytics
key: timeout
seealso:
- name: Logs Ingestion API
description: Overview of Logs Ingestion API in Azure Monitor
link: https://learn.microsoft.com/en-us/azure/azure-monitor/logs/logs-ingestion-api-overview
notes:
- Triple verbosity logging (C(-vvv)) can be used to generate JSON sample data for creating the table schema in Azure Log Analytics.
Search for the string C(Event Data:) in the output in order to locate the data sample.
"""
EXAMPLES = """
examples: |
Enable the plugin in ansible.cfg:
[defaults]
callback_enabled = community.general.loganalytics_ingestion
Set the environment variables:
export ANSIBLE_LOGANALYTICS_DCE_URL=https://my-dce.ingest.monitor.azure.com
export ANSIBLE_LOGANALYTICS_DCR_ID=dcr-xxxxxx
export ANSIBLE_LOGANALYTICS_CLIENT_ID=xxxxxxxx
export ANSIBLE_LOGANALYTICS_CLIENT_SECRET=xxxxxxxx
export ANSIBLE_LOGANALYTICS_TENANT_ID=xxxxxxxx
export ANSIBLE_LOGANALYTICS_STREAM_NAME=Custom-MyTable
"""
import getpass
import json
import socket
import uuid
from datetime import datetime, timedelta, timezone
from os.path import basename
from urllib.parse import urlencode
from ansible.module_utils.urls import open_url
from ansible.plugins.callback import CallbackBase
from ansible.utils.display import Display
display = Display()
class AzureLogAnalyticsIngestionSource:
def __init__(
self,
dce_url,
dcr_id,
disable_attempts,
disable_on_failure,
client_id,
client_secret,
tenant_id,
stream_name,
include_task_args,
include_content,
timeout,
fqcn,
):
self.dce_url = dce_url
self.dcr_id = dcr_id
self.disabled = False
self.disable_attempts = disable_attempts
self.disable_on_failure = disable_on_failure
self.client_id = client_id
self.client_secret = client_secret
self.failures = 0
self.tenant_id = tenant_id
self.stream_name = stream_name
self.include_task_args = include_task_args
self.include_content = include_content
self.token_expiration_time = None
self.session = str(uuid.uuid4())
self.host = socket.gethostname()
self.user = getpass.getuser()
self.timeout = timeout
self.fqcn = fqcn
self.bearer_token = self.get_bearer_token()
# OAuth2 authentication method to get a Bearer token
# This replaces the shared_key authentication mechanism
def get_bearer_token(self):
url = f"https://login.microsoftonline.com/{self.tenant_id}/oauth2/v2.0/token"
headers = {"Content-Type": "application/x-www-form-urlencoded"}
data = urlencode(
{
"grant_type": "client_credentials",
"client_id": self.client_id,
"client_secret": self.client_secret,
# The scope value comes from https://learn.microsoft.com/en-us/azure/azure-monitor/logs/logs-ingestion-api-overview#headers
# and https://learn.microsoft.com/en-us/entra/identity-platform/scopes-oidc#the-default-scope
"scope": "https://monitor.azure.com/.default",
}
)
response = open_url(url, data=data, force=True, headers=headers, method="POST", timeout=self.timeout)
j = json.loads(response.read().decode("utf-8"))
self.token_expiration_time = datetime.now() + timedelta(seconds=j.get("expires_in"))
return j.get("access_token")
def is_token_valid(self):
return datetime.now() + timedelta(seconds=10) < self.token_expiration_time
# Method to send event data to the Azure Logs Ingestion API
# This replaces the legacy API call and now uses the Logs Ingestion API endpoint
def send_event(self, event_data):
if not self.is_token_valid():
self.bearer_token = self.get_bearer_token()
ingestion_url = (
f"{self.dce_url}/dataCollectionRules/{self.dcr_id}/streams/{self.stream_name}?api-version=2023-01-01"
)
headers = {"Authorization": f"Bearer {self.bearer_token}", "Content-Type": "application/json"}
open_url(ingestion_url, data=json.dumps(event_data), headers=headers, method="POST", timeout=self.timeout)
def _rfc1123date(self):
return datetime.now(timezone.utc).strftime("%a, %d %b %Y %H:%M:%S GMT")
# This method wraps the private method with the appropriate error handling.
def send_to_loganalytics(self, playbook_name, result, state):
if self.disabled:
return
try:
self._send_to_loganalytics(playbook_name, result, state)
except Exception as e:
display.warning(f"{self.fqcn} callback plugin failure: {e}.")
if self.disable_on_failure:
self.failures += 1
if self.failures >= self.disable_attempts:
display.warning(
f"{self.fqcn} callback plugin failures exceed maximum of '{self.disable_attempts}'! Disabling plugin!"
)
self.disabled = True
else:
display.v(f"{self.fqcn} callback plugin failure {self.failures}/{self.disable_attempts}")
def _send_to_loganalytics(self, playbook_name, result, state):
ansible_role = str(result._task._role) if result._task._role else None
# Include/Exclude task args
if not self.include_task_args:
result._task_fields.pop("args", None)
# Include/Exclude content
if not self.include_content:
result._result.pop("content", None)
# Build the event data
event_data = [
{
"TimeGenerated": self._rfc1123date(),
"Host": result._host.name,
"User": self.user,
"Playbook": playbook_name,
"Role": ansible_role,
"TaskName": result._task.get_name(),
"Task": result._task_fields,
"Action": result._task_fields["action"],
"State": state,
"Result": result._result,
"Session": self.session,
}
]
# The data displayed here can be used as a sample file in order to create the table's schema.
display.vvv(f"Event Data: {json.dumps(event_data)}")
self.send_event(event_data)
class CallbackModule(CallbackBase):
CALLBACK_VERSION = 2.0
CALLBACK_TYPE = "notification"
CALLBACK_NAME = "loganalytics_ingestion"
CALLBACK_NEEDS_ENABLED = True
def __init__(self, display=None):
super().__init__(display=display)
self.start_datetimes = {}
self.playbook_name = None
self.azure_loganalytics = None
self.fqcn = f"community.general.{self.CALLBACK_NAME}"
def set_options(self, task_keys=None, var_options=None, direct=None):
super().set_options(task_keys=task_keys, var_options=var_options, direct=direct)
# Set options for the new Azure Logs Ingestion API configuration
self.client_id = self.get_option("client_id")
self.client_secret = self.get_option("client_secret")
self.dce_url = self.get_option("dce_url")
self.dcr_id = self.get_option("dcr_id")
self.disable_attempts = self.get_option("disable_attempts")
self.disable_on_failure = self.get_option("disable_on_failure")
self.include_content = self.get_option("include_content")
self.include_task_args = self.get_option("include_task_args")
self.stream_name = self.get_option("stream_name")
self.tenant_id = self.get_option("tenant_id")
self.timeout = self.get_option("timeout")
# Initialize the AzureLogAnalyticsIngestionSource with the new settings
self.azure_loganalytics = AzureLogAnalyticsIngestionSource(
self.dce_url,
self.dcr_id,
self.disable_attempts,
self.disable_on_failure,
self.client_id,
self.client_secret,
self.tenant_id,
self.stream_name,
self.include_task_args,
self.include_content,
self.timeout,
self.fqcn,
)
def v2_playbook_on_start(self, playbook):
self.playbook_name = basename(playbook._file_name)
# Build event data and send it to the Logs Ingestion API
def v2_runner_on_failed(self, result, **kwargs):
self.azure_loganalytics.send_to_loganalytics(self.playbook_name, result, "FAILED")
def v2_runner_on_ok(self, result, **kwargs):
self.azure_loganalytics.send_to_loganalytics(self.playbook_name, result, "OK")

View File

@@ -55,12 +55,13 @@ options:
default: ansible
"""
import logging
import json
import logging
import socket
from uuid import getnode
from ansible.plugins.callback import CallbackBase
from ansible.parsing.ajson import AnsibleJSONEncoder
from ansible.plugins.callback import CallbackBase
try:
from logdna import LogDNAHandler

View File

@@ -96,8 +96,8 @@ examples: >-
"""
import os
import socket
import random
import socket
import time
import uuid
@@ -178,7 +178,7 @@ class PlainTextSocketAppender:
while True:
try:
self._conn.send(to_bytes(multiline, errors="surrogate_or_strict"))
except socket.error:
except OSError:
self.reopen_connection()
continue
break

View File

@@ -94,12 +94,13 @@ ansible.cfg: |
}
"""
import os
import json
from ansible import context
import logging
import os
import socket
import uuid
import logging
from ansible import context
try:
import logstash

View File

@@ -79,10 +79,10 @@ options:
version_added: 8.2.0
"""
import email.utils
import json
import os
import re
import email.utils
import smtplib
from ansible.module_utils.common.text.converters import to_bytes

View File

@@ -148,15 +148,15 @@ from ansible.plugins.callback import CallbackBase
OTEL_LIBRARY_IMPORT_ERROR: ImportError | None
try:
from opentelemetry import trace
from opentelemetry.trace import SpanKind
from opentelemetry.exporter.otlp.proto.grpc.trace_exporter import OTLPSpanExporter as GRPCOTLPSpanExporter
from opentelemetry.exporter.otlp.proto.http.trace_exporter import OTLPSpanExporter as HTTPOTLPSpanExporter
from opentelemetry.sdk.resources import SERVICE_NAME, Resource
from opentelemetry.trace.status import Status, StatusCode
from opentelemetry.trace.propagation.tracecontext import TraceContextTextMapPropagator
from opentelemetry.sdk.trace import TracerProvider
from opentelemetry.sdk.trace.export import BatchSpanProcessor, SimpleSpanProcessor
from opentelemetry.sdk.trace.export.in_memory_span_exporter import InMemorySpanExporter
from opentelemetry.trace import SpanKind
from opentelemetry.trace.propagation.tracecontext import TraceContextTextMapPropagator
from opentelemetry.trace.status import Status, StatusCode
except ImportError as imp_exc:
OTEL_LIBRARY_IMPORT_ERROR = imp_exc
else:

View File

@@ -22,7 +22,7 @@ ansible.cfg: |-
callbacks_enabled=community.general.print_task
"""
from yaml import load, dump
from yaml import dump, load
try:
from yaml import CSafeDumper as SafeDumper

View File

@@ -18,9 +18,9 @@ description:
- This plugin uses C(say) or C(espeak) to "speak" about play events.
"""
import os
import platform
import subprocess
import os
from ansible.module_utils.common.process import get_bin_path
from ansible.plugins.callback import CallbackBase

View File

@@ -39,9 +39,8 @@ EXAMPLES = r"""
import difflib
from ansible import constants as C
from ansible.plugins.callback import CallbackBase
from ansible.module_utils.common.text.converters import to_text
from ansible.plugins.callback import CallbackBase
DONT_COLORIZE = False
COLORS = {

View File

@@ -83,11 +83,10 @@ examples: >-
authtoken = f23blad6-5965-4537-bf69-5b5a545blabla88
"""
import json
import uuid
import socket
import getpass
import json
import socket
import uuid
from os.path import basename
from ansible.module_utils.ansible_release import __version__ as ansible_version
@@ -255,7 +254,7 @@ class CallbackModule(CallbackBase):
self._runtime(result),
)
def runner_on_async_failed(self, result, **kwargs):
def v2_runner_on_async_failed(self, result, **kwargs):
self.splunk.send_event(
self.url,
self.authtoken,

View File

@@ -40,11 +40,10 @@ examples: |-
url = https://endpoint1.collection.us2.sumologic.com/receiver/v1/http/R8moSv1d8EW9LAUFZJ6dbxCFxwLH6kfCdcBfddlfxCbLuL-BN5twcTpMk__pYy_cDmp==
"""
import json
import uuid
import socket
import getpass
import json
import socket
import uuid
from os.path import basename
from ansible.module_utils.ansible_release import __version__ as ansible_version

View File

@@ -56,7 +56,6 @@ options:
import logging
import logging.handlers
import socket
from ansible.plugins.callback import CallbackBase

View File

@@ -5,7 +5,6 @@
from __future__ import annotations
DOCUMENTATION = r"""
name: timestamp
type: stdout
@@ -49,12 +48,13 @@ extends_documentation_fragment:
"""
import sys
import types
from datetime import datetime
from ansible.module_utils.common.text.converters import to_text
from ansible.plugins.callback.default import CallbackModule as Default
from ansible.utils.display import get_text_width
from ansible.module_utils.common.text.converters import to_text
from datetime import datetime
import types
import sys
# Store whether the zoneinfo module is available
_ZONEINFO_AVAILABLE = sys.version_info >= (3, 9)
@@ -89,7 +89,7 @@ def banner(self, msg, color=None, cows=True):
msg = msg.strip()
try:
star_len = self.columns - get_text_width(msg) - timestamp_len
except EnvironmentError:
except OSError:
star_len = self.columns - len(msg) - timestamp_len
if star_len <= 3:
star_len = 3

View File

@@ -20,11 +20,12 @@ requirements:
"""
from os.path import basename
from ansible import constants as C
from ansible import context
from ansible.module_utils.common.text.converters import to_text
from ansible.utils.color import colorize, hostcolor
from ansible.plugins.callback.default import CallbackModule as CallbackModule_default
from ansible.utils.color import colorize, hostcolor
class CallbackModule(CallbackModule_default):

View File

@@ -80,7 +80,7 @@ from ansible.errors import AnsibleError
from ansible.module_utils.basic import is_executable
from ansible.module_utils.common.process import get_bin_path
from ansible.module_utils.common.text.converters import to_bytes
from ansible.plugins.connection import ConnectionBase, BUFSIZE
from ansible.plugins.connection import BUFSIZE, ConnectionBase
from ansible.utils.display import Display
display = Display()
@@ -200,7 +200,7 @@ class Connection(ConnectionBase):
raise AnsibleError(f"failed to transfer file {in_path} to {out_path}") from e
if p.returncode != 0:
raise AnsibleError(f"failed to transfer file {in_path} to {out_path}:\n{stdout}\n{stderr}")
except IOError as e:
except OSError as e:
raise AnsibleError(f"file or module does not exist at: {in_path}") from e
def fetch_file(self, in_path, out_path):

View File

@@ -35,8 +35,8 @@ except ImportError:
pass
import os
import tempfile
import shutil
import tempfile
from ansible.errors import AnsibleError
from ansible.plugins.connection import ConnectionBase

View File

@@ -79,9 +79,9 @@ options:
import os
import re
from subprocess import call, Popen, PIPE
from subprocess import PIPE, Popen, call
from ansible.errors import AnsibleError, AnsibleConnectionFailure, AnsibleFileNotFound
from ansible.errors import AnsibleConnectionFailure, AnsibleError, AnsibleFileNotFound
from ansible.module_utils.common.process import get_bin_path
from ansible.module_utils.common.text.converters import to_bytes, to_text
from ansible.plugins.connection import ConnectionBase
@@ -104,11 +104,11 @@ class Connection(ConnectionBase):
if getattr(self._shell, "_IS_WINDOWS", False):
# Initializing regular expression patterns to match on a PowerShell or cmd command line.
self.powershell_regex_pattern = re.compile(
r"^(?P<executable>(\"?([a-z]:)?[a-z0-9 ()\\.]+)?powershell(\.exe)?\"?|(([a-z]:)?[a-z0-9()\\.]+)?powershell(\.exe)?)\s+.*(?P<command>-c(ommand)?)\s+", # noqa: E501
r'^"?(?P<executable>(?:[a-z]:\\)?[a-z0-9 ()\\.]*powershell(?:\.exe)?)"?\s+(?P<args>.*)(?P<command>-c(?:ommand)?)\s+(?P<post_args>.*(\n.*)*)',
re.IGNORECASE,
)
self.cmd_regex_pattern = re.compile(
r"^(?P<executable>(\"?([a-z]:)?[a-z0-9 ()\\.]+)?cmd(\.exe)?\"?|(([a-z]:)?[a-z0-9()\\.]+)?cmd(\.exe)?)\s+.*(?P<command>/c)\s+",
r'^"?(?P<executable>(?:[a-z]:\\)?[a-z0-9 ()\\.]*cmd(?:\.exe)?)"?\s+(?P<args>.*)(?P<command>/c)\s+(?P<post_args>.*)',
re.IGNORECASE,
)
@@ -142,30 +142,25 @@ class Connection(ConnectionBase):
]
if getattr(self._shell, "_IS_WINDOWS", False):
if (
(regex_match := self.powershell_regex_pattern.match(cmd))
and (regex_pattern := self.powershell_regex_pattern)
) or ((regex_match := self.cmd_regex_pattern.match(cmd)) and (regex_pattern := self.cmd_regex_pattern)):
if regex_match := self.powershell_regex_pattern.match(cmd):
regex_pattern = self.powershell_regex_pattern
elif regex_match := self.cmd_regex_pattern.match(cmd):
regex_pattern = self.cmd_regex_pattern
if regex_match:
self._display.vvvvvv(
f'Found keyword: "{regex_match.group("command")}" based on regex: {regex_pattern.pattern}',
host=self._instance(),
)
# Split the command on the argument -c(ommand) for PowerShell or /c for cmd.
before_command_argument, after_command_argument = cmd.split(regex_match.group("command"), 1)
exec_cmd.extend(
[
# To avoid splitting on a space contained in the path, set the executable as the first argument.
regex_match.group("executable").strip('"'),
# Remove the executable path and split the rest by space.
*(before_command_argument[len(regex_match.group("executable")) :].lstrip().split(" ")),
# Set the command argument depending on cmd or powershell.
regex_match.group("command"),
# Add the rest of the command at the end.
after_command_argument,
]
)
# To avoid splitting on a space contained in the path, set the executable as the first argument.
exec_cmd.append(regex_match.group("executable"))
if args := regex_match.group("args"):
exec_cmd.extend(args.strip().split(" "))
# Set the command argument depending on cmd or powershell and the rest of it
exec_cmd.append(regex_match.group("command"))
if post_args := regex_match.group("post_args"):
exec_cmd.append(post_args.strip())
else:
# For anything else using -EncodedCommand or else, just split on space.
exec_cmd.extend(cmd.split(" "))

View File

@@ -33,11 +33,12 @@ options:
import subprocess
from ansible_collections.community.general.plugins.connection.jail import Connection as Jail
from ansible.module_utils.common.text.converters import to_native
from ansible.errors import AnsibleError
from ansible.module_utils.common.text.converters import to_native
from ansible.utils.display import Display
from ansible_collections.community.general.plugins.connection.jail import Connection as Jail
display = Display()

View File

@@ -42,7 +42,7 @@ from shlex import quote as shlex_quote
from ansible.errors import AnsibleError
from ansible.module_utils.common.process import get_bin_path
from ansible.module_utils.common.text.converters import to_bytes, to_native, to_text
from ansible.plugins.connection import ConnectionBase, BUFSIZE
from ansible.plugins.connection import BUFSIZE, ConnectionBase
from ansible.utils.display import Display
display = Display()
@@ -172,7 +172,7 @@ class Connection(ConnectionBase):
raise AnsibleError(
f"failed to transfer file {in_path} to {out_path}:\n{to_native(stdout)}\n{to_native(stderr)}"
)
except IOError as e:
except OSError as e:
raise AnsibleError(f"file or module does not exist at: {in_path}") from e
def fetch_file(self, in_path, out_path):

View File

@@ -31,12 +31,12 @@ options:
- name: ansible_lxc_executable
"""
import errno
import fcntl
import os
import select
import shutil
import traceback
import select
import fcntl
import errno
HAS_LIBLXC = False
try:
@@ -94,7 +94,7 @@ class Connection(ConnectionBase):
while len(read_fds) > 0 or len(write_fds) > 0:
try:
ready_reads, ready_writes, dummy = select.select(read_fds, write_fds, [])
except select.error as e:
except OSError as e:
if e.args[0] == errno.EINTR:
continue
raise
@@ -173,7 +173,7 @@ class Connection(ConnectionBase):
raise errors.AnsibleFileNotFound(msg)
try:
src_file = open(in_path, "rb")
except IOError as e:
except OSError as e:
traceback.print_exc()
raise errors.AnsibleError(f"failed to open input file to {in_path}") from e
try:
@@ -184,7 +184,7 @@ class Connection(ConnectionBase):
try:
self.container.attach_wait(write_file, None)
except IOError as e:
except OSError as e:
traceback.print_exc()
msg = f"failed to transfer file to {out_path}"
raise errors.AnsibleError(msg) from e
@@ -200,7 +200,7 @@ class Connection(ConnectionBase):
try:
dst_file = open(out_path, "wb")
except IOError as e:
except OSError as e:
traceback.print_exc()
msg = f"failed to open output file {out_path}"
raise errors.AnsibleError(msg) from e
@@ -217,7 +217,7 @@ class Connection(ConnectionBase):
try:
self.container.attach_wait(write_file, None)
except IOError as e:
except OSError as e:
traceback.print_exc()
msg = f"failed to transfer file from {in_path} to {out_path}"
raise errors.AnsibleError(msg) from e

View File

@@ -74,9 +74,9 @@ options:
"""
import os
from subprocess import Popen, PIPE
from subprocess import PIPE, Popen
from ansible.errors import AnsibleError, AnsibleConnectionFailure, AnsibleFileNotFound
from ansible.errors import AnsibleConnectionFailure, AnsibleError, AnsibleFileNotFound
from ansible.module_utils.common.process import get_bin_path
from ansible.module_utils.common.text.converters import to_bytes, to_text
from ansible.plugins.connection import ConnectionBase

View File

@@ -9,7 +9,6 @@
from __future__ import annotations
DOCUMENTATION = r"""
name: qubes
short_description: Interact with an existing QubesOS AppVM
@@ -40,9 +39,9 @@ options:
import subprocess
from ansible.errors import AnsibleConnectionFailure
from ansible.module_utils.common.text.converters import to_bytes
from ansible.plugins.connection import ConnectionBase, ensure_connect
from ansible.errors import AnsibleConnectionFailure
from ansible.utils.display import Display
display = Display()

View File

@@ -16,8 +16,8 @@ description:
- This allows you to use existing Saltstack infrastructure to connect to targets.
"""
import os
import base64
import os
from ansible import errors
from ansible.plugins.connection import ConnectionBase

View File

@@ -231,6 +231,18 @@ options:
required: true
vars:
- name: wsl_distribution
wsl_remote_ssh_shell_type:
description:
- The shell type expected in the SSH session (not inside the WSL session).
- See also C(ansible_shell_type).
type: string
choices:
- cmd
- powershell
default: cmd
vars:
- name: wsl_remote_ssh_shell_type
version_added: 12.2.0
wsl_user:
description:
- WSL distribution user.
@@ -312,25 +324,25 @@ import io
import os
import pathlib
import shlex
import socket
import tempfile
import traceback
import typing as t
from binascii import hexlify
from subprocess import list2cmdline
from ansible.errors import (
AnsibleAuthenticationFailure,
AnsibleConnectionFailure,
AnsibleError,
)
from ansible_collections.community.general.plugins.module_utils._filelock import FileLock, LockTimeout
from ansible_collections.community.general.plugins.module_utils.version import LooseVersion
from ansible.module_utils.common.text.converters import to_bytes, to_native, to_text
from ansible.playbook.play_context import PlayContext
from ansible.plugins.connection import ConnectionBase
from ansible.utils.display import Display
from ansible.utils.path import makedirs_safe
from binascii import hexlify
from subprocess import list2cmdline
from ansible_collections.community.general.plugins.module_utils._filelock import FileLock, LockTimeout
from ansible_collections.community.general.plugins.module_utils.version import LooseVersion
PARAMIKO_IMPORT_ERR: str | None
try:
@@ -475,7 +487,7 @@ class Connection(ConnectionBase):
try:
ssh.load_system_host_keys(ssh_known_hosts)
break
except IOError:
except OSError:
pass # file was not found, but not required to function
except paramiko.hostkeys.InvalidHostKey as e:
raise AnsibleConnectionFailure(f"Invalid host key: {to_text(e.line)}") from e
@@ -578,18 +590,32 @@ class Connection(ConnectionBase):
wsl_distribution = self.get_option("wsl_distribution")
become = self.get_option("become")
become_user = self.get_option("become_user")
wsl_remote_ssh_shell_type = self.get_option("wsl_remote_ssh_shell_type")
is_integration_test = os.getenv("_ANSIBLE_TEST_WSL_CONNECTION_PLUGIN_WAERI5TEPHEESHA2FAE8")
if "%" in cmd:
if wsl_remote_ssh_shell_type == "powershell":
# there is no universal way to escape '%' here
# if this is raised, add a workaround to allow the specific situation (if possible)
raise AnsibleError("The command contains '%', cannot safely escape it for Powershell")
else:
cmd = cmd.replace("%", "^%")
if become and become_user:
wsl_user = become_user
else:
wsl_user = self.get_option("wsl_user")
args = ["wsl.exe", "--distribution", wsl_distribution]
args = ["wsl.exe"]
if wsl_remote_ssh_shell_type == "powershell" and not is_integration_test:
# Powershell stop-parsing token, treat the rest as arguments to the native command wsl.exe
args.append("--%")
args.extend(["--distribution", wsl_distribution])
if wsl_user:
args.extend(["--user", wsl_user])
args.extend(["--"])
args.extend(shlex.split(cmd))
if os.getenv("_ANSIBLE_TEST_WSL_CONNECTION_PLUGIN_WAERI5TEPHEESHA2FAE8"):
if is_integration_test:
return shlex.join(args)
return list2cmdline(args) # see https://github.com/python/cpython/blob/3.11/Lib/subprocess.py#L576
else:
return list2cmdline(args) # see https://github.com/python/cpython/blob/3.11/Lib/subprocess.py#L576
def exec_command(self, cmd: str, in_data: bytes | None = None, sudoable: bool = True) -> tuple[int, bytes, bytes]:
"""run a command on inside a WSL distribution"""
@@ -667,7 +693,7 @@ class Connection(ConnectionBase):
elif in_data == b"":
chan.shutdown_write()
except socket.timeout as e:
except TimeoutError as e:
raise AnsibleError(f"ssh timed out waiting for privilege escalation.\n{to_text(become_output)}") from e
stdout = b"".join(chan.makefile("rb", bufsize))

View File

@@ -35,7 +35,7 @@ from shlex import quote as shlex_quote
from ansible.errors import AnsibleError
from ansible.module_utils.common.process import get_bin_path
from ansible.module_utils.common.text.converters import to_bytes
from ansible.plugins.connection import ConnectionBase, BUFSIZE
from ansible.plugins.connection import BUFSIZE, ConnectionBase
from ansible.utils.display import Display
display = Display()
@@ -169,7 +169,7 @@ class Connection(ConnectionBase):
raise AnsibleError(f"failed to transfer file {in_path} to {out_path}") from e
if p.returncode != 0:
raise AnsibleError(f"failed to transfer file {in_path} to {out_path}:\n{stdout}\n{stderr}")
except IOError as e:
except OSError as e:
raise AnsibleError(f"file or module does not exist at: {in_path}") from e
def fetch_file(self, in_path, out_path):

View File

@@ -0,0 +1,30 @@
# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
# SPDX-License-Identifier: GPL-3.0-or-later
# SPDX-FileCopyrightText: 2026 Christoph Fiehe <christoph.fiehe@gmail.com>
# Note that this doc fragment is **PRIVATE** to the collection. It can have breaking changes at any time.
# Do not use this from other collections or standalone plugins/modules!
from __future__ import annotations
class ModuleDocFragment:
# Use together with ansible.builtin.url and icinga2_argument_spec from
# ansible_collections.community.general.plugins.module_utils._icinga2
DOCUMENTATION = r"""
options:
url:
description:
- URL of the Icinga 2 REST API.
type: str
required: true
ca_path:
description:
- CA certificates bundle to use to verify the Icinga 2 server certificate.
type: path
timeout:
description:
- How long to wait for the server to send data before giving up.
type: int
default: 10
"""

View File

@@ -41,8 +41,8 @@ EXAMPLES = r"""
# Produces ['a', 'ab', 'abc']
"""
from itertools import accumulate
from collections.abc import Sequence
from itertools import accumulate
from ansible.errors import AnsibleFilterError

View File

@@ -34,9 +34,10 @@ _value:
type: dictionary
"""
from ansible.errors import AnsibleFilterError
from collections.abc import Sequence
from collections import Counter
from collections.abc import Sequence
from ansible.errors import AnsibleFilterError
def counter(sequence):

View File

@@ -4,8 +4,8 @@
from __future__ import annotations
from ansible.errors import AnsibleFilterError
from ansible.module_utils.common.text.converters import to_bytes
from ansible.module_utils.common.collections import is_string
from ansible.module_utils.common.text.converters import to_bytes
try:
from zlib import crc32

View File

@@ -80,11 +80,11 @@ _value:
from ansible.errors import AnsibleFilterError
from ansible_collections.community.general.plugins.module_utils.csv import (
CSVError,
CustomDialectFailureError,
DialectNotAvailableError,
initialize_dialect,
read_csv,
CSVError,
DialectNotAvailableError,
CustomDialectFailureError,
)

View File

@@ -16,6 +16,20 @@ options:
description: A string containing an INI document.
type: string
required: true
delimiters:
description: A list of characters used as delimiters in the INI document.
type: list
elements: string
default:
- "="
- ":"
version_added: 12.4.0
seealso:
- plugin: community.general.to_ini
plugin_type: filter
- plugin: ansible.builtin.ini
plugin_type: lookup
- module: community.general.ini_file
"""
EXAMPLES = r"""
@@ -43,17 +57,21 @@ _value:
"""
from io import StringIO
from configparser import ConfigParser
from io import StringIO
from ansible.errors import AnsibleFilterError
from ansible.module_utils.common.collections import is_sequence
class IniParser(ConfigParser):
"""Implements a configparser which is able to return a dict"""
def __init__(self):
super().__init__(interpolation=None)
def __init__(self, delimiters=None):
if delimiters is None:
super().__init__(interpolation=None)
else:
super().__init__(interpolation=None, delimiters=delimiters)
self.optionxform = str
def as_dict(self):
@@ -68,13 +86,21 @@ class IniParser(ConfigParser):
return d
def from_ini(obj):
def from_ini(obj, delimiters=None):
"""Read the given string as INI file and return a dict"""
if not isinstance(obj, str):
raise AnsibleFilterError(f"from_ini requires a str, got {type(obj)}")
if delimiters is not None:
if not is_sequence(delimiters):
raise AnsibleFilterError(f"from_ini's delimiters parameter must be a sequence, got {type(delimiters)}")
delimiters = tuple(delimiters)
if not all(isinstance(elt, str) for elt in delimiters):
raise AnsibleFilterError(
f"from_ini's delimiters parameter must be a sequence of strings, got {delimiters!r}"
)
parser = IniParser()
parser = IniParser(delimiters=delimiters)
try:
parser.read_file(StringIO(obj))

View File

@@ -52,9 +52,10 @@ _value:
type: dictionary
"""
from ansible.errors import AnsibleFilterError
from collections.abc import Mapping, Sequence
from ansible.errors import AnsibleFilterError
def groupby_as_dict(sequence, attribute):
"""

View File

@@ -8,7 +8,6 @@ from ansible.errors import (
AnsibleError,
AnsibleFilterError,
)
from ansible.module_utils.common.collections import is_sequence
try:

View File

@@ -74,9 +74,10 @@ _value:
type: any
"""
from ansible.errors import AnsibleError, AnsibleFilterError
import importlib
from ansible.errors import AnsibleError, AnsibleFilterError
try:
import jc

View File

@@ -6,11 +6,10 @@ from __future__ import annotations
import typing as t
from json import loads
from ansible.errors import AnsibleFilterError
if t.TYPE_CHECKING:
from typing import Any
from collections.abc import Callable
JSONPATCH_IMPORT_ERROR: ImportError | None
@@ -31,7 +30,7 @@ OPERATIONS_NEEDING_VALUE = ["add", "replace", "test"]
class FilterModule:
"""Filter plugin."""
def check_json_object(self, filter_name: str, object_name: str, inp: Any):
def check_json_object(self, filter_name: str, object_name: str, inp: t.Any):
if isinstance(inp, (str, bytes, bytearray)):
try:
return loads(inp)
@@ -64,9 +63,9 @@ class FilterModule:
inp: str | list | dict | bytes | bytearray,
op: str,
path: str,
value: Any = None,
value: t.Any = None,
**kwargs: dict,
) -> Any:
) -> t.Any:
if not HAS_LIB:
raise AnsibleFilterError(
"You need to install 'jsonpatch' package prior to running 'json_patch' filter"
@@ -110,7 +109,7 @@ class FilterModule:
operations: list,
/,
fail_test: bool = False,
) -> Any:
) -> t.Any:
if not HAS_LIB:
raise AnsibleFilterError(
"You need to install 'jsonpatch' package prior to running 'json_patch_recipe' filter"
@@ -160,7 +159,7 @@ class FilterModule:
return result
def filters(self) -> dict[str, Callable[..., Any]]:
def filters(self) -> dict[str, Callable[..., t.Any]]:
"""Map filter plugin names to their functions.
Returns:

View File

@@ -194,13 +194,13 @@ _value:
elements: dictionary
"""
from ansible.errors import AnsibleFilterError
from collections.abc import Mapping, Sequence
from ansible.utils.vars import merge_hash
from collections import defaultdict
from collections.abc import Mapping, Sequence
from operator import itemgetter
from ansible.errors import AnsibleFilterError
from ansible.utils.vars import merge_hash
def list_mergeby(x, y, index, recursive=False, list_merge="replace"):
"""Merge 2 lists by attribute 'index'. The function 'merge_hash'

View File

@@ -5,8 +5,8 @@
from __future__ import annotations
import re
from ansible.errors import AnsibleFilterError
from ansible.errors import AnsibleFilterError
UNIT_FACTORS = {
"ms": [],

View File

@@ -16,6 +16,12 @@ options:
description: The dictionary that should be converted to the INI format.
type: dictionary
required: true
seealso:
- plugin: ansible.builtin.ini
plugin_type: lookup
- module: community.general.ini_file
- plugin: community.general.from_ini
plugin_type: filter
"""
EXAMPLES = r"""
@@ -50,6 +56,7 @@ _value:
from collections.abc import Mapping
from configparser import ConfigParser
from io import StringIO
from ansible.errors import AnsibleFilterError

50
plugins/filter/to_toml.py Normal file
View File

@@ -0,0 +1,50 @@
# Copyright (c) Contributors to the Ansible project
# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
# SPDX-License-Identifier: GPL-3.0-or-later
from __future__ import annotations
import typing as t
from collections.abc import Mapping
from ansible.module_utils.common.collections import is_sequence
from ansible.module_utils.common.text.converters import to_text
TOMLKIT_IMPORT_ERROR: ImportError | None
try:
from tomlkit import dumps
except ImportError as imp_exc:
TOMLKIT_IMPORT_ERROR = imp_exc
else:
TOMLKIT_IMPORT_ERROR = None
from ansible.errors import AnsibleError, AnsibleFilterError
from ansible_collections.community.general.plugins.plugin_utils._tags import remove_all_tags
def _stringify_keys(value: t.Any) -> t.Any:
"""Recursively convert all keys to strings."""
if isinstance(value, Mapping):
return {to_text(k): _stringify_keys(v) for k, v in value.items()}
if is_sequence(value):
return [_stringify_keys(e) for e in value]
return value
def to_toml(value: t.Mapping, *, redact_sensitive_values: bool = False) -> str:
"""Serialize input as TOML."""
if TOMLKIT_IMPORT_ERROR:
raise AnsibleError("tomlkit must be installed to use this plugin") from TOMLKIT_IMPORT_ERROR
if not isinstance(value, Mapping):
raise AnsibleFilterError("to_toml only accepts dictionaries.")
return dumps(
remove_all_tags(_stringify_keys(value), redact_sensitive_values=redact_sensitive_values),
)
class FilterModule:
def filters(self):
return {
"to_toml": to_toml,
}

View File

@@ -0,0 +1,42 @@
# Copyright (c) Contributors to the Ansible project
# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
# SPDX-License-Identifier: GPL-3.0-or-later
DOCUMENTATION:
name: to_toml
author:
- Matt Williaks (@milliams)
version_added: 12.3.0
short_description: Convert variable to TOML string
description:
- Converts an Ansible variable into a TOML string representation.
- This filter functions as a wrapper to the L(Python TOML Kit library, https://pypi.org/project/tomlkit/)'s C(tomlkit.dumps) function.
requirements:
- tomlkit
positional: _input
options:
_input:
description:
- A variable or expression that returns a data structure.
type: dict
required: true
redact_sensitive_values:
description:
- If set to V(true), vaulted strings are replaced by V(<redacted>) instead of being decrypted.
- With future ansible-core versions, this can extend to other strings tagged as sensitive.
- B(Note) that with ansible-core 2.18 and before this might not yield the expected result
since these versions of ansible-core strip the vault information away from strings that are
part of more complex data structures specified in C(vars).
type: bool
default: false
EXAMPLES: |
---
# Dump variable in a template to create a TOML document
value: "{{ my_config | community.general.to_toml }}"
RETURN:
_value:
description:
- The TOML serialized string representing the variable structure inputted.
type: string

View File

@@ -5,7 +5,6 @@
from __future__ import annotations
import typing as t
from collections.abc import Mapping, Set
from yaml import dump
@@ -14,81 +13,7 @@ try:
except ImportError:
from yaml import SafeDumper # type: ignore
from ansible.module_utils.common.collections import is_sequence
try:
# This is ansible-core 2.19+
from ansible.utils.vars import transform_to_native_types
from ansible.parsing.vault import VaultHelper, VaultLib
HAS_TRANSFORM_TO_NATIVE_TYPES = True
except ImportError:
HAS_TRANSFORM_TO_NATIVE_TYPES = False
from ansible.parsing.yaml.objects import AnsibleVaultEncryptedUnicode
from ansible.utils.unsafe_proxy import AnsibleUnsafe
def _to_native_types_compat(value: t.Any, *, redact_value: str | None) -> t.Any:
"""Compatibility function for ansible-core 2.18 and before."""
if value is None:
return value
if isinstance(value, AnsibleUnsafe):
# This only works up to ansible-core 2.18:
return _to_native_types_compat(value._strip_unsafe(), redact_value=redact_value) # type: ignore
# But that's fine, since this code path isn't taken on ansible-core 2.19+ anyway.
if isinstance(value, Mapping):
return {
_to_native_types_compat(key, redact_value=redact_value): _to_native_types_compat(
val, redact_value=redact_value
)
for key, val in value.items()
}
if isinstance(value, Set):
return {_to_native_types_compat(elt, redact_value=redact_value) for elt in value}
if is_sequence(value):
return [_to_native_types_compat(elt, redact_value=redact_value) for elt in value]
if isinstance(value, AnsibleVaultEncryptedUnicode):
if redact_value is not None:
return redact_value
# This only works up to ansible-core 2.18:
return value.data
# But that's fine, since this code path isn't taken on ansible-core 2.19+ anyway.
if isinstance(value, bytes):
return bytes(value)
if isinstance(value, str):
return str(value)
return value
def _to_native_types(value: t.Any, *, redact: bool) -> t.Any:
if isinstance(value, Mapping):
return {_to_native_types(k, redact=redact): _to_native_types(v, redact=redact) for k, v in value.items()}
if is_sequence(value):
return [_to_native_types(e, redact=redact) for e in value]
if redact:
ciphertext = VaultHelper.get_ciphertext(value, with_tags=False)
if ciphertext and VaultLib.is_encrypted(ciphertext):
return "<redacted>"
return transform_to_native_types(value, redact=redact)
def remove_all_tags(value: t.Any, *, redact_sensitive_values: bool = False) -> t.Any:
"""
Remove all tags from all values in the input.
If ``redact_sensitive_values`` is ``True``, all sensitive values will be redacted.
"""
if HAS_TRANSFORM_TO_NATIVE_TYPES:
return _to_native_types(value, redact=redact_sensitive_values)
return _to_native_types_compat( # type: ignore[unreachable]
value,
redact_value="<redacted>"
if redact_sensitive_values
else None, # same string as in ansible-core 2.19 by transform_to_native_types()
)
from ansible_collections.community.general.plugins.plugin_utils._tags import remove_all_tags
def to_yaml(

View File

@@ -197,7 +197,7 @@ class InventoryModule(BaseInventoryPlugin, Cacheable):
data = self.cobbler.get_profiles(self.token)
else:
data = self.cobbler.get_profiles()
except (socket.gaierror, socket.error, xmlrpc_client.ProtocolError):
except (socket.gaierror, OSError, xmlrpc_client.ProtocolError):
self._reload_cache()
else:
self._init_cache()
@@ -221,7 +221,7 @@ class InventoryModule(BaseInventoryPlugin, Cacheable):
data[i] = self.cobbler.get_system_as_rendered(host["name"], self.token)
else:
data[i] = self.cobbler.get_system_as_rendered(host["name"])
except (socket.gaierror, socket.error, xmlrpc_client.ProtocolError):
except (socket.gaierror, OSError, xmlrpc_client.ProtocolError):
self._reload_cache()
else:
self._init_cache()

View File

@@ -5,7 +5,6 @@
from __future__ import annotations
DOCUMENTATION = r"""
name: gitlab_runners
author:

View File

@@ -4,7 +4,6 @@
# SPDX-License-Identifier: GPL-3.0-or-later
from __future__ import annotations
DOCUMENTATION = r"""
name: icinga2
short_description: Icinga2 inventory source
@@ -97,8 +96,8 @@ import json
from urllib.error import HTTPError
from ansible.errors import AnsibleParserError
from ansible.plugins.inventory import BaseInventoryPlugin, Constructable
from ansible.module_utils.urls import open_url
from ansible.plugins.inventory import BaseInventoryPlugin, Constructable
from ansible_collections.community.general.plugins.plugin_utils.unsafe import make_unsafe

View File

@@ -83,11 +83,12 @@ remotes:
- remote-2:default
"""
from ansible.plugins.inventory import BaseInventoryPlugin, Constructable
from ansible.utils.display import Display
from json import loads
from subprocess import check_output
from ansible.plugins.inventory import BaseInventoryPlugin, Constructable
from ansible.utils.display import Display
display = Display()

View File

@@ -170,13 +170,13 @@ groups:
test: inventory_hostname.startswith('test')
"""
import re
import os
from subprocess import Popen, PIPE
import re
from subprocess import PIPE, Popen
from ansible.errors import AnsibleError, AnsibleParserError
from ansible.module_utils.common.text.converters import to_native, to_text
from ansible.plugins.inventory import BaseInventoryPlugin, Constructable, Cacheable
from ansible.plugins.inventory import BaseInventoryPlugin, Cacheable, Constructable
from ansible.utils.display import Display
display = Display()

View File

@@ -125,15 +125,14 @@ compose:
"""
from ansible.errors import AnsibleError
from ansible.plugins.inventory import BaseInventoryPlugin, Constructable, Cacheable
from ansible.plugins.inventory import BaseInventoryPlugin, Cacheable, Constructable
from ansible_collections.community.general.plugins.plugin_utils.unsafe import make_unsafe
try:
from linode_api4 import LinodeClient
from linode_api4.objects.linode import Instance
from linode_api4.errors import ApiError as LinodeApiError
from linode_api4.objects.linode import Instance
HAS_LINODE = True
except ImportError:
@@ -203,7 +202,7 @@ class InventoryModule(BaseInventoryPlugin, Constructable, Cacheable):
ips += [instance.ips.ipv6.slaac, instance.ips.ipv6.link_local]
ips += instance.ips.ipv6.pools
for ip_type in set(ip.type for ip in ips):
for ip_type in {ip.type for ip in ips}:
self.inventory.set_variable(
hostname, ip_type, make_unsafe(self._ip_data([ip for ip in ips if ip.type == ip_type]))
)

View File

@@ -167,15 +167,16 @@ groupby:
"""
import json
import os
import re
import time
import os
from urllib.parse import urlencode
from ansible.plugins.inventory import BaseInventoryPlugin
from ansible.module_utils.common.text.converters import to_native, to_text
from ansible.module_utils.common.dict_transformations import dict_merge
from ansible.errors import AnsibleError, AnsibleParserError
from ansible.module_utils.common.dict_transformations import dict_merge
from ansible.module_utils.common.text.converters import to_native, to_text
from ansible.plugins.inventory import BaseInventoryPlugin
from ansible_collections.community.general.plugins.module_utils.lxd import LXDClient, LXDClientException
from ansible_collections.community.general.plugins.plugin_utils.unsafe import make_unsafe
@@ -210,9 +211,9 @@ class InventoryModule(BaseInventoryPlugin):
Returns:
dict(json_data): json data"""
try:
with open(path, "r") as json_file:
with open(path) as json_file:
return json.load(json_file)
except (IOError, json.decoder.JSONDecodeError) as err:
except (OSError, json.decoder.JSONDecodeError) as err:
raise AnsibleParserError(f"Could not load the test data from {to_native(path)}: {err}") from err
def save_json_data(self, path, file_name=None):
@@ -242,7 +243,7 @@ class InventoryModule(BaseInventoryPlugin):
cwd = os.path.abspath(os.path.dirname(__file__))
with open(os.path.abspath(os.path.join(cwd, *path)), "w") as json_file:
json.dump(self.data, json_file)
except IOError as err:
except OSError as err:
raise AnsibleParserError(f"Could not save data: {err}") from err
def verify_file(self, path):

View File

@@ -125,14 +125,13 @@ groups:
import os
import re
from subprocess import Popen, PIPE
from subprocess import PIPE, Popen
from ansible import constants as C
from ansible.errors import AnsibleParserError
from ansible.module_utils.common.text.converters import to_native, to_text
from ansible.plugins.inventory import BaseInventoryPlugin, Constructable, Cacheable
from ansible.module_utils.common.process import get_bin_path
from ansible.module_utils.common.text.converters import to_native, to_text
from ansible.plugins.inventory import BaseInventoryPlugin, Cacheable, Constructable
from ansible_collections.community.general.plugins.plugin_utils.unsafe import make_unsafe

View File

@@ -64,10 +64,10 @@ from sys import version as python_version
from urllib.parse import urljoin
from ansible.errors import AnsibleError
from ansible.module_utils.ansible_release import __version__ as ansible_version
from ansible.module_utils.common.text.converters import to_text
from ansible.module_utils.urls import open_url
from ansible.plugins.inventory import BaseInventoryPlugin
from ansible.module_utils.common.text.converters import to_text
from ansible.module_utils.ansible_release import __version__ as ansible_version
from ansible_collections.community.general.plugins.plugin_utils.unsafe import make_unsafe

View File

@@ -4,7 +4,6 @@
from __future__ import annotations
DOCUMENTATION = r"""
name: opennebula
author:
@@ -90,14 +89,14 @@ try:
except ImportError:
HAS_PYONE = False
import os
from collections import namedtuple
from ansible.errors import AnsibleError
from ansible.plugins.inventory import BaseInventoryPlugin, Constructable
from ansible_collections.community.general.plugins.plugin_utils.unsafe import make_unsafe
from collections import namedtuple
import os
class InventoryModule(BaseInventoryPlugin, Constructable):
NAME = "community.general.opennebula"
@@ -119,10 +118,10 @@ class InventoryModule(BaseInventoryPlugin, Constructable):
if authfile is None:
authfile = os.path.join(os.environ.get("HOME"), ".one", "one_auth")
try:
with open(authfile, "r") as fp:
with open(authfile) as fp:
authstring = fp.read().rstrip()
username, password = authstring.split(":")
except (OSError, IOError) as e:
except OSError as e:
raise AnsibleError(f"Could not find or read ONE_AUTH file at '{authfile}'") from e
except Exception as e:
raise AnsibleError(f"Error occurs when reading ONE_AUTH file at '{authfile}'") from e

View File

@@ -4,7 +4,6 @@
from __future__ import annotations
DOCUMENTATION = r"""
name: scaleway
author:
@@ -118,8 +117,8 @@ variables:
ansible_user: "'admin'"
"""
import os
import json
import os
YAML_IMPORT_ERROR: ImportError | None
try:
@@ -129,14 +128,15 @@ except ImportError as exc:
else:
YAML_IMPORT_ERROR = None
import urllib.parse as urllib_parse
from ansible.errors import AnsibleError
from ansible.module_utils.common.text.converters import to_text
from ansible.module_utils.urls import open_url
from ansible.plugins.inventory import BaseInventoryPlugin, Constructable
from ansible_collections.community.general.plugins.module_utils.scaleway import SCALEWAY_LOCATION, parse_pagination_link
from ansible_collections.community.general.plugins.plugin_utils.unsafe import make_unsafe
from ansible.module_utils.urls import open_url
from ansible.module_utils.common.text.converters import to_text
import urllib.parse as urllib_parse
def _fetch_information(token, url):

View File

@@ -72,14 +72,13 @@ groups:
"""
import os
from subprocess import Popen, PIPE
from collections.abc import MutableMapping
from subprocess import PIPE, Popen
from ansible.errors import AnsibleParserError
from ansible.module_utils.common.text.converters import to_bytes, to_text
from collections.abc import MutableMapping
from ansible.plugins.inventory import BaseInventoryPlugin, Constructable, Cacheable
from ansible.module_utils.common.process import get_bin_path
from ansible.module_utils.common.text.converters import to_bytes, to_text
from ansible.plugins.inventory import BaseInventoryPlugin, Cacheable, Constructable
from ansible_collections.community.general.plugins.plugin_utils.unsafe import make_unsafe

View File

@@ -99,7 +99,7 @@ import ssl
from time import sleep
from ansible.errors import AnsibleError
from ansible.plugins.inventory import BaseInventoryPlugin, Constructable, Cacheable
from ansible.plugins.inventory import BaseInventoryPlugin, Cacheable, Constructable
from ansible_collections.community.general.plugins.module_utils.version import LooseVersion
from ansible_collections.community.general.plugins.plugin_utils.unsafe import make_unsafe

View File

@@ -77,7 +77,6 @@ import base64
from ansible.errors import AnsibleLookupError
from ansible.plugins.lookup import LookupBase
from ansible.utils.display import Display
display = Display()

View File

@@ -118,7 +118,7 @@ _raw:
elements: list
"""
from subprocess import Popen, PIPE
from subprocess import PIPE, Popen
from ansible.errors import AnsibleError, AnsibleOptionsError
from ansible.module_utils.common.text.converters import to_bytes, to_text

View File

@@ -3,7 +3,6 @@
# SPDX-License-Identifier: GPL-3.0-or-later
from __future__ import annotations
DOCUMENTATION = r"""
name: bitwarden_secrets_manager
author:
@@ -67,7 +66,7 @@ _raw:
elements: dict
"""
from subprocess import Popen, PIPE
from subprocess import PIPE, Popen
from time import sleep
from ansible.errors import AnsibleLookupError

View File

@@ -42,8 +42,8 @@ _raw:
"""
from ansible.errors import AnsibleError
from ansible.plugins.lookup import LookupBase
from ansible.parsing.splitter import parse_kv
from ansible.plugins.lookup import LookupBase
try:
import chef

View File

@@ -61,11 +61,9 @@ import re
from importlib import import_module
import yaml
from ansible.errors import AnsibleLookupError
from ansible.plugins.lookup import LookupBase
FQCN_RE = re.compile(r"^[A-Za-z0-9_]+\.[A-Za-z0-9_]+$")

View File

@@ -4,7 +4,6 @@
# SPDX-License-Identifier: GPL-3.0-or-later
from __future__ import annotations
DOCUMENTATION = r"""
author: Unknown (!UNKNOWN)
name: consul_kv
@@ -112,9 +111,9 @@ _raw:
from urllib.parse import urlparse
from ansible.errors import AnsibleError, AnsibleAssertionError
from ansible.plugins.lookup import LookupBase
from ansible.errors import AnsibleAssertionError, AnsibleError
from ansible.module_utils.common.text.converters import to_text
from ansible.plugins.lookup import LookupBase
try:
import consul

View File

@@ -79,12 +79,11 @@ _result:
import os
import subprocess
from subprocess import PIPE
from subprocess import Popen
from subprocess import PIPE, Popen
from ansible.errors import AnsibleError
from ansible.plugins.lookup import LookupBase
from ansible.module_utils.common.text.converters import to_bytes, to_native
from ansible.plugins.lookup import LookupBase
from ansible.utils.display import Display
display = Display()

View File

@@ -118,8 +118,9 @@ _list:
key2: bar
"""
from ansible.errors import AnsibleLookupError
from collections.abc import Mapping, Sequence
from ansible.errors import AnsibleLookupError
from ansible.plugins.lookup import LookupBase
from ansible.template import Templar

View File

@@ -240,20 +240,20 @@ _list:
- C(strings).
"""
from ansible.errors import AnsibleError
from ansible.plugins.lookup import LookupBase
from ansible.module_utils.parsing.convert_bool import boolean
from ansible.utils.display import Display
import socket
from ansible.errors import AnsibleError
from ansible.module_utils.parsing.convert_bool import boolean
from ansible.plugins.lookup import LookupBase
from ansible.utils.display import Display
try:
import dns.exception
import dns.name
import dns.rdataclass
import dns.resolver
import dns.reversename
import dns.rdataclass
from dns.rdatatype import (
A,
AAAA,
CAA,
CNAME,
@@ -274,6 +274,7 @@ try:
SSHFP,
TLSA,
TXT,
A,
)
HAVE_DNS = True

View File

@@ -3,7 +3,6 @@
# SPDX-License-Identifier: GPL-3.0-or-later
from __future__ import annotations
DOCUMENTATION = r"""
name: dsv
author: Adam Migus (@amigus) <adam@migus.org>
@@ -96,9 +95,8 @@ try:
except ImportError:
sdk_is_missing = True
from ansible.utils.display import Display
from ansible.plugins.lookup import LookupBase
from ansible.utils.display import Display
display = Display()

View File

@@ -69,8 +69,8 @@ _raw:
import json
from ansible.plugins.lookup import LookupBase
from ansible.module_utils.urls import open_url
from ansible.plugins.lookup import LookupBase
# this can be made configurable, not should not use ansible.cfg
#

View File

@@ -124,11 +124,11 @@ _raw:
description: Time of last metadata update or creation (depends on OS).
type: float
"""
import grp
import os
import pwd
import grp
import stat
import re
import stat
HAVE_SELINUX = False
try:
@@ -138,8 +138,8 @@ try:
except ImportError:
pass
from ansible.plugins.lookup import LookupBase
from ansible.module_utils.common.text.converters import to_native, to_text
from ansible.plugins.lookup import LookupBase
from ansible.utils.display import Display
display = Display()

View File

@@ -83,7 +83,7 @@ except ImportError:
HAS_PYTHON_JWT = False # vs pyjwt
if HAS_JWT and hasattr(jwt, "JWT"):
HAS_PYTHON_JWT = True
from jwt import jwk_from_pem, JWT # type: ignore[attr-defined]
from jwt import JWT, jwk_from_pem # type: ignore[attr-defined]
jwt_instance = JWT()
@@ -95,12 +95,12 @@ except ImportError:
HAS_CRYPTOGRAPHY = False
import time
import json
import time
from urllib.error import HTTPError
from ansible.module_utils.urls import open_url
from ansible.errors import AnsibleError, AnsibleOptionsError
from ansible.module_utils.urls import open_url
from ansible.plugins.lookup import LookupBase
from ansible.utils.display import Display

View File

@@ -67,9 +67,9 @@ _raw:
elements: str
"""
from ansible.module_utils.common.text.converters import to_text
from ansible.plugins.lookup import LookupBase
from ansible.utils.cmd_functions import run_cmd
from ansible.module_utils.common.text.converters import to_text
class Hiera:

View File

@@ -39,7 +39,7 @@ _raw:
elements: str
"""
from subprocess import Popen, PIPE
from subprocess import PIPE, Popen
from ansible.errors import AnsibleError
from ansible.module_utils.common.text.converters import to_bytes, to_text

View File

@@ -59,8 +59,8 @@ _raw:
from ansible.errors import AnsibleError
from ansible.plugins.lookup import LookupBase
from ansible.module_utils.common.text.converters import to_native, to_text
from ansible.plugins.lookup import LookupBase
HAVE_LMDB = True
try:

Some files were not shown because too many files have changed in this diff Show More