* test(yarn): add Alpine Linux support via apk
Install nodejs and yarn via apk on Alpine, sharing the functional
test block with the existing non-Alpine (pre-built binary) path.
Extracts the test block into tests.yml to avoid duplication.
Fixes#4270
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
* fix(yarn): skip Node.js runtime warnings in stderr processing
Node.js 24 emits DeprecationWarning lines to stderr (e.g. for url.parse())
that are not JSON, causing _process_yarn_error to fail with "Unexpected
stderr output from Yarn". Skip lines starting with "(node:" before
attempting JSON parsing.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
* test(yarn): add changelog fragment for #11943
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
* fix(yarn): only JSON-parse lines starting with '{' in stderr
Node.js 24 emits multi-line DeprecationWarnings to stderr (e.g. the hint
line "(Use `node --trace-deprecation ...`") that are not JSON and were
tripping the "Unexpected stderr output from Yarn" failure. Yarn's
structured output always starts with '{', so skip any line that doesn't.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
* test(yarn): install sqlite on Alpine to fix nodejs 22 symbol error
On Alpine 3.21 nodejs 22 requires SQLite session extension symbols
(sqlite3session_*) that are not present in sqlite-libs; installing
the full sqlite package provides them.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
* test(yarn): refresh apk cache and upgrade sqlite-libs before installing nodejs
The CI Alpine container may have a stale sqlite-libs that lacks the
session extension symbols (sqlite3session_*) required by nodejs 22+.
Force a cache refresh and upgrade sqlite-libs to the latest revision.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
* fix(yarn): warn on non-JSON stderr lines instead of silently skipping
Non-JSON lines in stderr (e.g. Node.js runtime DeprecationWarnings) are
surfaced to the user via module.warn() rather than being silently ignored,
since their content and meaning are not known in advance.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
* prefix yarn output line
* Update changelogs/fragments/11943-yarn-nodejs-runtime-warnings.yml
Co-authored-by: Felix Fontein <felix@fontein.de>
---------
Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-authored-by: Felix Fontein <felix@fontein.de>
* fix(xml): coerce boolean values to string with a warning
Fixes#7171
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
* test(xml): add integration tests for boolean value handling
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
* changelog: add fragment for PR 11959
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
* adjustments from review
* test(xml): update boolean-value integration tests to expect failure
Now that xml fails on non-string values, replace the old success-path
tests with failure assertions and add a positive test for quoted strings.
Remove the no-longer-needed result XML fixtures.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
* adjustments from review
* fix(xml): correct boolean test assertions to match actual error message format
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
---------
Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
* feat(datadog_monitor): deprecate mute and unmute states
The Datadog mute/unmute monitor API is deprecated upstream, and the
module's silenced parameter was never correctly wired to the mute
endpoint. Direct users to community.general.datadog_downtime instead.
Planned removal in 15.0.0.
Fixes#1535
* feat(datadog_monitor): add changelog fragment for #11988
* multiple module utils: flatten directories
* adjust pritunl tests
* adjust lxca and keycloak tests
* adjust botmeta
* rename test files correctly
* and an import fix
* rename pritunl api mod utils test
* fix typo in test filename
* rename references to pritunl api test
* rename keycloak mod utils test
* Add initial secret reference support
* Add changelog fragment
Bring in minor improvements mentioned.
* Apply suggestions from code review
Co-authored-by: Felix Fontein <felix@fontein.de>
---------
Co-authored-by: Felix Fontein <felix@fontein.de>
* gem - fix --user-install conflict with OS-injected --install-dir
Some distributions (e.g. Fedora) inject --install-dir via operating_system.rb
as a platform default. Combining that with --user-install causes a gem CLI
parser error. Resolve the user install directory at install time and pass
--install-dir instead, which is semantically equivalent and avoids the conflict.
Uninstall is intentionally left unscoped so gem can find gems regardless of
where they were originally installed.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
* gem - add changelog fragment for #11873
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
* gem - fix user_install handling for install and uninstall
Two issues found in CI:
1. `gem environment user_gemhome` is not supported on older RubyGems (e.g.
Ubuntu 20.04 ships 3.1.2). Simplify get_user_install_dir() to always parse
the full `gem environment` output for "USER INSTALLATION DIRECTORY", which
is stable across all supported versions.
2. On Fedora, `gem uninstall` without flags only searches the system gem path
(set by operating_system.rb), so it cannot find gems installed to the user
dir via --install-dir. Add user_install to the uninstall args_order so that
gem uninstall --user-install is passed when user_install=True. The OS
defaults conflict only applies to gem install, not gem uninstall.
The integration test is updated to be consistent: the user_install:false
install/remove block now also specifies user_install:false on removal.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
* gem - use --install-dir for both install and uninstall of user gems
gem uninstall --user-install does not reliably find gems on Fedora/RHEL when
running as root, because those systems may disable user gem home for root and
Gem.user_dir may differ from the path resolved via 'gem environment'.
Use --install-dir <user_dir> for uninstall as well, since that is the exact
path used during install, making the operation consistent across platforms.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
* gem - add override_platform_install_dir option and type hints
- add type hints to all functions
- fix misleading comment about --install-dir scoping for uninstall
- add override_platform_install_dir option (default=false) to opt in to
resolving and passing the user gem dir explicitly to both gem install
and gem uninstall, working around OS-injected platform defaults on
distributions such as Fedora
- reclassify changelog fragment as minor_changes (new parameter, not
backport-eligible)
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
* test(gem): add integration test for override_platform_install_dir
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
* test(gem): skip default user_install test on RedHat family
OS-injected --install-dir on RHEL/Fedora makes the default user_install: true
case fail. The override_platform_install_dir block already covers the correct
path on those platforms.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
---------
Co-authored-by: Claude Opus 4.7 <noreply@anthropic.com>
* fix(ipa_group): skip group_mod when external flag matches IPA state
When external=false (the default), get_group_diff() left the external
key in the diff even though the group was already non-external, causing
a spurious group_mod call that IPA rejected with "no modifications to
be performed". The fix checks equality in both directions.
Fixes#5061
* fix(ipa_group): add changelog fragment for PR 11933
* add quoting to fragment
* fix(odbc): fetch rows before committing to fix HY010 function sequence error
Fixes#5395
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
* chore(odbc): add changelog fragment for PR #11972
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
---------
Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
* fix(apt_rpm): do not fail when update-kernel finds no new kernel
update-kernel exits with rc=1 when the kernel is already at the latest
version. Handle this case gracefully by checking for the known
"There are no available kernels" message in stderr and returning
changed=False instead of raising an error.
Fixes#10055
* fix(apt_rpm): add changelog fragment for #11949
* Apply suggestion from review
Co-authored-by: Felix Fontein <felix@fontein.de>
---------
Co-authored-by: Felix Fontein <felix@fontein.de>
* feat(snap): add devmode parameter to support --devmode flag
Closes#8155
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
* feat(changelog): add fragment for PR 11952
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
---------
Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
* fix(logstash_plugin): use env vars for proxy, expose stderr on failure
Replace broken -DproxyHost/-DproxyPort JVM flags with http_proxy/https_proxy
environment variables, which are respected by modern Logstash bundled JDK.
Also include stderr in fail_json so the actual error output is visible.
Fixes#8650
* feat(changelog): add fragment for PR 11951
* fix(zypper_repository): allow state=absent when .repo URL/file is unreachable
When removing a repository by .repo URL, a download failure used to cause
an unconditional fail_json. Now, for state=absent, the module warns and
falls back to deriving the alias from the .repo filename basename.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
* feat(changelog): add fragment for PR 11947
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
---------
Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
* feat(xml): add huge_tree option to support large XML files
Add the huge_tree parameter (bool, default false) which passes huge_tree=True
to lxml's XMLParser, disabling libxml2's internal size restrictions on text
nodes and document depth.
Fixes#4897
* fix(xml): add changelog fragment for PR 11940
* feat(supervisorctl): use parallel bulk commands for name=all
When name=all, dispatch a single `supervisorctl start/stop/restart all`
instead of iterating per process, matching the CLI's parallel behaviour.
Also extract inline status-filter lambdas into named module-level functions.
Fixes#8159
* feat(changelog): add fragment for PR 11953
* fix(selective): route output through display to honour ANSIBLE_LOG_PATH
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
* fix(selective): add changelog fragment for PR 11927
---------
Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
* lxc_container: use LVM runners from _lvm module utils
Replace direct run_command calls for lvs, vgdisplay, lvdisplay,
lvcreate, and lvremove with the shared CmdRunner-based runners from
module_utils/_lvm.py. Switches from human-readable text parsing to
machine-readable --noheadings/--nosuffix/--separator output.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
* lxc_container: add changelog fragment for PR 11920
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
* generate run_info information for commands
---------
Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
* scaleway: fix NoneType error in get_resources() when API returns empty or non-JSON response
* add changelog fragment for #11918
* Update changelogs/fragments/11361-scaleway-get-resources-none-type.yml
Co-authored-by: Felix Fontein <felix@fontein.de>
---------
Co-authored-by: RealCharlesChia <RealCharlesChia@users.noreply.github.com>
Co-authored-by: Felix Fontein <felix@fontein.de>
* pfexec become plugin: fix broken defaults for illumos/SmartOS
The pfexec become plugin has had incorrect defaults since it was
migrated from Ansible core, making it unusable on illumos without
manual workarounds:
1. become_flags defaulted to '-H -S -n' which are sudo flags.
pfexec does not accept any of these options, causing:
'exec: illegal option -- H'
2. wrap_exe defaulted to false. Unlike sudo, pfexec does not
interpret shell constructs internally. Since Ansible generates
compound commands (echo BECOME-SUCCESS-xxx ; python3), these
must be wrapped in /bin/sh -c for pfexec to execute them.
These issues were originally reported in 2016 (ansible/ansible#15642),
migrated to community.general as #3671, and partially fixed by PR #3889
in 2022 (which corrected quoting but not the defaults). Users have had
to work around this with explicit inventory settings ever since.
Changes:
- become_flags default: '-H -S -n' -> '' (empty)
- wrap_exe default: false -> true
- build_become_command: handle empty flags cleanly
- Updated tests to match corrected defaults
- Added test for custom flags
- Improved wrap_exe description to explain why it should be enabled
* Update changelog fragment with PR number
* Fix ruff formatting in test_pfexec.py
* Address review feedback from russoz
Remove redundant 'should generally be left enabled' description line
and simplify become command return by removing unnecessary flags
conditional.
* Fix unit test regexes for empty default flags
Match double space in test assertions when become_flags defaults to
empty string, consistent with doas, dzdo, and pbrun test patterns.
* pfexec become plugin: deprecate wrap_exe default rather than flipping
Changing the wrap_exe default from false to true is a breaking change
for the narrow case (e.g. ansible.builtin.raw) where the current default
does work, so deprecate instead: remove the default, emit a deprecation
warning when the option is unset, and treat that as false for now.
Build the become command with " ".join() so an empty become_flags no
longer produces a stray double space.
Tests set wrap_exe explicitly so the deprecation warning does not fire
during unit runs.
* pfexec become plugin: target 14.0.0 for wrap_exe deprecation
Per felixfontein's review, switch the deprecation target for the wrap_exe
default from community.general 15.0.0 to 14.0.0, and reword the option
description to mark the current default as deprecated rather than just
"changing in a future release".
* Fix nmap inventory plugin: skip setting reserved 'name' variable
Skip setting 'name' as a host variable to avoid Ansible warning:
'[WARNING]: Found variable using reserved name name'
The 'name' is already used as the hostname, so it's redundant as a
separate host variable. This fixes the warning that appears when using
the nmap inventory plugin.
Fixes: https://github.com/ansible-collections/community.general/issues/11766
* nmap inventory plugin: add set_name_variable option to control name variable
Add a new 'set_name_variable' option to control whether the 'name' variable
is set for each host. When true (default), maintains backward compatibility.
When false, skips setting the 'name' variable to avoid the 'Found variable
using reserved name' warning.
Fixes: https://github.com/ansible-collections/community.general/issues/11766
* Address review feedback: fix changelog category and version number
- Change 'bugfixes' to 'minor_changes' in changelog fragment
- Add PR and issue links to changelog description
- Update version_added from 10.6.0 to 13.0.0
Reviewed-by: felixfontein
---------
Co-authored-by: jiaza <jiaza@nscc-tj.cn>
* Make all doc fragments private.
* Make all plugin utils private.
* Make all module utils private.
* Reformat.
* Changelog fragment.
* Update configs and ignores.
* Adjust unit test names.
* Bump version to 13.0.0.
* Remove deprecated modules and plugins.
* Remove deprecated module utils.
* Remove leftovers.
* Remove mode=compatibility.
* Change default of is_pre740 from true to false.
* Change default of force_defaults from true to false.
* Remove support for ubuntu_legacy mechanism.
* Remove cpanm compatibility tests.
keycloak modules: add missing author credit for contributions
Added myself (@koke1997) to the author list of three modules
I contributed to in PRs #11468, #11470, #11471, and #11473 but forgot
to include at the time. Also signing up as maintainer for these modules
in .github/BOTMETA.yml so the bot can route related issues and PRs.
* jira - resolve Cloud assignee email to account ID via user search
When cloud=true and assignee contains '@', look up a unique user with
GET /rest/api/2/user/search and use accountId for create, transition,
and edit. Document Jira Cloud vs Server/Data Center assignee behavior.
Fixes https://github.com/ansible-collections/community.general/issues/11734
Assisted-by AI: Claude 4.6 Opus (Anthropic) via Cursor IDE
Signed-off-by: Vladimir Vasilev <vvasilev@redhat.com>
* * Using urllib.parse.quote for URL encoding
* Adding "added in version" note for assignee when resolving account_id from email
Signed-off-by: Vladimir Vasilev <vvasilev@redhat.com>
* * Added cached variable 'user_email'
* Changed comparison to handle missing email safely
* Updated error message formatting to use repr-style values
Signed-off-by: Vladimir Vasilev <vvasilev@redhat.com>
* jira - adjust assignee and cloud descriptions (#11734)
Signed-off-by: Vladimir Vasilev <vvasilev@redhat.com>
* jira - resolve user-type field emails to account IDs on Jira Cloud (#11734)
When cloud=true, user-type fields (assignee, reporter, and any listed
in the new custom_user_fields parameter) that contain '@' are resolved
from email to Jira Cloud account ID via the user search API. Strings
without '@' are assumed to be account IDs. Add custom_user_fields
parameter for user to declare additional custom fields of user type.
Signed-off-by: Vladimir Vasilev <vvasilev@redhat.com>
* jira - address PR 11735 review (docs, assignee path, errors, naming)
- Clarify O(custom_user_fields): built-ins stay automatic; list extra
user-typed fields without implying they are only custom-field IDs.
- On Jira Cloud, set assignee from the module param as a plain string and
let resolve_user_fields() map it to accountId (including email lookup).
- Drop redundant ``or []`` when merging O(custom_user_fields) with the
built-in user field list.
- Use public names USER_FIELDS, resolve_user_fields, and resolve_account_id
(no leading underscore) per reviewer preference.
- Quote field name and email in resolution errors with explicit "…" text
instead of repr-style !r, keeping values readable in failure messages.
Refs: https://github.com/ansible-collections/community.general/pull/11735
AI-assisted: Composer 2 (Anthropic) via Cursor IDE
Signed-off-by: Vladimir Vasilev <vvasilev@redhat.com>
* Changing fail_json formatting
Signed-off-by: Vladimir Vasilev <vvasilev@redhat.com>
* formatting fixes
Signed-off-by: Vladimir Vasilev <vvasilev@redhat.com>
* jira - fixing assignee as module option in description
Signed-off-by: Vladimir Vasilev <vvasilev@redhat.com>
---------
Signed-off-by: Vladimir Vasilev <vvasilev@redhat.com>
* lvol - migrate to CmdRunner
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
* lvol - add changelog fragment for #11887
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
* adjust the changelog fragment
---------
Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
* ipa_dnsrecord: add solo parameter for append-without-replace semantics
Fixes#682
Adds O(solo) boolean parameter (default true, preserving current
replace behaviour) consistent with other DNS modules such as
community.general.dnsimple. When solo=false, only values not
already present in IPA are added, leaving existing values untouched.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
* ipa_dnsrecord: rename solo parameter to exclusive
Rename O(solo) to O(exclusive) following reviewer feedback.
'exclusive' is the established Ansible convention for this semantic
(e.g. community.general.ini_file), while 'solo' implies single-value
DNS records.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
* ipa_dnsrecord: fix changelog fragment symbol markup
Use double backticks per RST convention in changelog fragments,
not the O() macro (which is for module docstrings).
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
* Update plugins/modules/ipa_dnsrecord.py
Co-authored-by: Felix Fontein <felix@fontein.de>
* ipa_dnsrecord: implement exclusive semantics for state=absent
- exclusive=true + state=absent: remove all existing values of that
record type and name, ignoring the specified record_value(s)
- exclusive=false + state=absent: remove only the specified values
that actually exist in IPA, preserving all others
Also updates the exclusive parameter documentation to cover both
state=present and state=absent behaviour.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
---------
Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-authored-by: Felix Fontein <felix@fontein.de>
* udm_user - replace crypt/legacycrypt with passlib
The stdlib crypt module was removed in Python 3.13. Replace the
crypt/legacycrypt import chain with passlib (already used elsewhere
in the collection) and use CryptContext.verify() for password
comparison.
Fixes#4690
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* Add changelog fragment for PR 11860
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* remove redundant ignore file entries
* udm_user, homectl - replace crypt/legacycrypt with _crypt module utils
Add a new _crypt module_utils that abstracts password hashing and
verification. It uses passlib when available, falling back to the
stdlib crypt or legacycrypt, and raises ImportError if none of them
can be imported. Both udm_user and homectl now use this shared
utility, fixing compatibility with Python 3.13+.
Fixes#4690
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
* Add BOTMETA entry for _crypt module utils
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
* _crypt - fix mypy errors and handle complete unavailability
Replace CryptContext = object fallback (rejected by mypy) with a
proper dummy class definition. Add has_crypt_context flag so modules
can detect when no backend is available. Update both modules to
import and check has_crypt_context instead of testing for None.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
* adjsutments from review
* Update plugins/modules/homectl.py
Co-authored-by: Felix Fontein <felix@fontein.de>
* Update plugins/modules/udm_user.py
Co-authored-by: Felix Fontein <felix@fontein.de>
---------
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
Co-authored-by: Felix Fontein <felix@fontein.de>
* locale_gen: support locales not yet listed in /etc/locale.gen
On systems like Gentoo where /etc/locale.gen starts with only a handful
of commented examples, set_locale_glibc() now appends missing locale
entries sourced from /usr/share/i18n/SUPPORTED instead of silently
doing nothing. Also extracts the shared locale-entry regex into a
module-level constant RE_LOCALE_ENTRY.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
* locale_gen: add changelog fragment for issue 2399
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
---------
Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
* gitlab_project_variable - use find_project() for consistent error handling
Replace the bare projects.get() call in GitlabProjectVariables.get_project()
with find_project() from module_utils/gitlab, which all other GitLab modules
already use. This ensures a graceful fail_json (with a clear error message)
when the project is not found, rather than an unhandled GitlabGetError
propagating as a module traceback.
Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>
* Add changelog fragment for PR 11878
Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>
* minor adjustment in f-string
---------
Co-authored-by: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>
* homebrew_cask: fix false failure on upgrade of latest-versioned casks
Use rc == 0 to determine upgrade success, consistent with _upgrade_all().
The previous check (_current_cask_is_installed() and not _current_cask_is_outdated())
was unreliable: for `latest`-versioned casks under --greedy, brew may still
list the cask as outdated after a successful upgrade, causing the task to fail
with a harmless warning from stderr as the error message.
Fixes#1647
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
* homebrew_cask: add changelog fragment for #11838
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
* Fix changelog fragment
---------
Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>