mirror of
https://github.com/ansible-collections/community.general.git
synced 2026-04-30 10:26:52 +00:00
Compare commits
20 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
06bce0dbf4 | ||
|
|
4bfb832f0d | ||
|
|
9032b14610 | ||
|
|
444fbe8710 | ||
|
|
68fb96480c | ||
|
|
b901fa7463 | ||
|
|
f73b3bb2a2 | ||
|
|
6ee0141964 | ||
|
|
9315a7bb56 | ||
|
|
4f37a931a0 | ||
|
|
b756728718 | ||
|
|
9183c5aea0 | ||
|
|
7e0f2e1f42 | ||
|
|
a808b3d7ce | ||
|
|
03d944be9a | ||
|
|
4c6d439a13 | ||
|
|
2ea8850f2d | ||
|
|
cbaac1ca17 | ||
|
|
0d234ad3f6 | ||
|
|
195ccc47a1 |
@@ -29,14 +29,14 @@ schedules:
|
||||
always: true
|
||||
branches:
|
||||
include:
|
||||
- stable-9
|
||||
- stable-8
|
||||
- stable-7
|
||||
- cron: 0 11 * * 0
|
||||
displayName: Weekly (old stable branches)
|
||||
always: true
|
||||
branches:
|
||||
include:
|
||||
- stable-6
|
||||
- stable-7
|
||||
|
||||
variables:
|
||||
- name: checkoutPath
|
||||
@@ -53,7 +53,7 @@ variables:
|
||||
resources:
|
||||
containers:
|
||||
- container: default
|
||||
image: quay.io/ansible/azure-pipelines-test-container:4.0.1
|
||||
image: quay.io/ansible/azure-pipelines-test-container:6.0.0
|
||||
|
||||
pool: Standard
|
||||
|
||||
@@ -127,6 +127,7 @@ stages:
|
||||
- test: '3.10'
|
||||
- test: '3.11'
|
||||
- test: '3.12'
|
||||
- test: '3.13'
|
||||
- stage: Units_2_17
|
||||
displayName: Units 2.17
|
||||
dependsOn: []
|
||||
@@ -354,6 +355,7 @@ stages:
|
||||
targets:
|
||||
- test: '3.8'
|
||||
- test: '3.11'
|
||||
- test: '3.13'
|
||||
- stage: Generic_2_17
|
||||
displayName: Generic 2.17
|
||||
dependsOn: []
|
||||
|
||||
113
CHANGELOG.md
113
CHANGELOG.md
@@ -2,76 +2,107 @@
|
||||
|
||||
**Topics**
|
||||
|
||||
- <a href="#v8-6-1">v8\.6\.1</a>
|
||||
- <a href="#v8-6-2">v8\.6\.2</a>
|
||||
- <a href="#release-summary">Release Summary</a>
|
||||
- <a href="#security-fixes">Security Fixes</a>
|
||||
- <a href="#bugfixes">Bugfixes</a>
|
||||
- <a href="#v8-6-0">v8\.6\.0</a>
|
||||
- <a href="#known-issues">Known Issues</a>
|
||||
- <a href="#v8-6-1">v8\.6\.1</a>
|
||||
- <a href="#release-summary-1">Release Summary</a>
|
||||
- <a href="#security-fixes">Security Fixes</a>
|
||||
- <a href="#bugfixes-1">Bugfixes</a>
|
||||
- <a href="#v8-6-0">v8\.6\.0</a>
|
||||
- <a href="#release-summary-2">Release Summary</a>
|
||||
- <a href="#minor-changes">Minor Changes</a>
|
||||
- <a href="#deprecated-features">Deprecated Features</a>
|
||||
- <a href="#bugfixes-1">Bugfixes</a>
|
||||
- <a href="#bugfixes-2">Bugfixes</a>
|
||||
- <a href="#new-modules">New Modules</a>
|
||||
- <a href="#v8-5-0">v8\.5\.0</a>
|
||||
- <a href="#release-summary-2">Release Summary</a>
|
||||
- <a href="#release-summary-3">Release Summary</a>
|
||||
- <a href="#minor-changes-1">Minor Changes</a>
|
||||
- <a href="#security-fixes-1">Security Fixes</a>
|
||||
- <a href="#bugfixes-2">Bugfixes</a>
|
||||
- <a href="#bugfixes-3">Bugfixes</a>
|
||||
- <a href="#new-modules-1">New Modules</a>
|
||||
- <a href="#v8-4-0">v8\.4\.0</a>
|
||||
- <a href="#release-summary-3">Release Summary</a>
|
||||
- <a href="#release-summary-4">Release Summary</a>
|
||||
- <a href="#minor-changes-2">Minor Changes</a>
|
||||
- <a href="#bugfixes-3">Bugfixes</a>
|
||||
- <a href="#bugfixes-4">Bugfixes</a>
|
||||
- <a href="#new-plugins">New Plugins</a>
|
||||
- <a href="#callback">Callback</a>
|
||||
- <a href="#filter">Filter</a>
|
||||
- <a href="#new-modules-2">New Modules</a>
|
||||
- <a href="#v8-3-0">v8\.3\.0</a>
|
||||
- <a href="#release-summary-4">Release Summary</a>
|
||||
- <a href="#release-summary-5">Release Summary</a>
|
||||
- <a href="#minor-changes-3">Minor Changes</a>
|
||||
- <a href="#deprecated-features-1">Deprecated Features</a>
|
||||
- <a href="#bugfixes-4">Bugfixes</a>
|
||||
- <a href="#bugfixes-5">Bugfixes</a>
|
||||
- <a href="#new-modules-3">New Modules</a>
|
||||
- <a href="#v8-2-0">v8\.2\.0</a>
|
||||
- <a href="#release-summary-5">Release Summary</a>
|
||||
- <a href="#release-summary-6">Release Summary</a>
|
||||
- <a href="#minor-changes-4">Minor Changes</a>
|
||||
- <a href="#bugfixes-5">Bugfixes</a>
|
||||
- <a href="#bugfixes-6">Bugfixes</a>
|
||||
- <a href="#new-plugins-1">New Plugins</a>
|
||||
- <a href="#connection">Connection</a>
|
||||
- <a href="#filter-1">Filter</a>
|
||||
- <a href="#lookup">Lookup</a>
|
||||
- <a href="#new-modules-4">New Modules</a>
|
||||
- <a href="#v8-1-0">v8\.1\.0</a>
|
||||
- <a href="#release-summary-6">Release Summary</a>
|
||||
- <a href="#release-summary-7">Release Summary</a>
|
||||
- <a href="#minor-changes-5">Minor Changes</a>
|
||||
- <a href="#bugfixes-6">Bugfixes</a>
|
||||
- <a href="#bugfixes-7">Bugfixes</a>
|
||||
- <a href="#new-plugins-2">New Plugins</a>
|
||||
- <a href="#lookup-1">Lookup</a>
|
||||
- <a href="#test">Test</a>
|
||||
- <a href="#new-modules-5">New Modules</a>
|
||||
- <a href="#v8-0-2">v8\.0\.2</a>
|
||||
- <a href="#release-summary-7">Release Summary</a>
|
||||
- <a href="#bugfixes-7">Bugfixes</a>
|
||||
- <a href="#v8-0-1">v8\.0\.1</a>
|
||||
- <a href="#release-summary-8">Release Summary</a>
|
||||
- <a href="#bugfixes-8">Bugfixes</a>
|
||||
- <a href="#v8-0-0">v8\.0\.0</a>
|
||||
- <a href="#v8-0-1">v8\.0\.1</a>
|
||||
- <a href="#release-summary-9">Release Summary</a>
|
||||
- <a href="#bugfixes-9">Bugfixes</a>
|
||||
- <a href="#v8-0-0">v8\.0\.0</a>
|
||||
- <a href="#release-summary-10">Release Summary</a>
|
||||
- <a href="#minor-changes-6">Minor Changes</a>
|
||||
- <a href="#breaking-changes--porting-guide">Breaking Changes / Porting Guide</a>
|
||||
- <a href="#deprecated-features-2">Deprecated Features</a>
|
||||
- <a href="#removed-features-previously-deprecated">Removed Features \(previously deprecated\)</a>
|
||||
- <a href="#bugfixes-9">Bugfixes</a>
|
||||
- <a href="#known-issues">Known Issues</a>
|
||||
- <a href="#bugfixes-10">Bugfixes</a>
|
||||
- <a href="#known-issues-1">Known Issues</a>
|
||||
- <a href="#new-plugins-3">New Plugins</a>
|
||||
- <a href="#lookup-2">Lookup</a>
|
||||
- <a href="#new-modules-6">New Modules</a>
|
||||
This changelog describes changes after version 7\.0\.0\.
|
||||
|
||||
<a id="v8-6-2"></a>
|
||||
## v8\.6\.2
|
||||
|
||||
<a id="release-summary"></a>
|
||||
### Release Summary
|
||||
|
||||
Regular bugfix release\.
|
||||
|
||||
<a id="bugfixes"></a>
|
||||
### Bugfixes
|
||||
|
||||
* git\_config \- fix behavior of <code>state\=absent</code> if <code>value</code> is present \([https\://github\.com/ansible\-collections/community\.general/issues/8436](https\://github\.com/ansible\-collections/community\.general/issues/8436)\, [https\://github\.com/ansible\-collections/community\.general/pull/8452](https\://github\.com/ansible\-collections/community\.general/pull/8452)\)\.
|
||||
* homebrew \- do not fail when brew prints warnings \([https\://github\.com/ansible\-collections/community\.general/pull/8406](https\://github\.com/ansible\-collections/community\.general/pull/8406)\, [https\://github\.com/ansible\-collections/community\.general/issues/7044](https\://github\.com/ansible\-collections/community\.general/issues/7044)\)\.
|
||||
* keycloak\_client \- fix TypeError when sanitizing the <code>saml\.signing\.private\.key</code> attribute in the module\'s diff or state output\. The <code>sanitize\_cr</code> function expected a dict where in some cases a list might occur \([https\://github\.com/ansible\-collections/community\.general/pull/8403](https\://github\.com/ansible\-collections/community\.general/pull/8403)\)\.
|
||||
* keycloak\_realm \- add normalizations for <code>attributes</code> and <code>protocol\_mappers</code> \([https\://github\.com/ansible\-collections/community\.general/pull/8496](https\://github\.com/ansible\-collections/community\.general/pull/8496)\)\.
|
||||
* launched \- correctly report changed status in check mode \([https\://github\.com/ansible\-collections/community\.general/pull/8406](https\://github\.com/ansible\-collections/community\.general/pull/8406)\)\.
|
||||
* opennebula inventory plugin \- fix invalid reference to IP when inventory runs against NICs with no IPv4 address \([https\://github\.com/ansible\-collections/community\.general/pull/8489](https\://github\.com/ansible\-collections/community\.general/pull/8489)\)\.
|
||||
* opentelemetry callback \- do not save the JSON response when using the <code>ansible\.builtin\.uri</code> module \([https\://github\.com/ansible\-collections/community\.general/pull/8430](https\://github\.com/ansible\-collections/community\.general/pull/8430)\)\.
|
||||
* opentelemetry callback \- do not save the content response when using the <code>ansible\.builtin\.slurp</code> module \([https\://github\.com/ansible\-collections/community\.general/pull/8430](https\://github\.com/ansible\-collections/community\.general/pull/8430)\)\.
|
||||
* paman \- do not fail if an empty list of packages has been provided and there is nothing to do \([https\://github\.com/ansible\-collections/community\.general/pull/8514](https\://github\.com/ansible\-collections/community\.general/pull/8514)\)\.
|
||||
|
||||
<a id="known-issues"></a>
|
||||
### Known Issues
|
||||
|
||||
* homectl \- the module does not work under Python 3\.13 or newer\, since it relies on the removed <code>crypt</code> standard library module \([https\://github\.com/ansible\-collections/community\.general/issues/4691](https\://github\.com/ansible\-collections/community\.general/issues/4691)\, [https\://github\.com/ansible\-collections/community\.general/pull/8497](https\://github\.com/ansible\-collections/community\.general/pull/8497)\)\.
|
||||
* udm\_user \- the module does not work under Python 3\.13 or newer\, since it relies on the removed <code>crypt</code> standard library module \([https\://github\.com/ansible\-collections/community\.general/issues/4690](https\://github\.com/ansible\-collections/community\.general/issues/4690)\, [https\://github\.com/ansible\-collections/community\.general/pull/8497](https\://github\.com/ansible\-collections/community\.general/pull/8497)\)\.
|
||||
|
||||
<a id="v8-6-1"></a>
|
||||
## v8\.6\.1
|
||||
|
||||
<a id="release-summary"></a>
|
||||
<a id="release-summary-1"></a>
|
||||
### Release Summary
|
||||
|
||||
Regular bugfix release\.
|
||||
@@ -81,7 +112,7 @@ Regular bugfix release\.
|
||||
|
||||
* keycloak\_identity\_provider \- the client secret was not correctly sanitized by the module\. The return values <code>proposed</code>\, <code>existing</code>\, and <code>end\_state</code>\, as well as the diff\, did contain the client secret unmasked \([https\://github\.com/ansible\-collections/community\.general/pull/8355](https\://github\.com/ansible\-collections/community\.general/pull/8355)\)\.
|
||||
|
||||
<a id="bugfixes"></a>
|
||||
<a id="bugfixes-1"></a>
|
||||
### Bugfixes
|
||||
|
||||
* keycloak\_user\_federation \- fix diff of empty <code>krbPrincipalAttribute</code> \([https\://github\.com/ansible\-collections/community\.general/pull/8320](https\://github\.com/ansible\-collections/community\.general/pull/8320)\)\.
|
||||
@@ -92,7 +123,7 @@ Regular bugfix release\.
|
||||
<a id="v8-6-0"></a>
|
||||
## v8\.6\.0
|
||||
|
||||
<a id="release-summary-1"></a>
|
||||
<a id="release-summary-2"></a>
|
||||
### Release Summary
|
||||
|
||||
Regular bugfix and features release\.
|
||||
@@ -120,7 +151,7 @@ Regular bugfix and features release\.
|
||||
|
||||
* hipchat callback plugin \- the hipchat service has been discontinued and the self\-hosted variant has been End of Life since 2020\. The callback plugin is therefore deprecated and will be removed from community\.general 10\.0\.0 if nobody provides compelling reasons to still keep it \([https\://github\.com/ansible\-collections/community\.general/issues/8184](https\://github\.com/ansible\-collections/community\.general/issues/8184)\, [https\://github\.com/ansible\-collections/community\.general/pull/8189](https\://github\.com/ansible\-collections/community\.general/pull/8189)\)\.
|
||||
|
||||
<a id="bugfixes-1"></a>
|
||||
<a id="bugfixes-2"></a>
|
||||
### Bugfixes
|
||||
|
||||
* aix\_filesystem \- fix <code>\_validate\_vg</code> not passing VG name to <code>lsvg\_cmd</code> \([https\://github\.com/ansible\-collections/community\.general/issues/8151](https\://github\.com/ansible\-collections/community\.general/issues/8151)\)\.
|
||||
@@ -146,7 +177,7 @@ Regular bugfix and features release\.
|
||||
<a id="v8-5-0"></a>
|
||||
## v8\.5\.0
|
||||
|
||||
<a id="release-summary-2"></a>
|
||||
<a id="release-summary-3"></a>
|
||||
### Release Summary
|
||||
|
||||
Regular feature and bugfix release with security fixes\.
|
||||
@@ -169,7 +200,7 @@ Regular feature and bugfix release with security fixes\.
|
||||
|
||||
* cobbler\, gitlab\_runners\, icinga2\, linode\, lxd\, nmap\, online\, opennebula\, proxmox\, scaleway\, stackpath\_compute\, virtualbox\, and xen\_orchestra inventory plugin \- make sure all data received from the remote servers is marked as unsafe\, so remote code execution by obtaining texts that can be evaluated as templates is not possible \([https\://www\.die\-welt\.net/2024/03/remote\-code\-execution\-in\-ansible\-dynamic\-inventory\-plugins/](https\://www\.die\-welt\.net/2024/03/remote\-code\-execution\-in\-ansible\-dynamic\-inventory\-plugins/)\, [https\://github\.com/ansible\-collections/community\.general/pull/8098](https\://github\.com/ansible\-collections/community\.general/pull/8098)\)\.
|
||||
|
||||
<a id="bugfixes-2"></a>
|
||||
<a id="bugfixes-3"></a>
|
||||
### Bugfixes
|
||||
|
||||
* aix\_filesystem \- fix issue with empty list items in crfs logic and option order \([https\://github\.com/ansible\-collections/community\.general/pull/8052](https\://github\.com/ansible\-collections/community\.general/pull/8052)\)\.
|
||||
@@ -191,7 +222,7 @@ Regular feature and bugfix release with security fixes\.
|
||||
<a id="v8-4-0"></a>
|
||||
## v8\.4\.0
|
||||
|
||||
<a id="release-summary-3"></a>
|
||||
<a id="release-summary-4"></a>
|
||||
### Release Summary
|
||||
|
||||
Regular bugfix and feature release\.
|
||||
@@ -209,7 +240,7 @@ Regular bugfix and feature release\.
|
||||
* sudoers \- add support for the <code>NOEXEC</code> tag in sudoers rules \([https\://github\.com/ansible\-collections/community\.general/pull/7983](https\://github\.com/ansible\-collections/community\.general/pull/7983)\)\.
|
||||
* terraform \- fix <code>diff\_mode</code> in state <code>absent</code> and when terraform <code>resource\_changes</code> does not exist \([https\://github\.com/ansible\-collections/community\.general/pull/7963](https\://github\.com/ansible\-collections/community\.general/pull/7963)\)\.
|
||||
|
||||
<a id="bugfixes-3"></a>
|
||||
<a id="bugfixes-4"></a>
|
||||
### Bugfixes
|
||||
|
||||
* cargo \- fix idempotency issues when using a custom installation path for packages \(using the <code>\-\-path</code> parameter\)\. The initial installation runs fine\, but subsequent runs use the <code>get\_installed\(\)</code> function which did not check the given installation location\, before running <code>cargo install</code>\. This resulted in a false <code>changed</code> state\. Also the removal of packeges using <code>state\: absent</code> failed\, as the installation check did not use the given parameter \([https\://github\.com/ansible\-collections/community\.general/pull/7970](https\://github\.com/ansible\-collections/community\.general/pull/7970)\)\.
|
||||
@@ -247,7 +278,7 @@ Regular bugfix and feature release\.
|
||||
<a id="v8-3-0"></a>
|
||||
## v8\.3\.0
|
||||
|
||||
<a id="release-summary-4"></a>
|
||||
<a id="release-summary-5"></a>
|
||||
### Release Summary
|
||||
|
||||
Regular bugfix and feature release\.
|
||||
@@ -270,7 +301,7 @@ Regular bugfix and feature release\.
|
||||
|
||||
* consul\_acl \- the module has been deprecated and will be removed in community\.general 10\.0\.0\. <code>consul\_token</code> and <code>consul\_policy</code> can be used instead \([https\://github\.com/ansible\-collections/community\.general/pull/7901](https\://github\.com/ansible\-collections/community\.general/pull/7901)\)\.
|
||||
|
||||
<a id="bugfixes-4"></a>
|
||||
<a id="bugfixes-5"></a>
|
||||
### Bugfixes
|
||||
|
||||
* homebrew \- detect already installed formulae and casks using JSON output from <code>brew info</code> \([https\://github\.com/ansible\-collections/community\.general/issues/864](https\://github\.com/ansible\-collections/community\.general/issues/864)\)\.
|
||||
@@ -294,7 +325,7 @@ Regular bugfix and feature release\.
|
||||
<a id="v8-2-0"></a>
|
||||
## v8\.2\.0
|
||||
|
||||
<a id="release-summary-5"></a>
|
||||
<a id="release-summary-6"></a>
|
||||
### Release Summary
|
||||
|
||||
Regular bugfix and feature release\.
|
||||
@@ -315,7 +346,7 @@ Regular bugfix and feature release\.
|
||||
* ssh\_config \- new feature to set <code>IdentitiesOnly</code> option to <code>yes</code> or <code>no</code> \([https\://github\.com/ansible\-collections/community\.general/pull/7704](https\://github\.com/ansible\-collections/community\.general/pull/7704)\)\.
|
||||
* xcc\_redfish\_command \- added support for raw POSTs \(<code>command\=PostResource</code> in <code>category\=Raw</code>\) without a specific action info \([https\://github\.com/ansible\-collections/community\.general/pull/7746](https\://github\.com/ansible\-collections/community\.general/pull/7746)\)\.
|
||||
|
||||
<a id="bugfixes-5"></a>
|
||||
<a id="bugfixes-6"></a>
|
||||
### Bugfixes
|
||||
|
||||
* keycloak\_identity\_provider \- <code>mappers</code> processing was not idempotent if the mappers configuration list had not been sorted by name \(in ascending order\)\. Fix resolves the issue by sorting mappers in the desired state using the same key which is used for obtaining existing state \([https\://github\.com/ansible\-collections/community\.general/pull/7418](https\://github\.com/ansible\-collections/community\.general/pull/7418)\)\.
|
||||
@@ -355,7 +386,7 @@ Regular bugfix and feature release\.
|
||||
<a id="v8-1-0"></a>
|
||||
## v8\.1\.0
|
||||
|
||||
<a id="release-summary-6"></a>
|
||||
<a id="release-summary-7"></a>
|
||||
### Release Summary
|
||||
|
||||
Regular bugfix and feature release\.
|
||||
@@ -397,7 +428,7 @@ Regular bugfix and feature release\.
|
||||
* redfish\_info \- adding the <code>BootProgress</code> property when getting <code>Systems</code> info \([https\://github\.com/ansible\-collections/community\.general/pull/7626](https\://github\.com/ansible\-collections/community\.general/pull/7626)\)\.
|
||||
* ssh\_config \- adds <code>controlmaster</code>\, <code>controlpath</code> and <code>controlpersist</code> parameters \([https\://github\.com/ansible\-collections/community\.general/pull/7456](https\://github\.com/ansible\-collections/community\.general/pull/7456)\)\.
|
||||
|
||||
<a id="bugfixes-6"></a>
|
||||
<a id="bugfixes-7"></a>
|
||||
### Bugfixes
|
||||
|
||||
* apt\-rpm \- the module did not upgrade packages if a newer version exists\. Now the package will be reinstalled if the candidate is newer than the installed version \([https\://github\.com/ansible\-collections/community\.general/issues/7414](https\://github\.com/ansible\-collections/community\.general/issues/7414)\)\.
|
||||
@@ -438,12 +469,12 @@ Regular bugfix and feature release\.
|
||||
<a id="v8-0-2"></a>
|
||||
## v8\.0\.2
|
||||
|
||||
<a id="release-summary-7"></a>
|
||||
<a id="release-summary-8"></a>
|
||||
### Release Summary
|
||||
|
||||
Bugfix release for inclusion in Ansible 9\.0\.0rc1\.
|
||||
|
||||
<a id="bugfixes-7"></a>
|
||||
<a id="bugfixes-8"></a>
|
||||
### Bugfixes
|
||||
|
||||
* ocapi\_utils\, oci\_utils\, redfish\_utils module utils \- replace <code>type\(\)</code> calls with <code>isinstance\(\)</code> calls \([https\://github\.com/ansible\-collections/community\.general/pull/7501](https\://github\.com/ansible\-collections/community\.general/pull/7501)\)\.
|
||||
@@ -452,12 +483,12 @@ Bugfix release for inclusion in Ansible 9\.0\.0rc1\.
|
||||
<a id="v8-0-1"></a>
|
||||
## v8\.0\.1
|
||||
|
||||
<a id="release-summary-8"></a>
|
||||
<a id="release-summary-9"></a>
|
||||
### Release Summary
|
||||
|
||||
Bugfix release for inclusion in Ansible 9\.0\.0b1\.
|
||||
|
||||
<a id="bugfixes-8"></a>
|
||||
<a id="bugfixes-9"></a>
|
||||
### Bugfixes
|
||||
|
||||
* gitlab\_group\_members \- fix gitlab constants call in <code>gitlab\_group\_members</code> module \([https\://github\.com/ansible\-collections/community\.general/issues/7467](https\://github\.com/ansible\-collections/community\.general/issues/7467)\)\.
|
||||
@@ -470,7 +501,7 @@ Bugfix release for inclusion in Ansible 9\.0\.0b1\.
|
||||
<a id="v8-0-0"></a>
|
||||
## v8\.0\.0
|
||||
|
||||
<a id="release-summary-9"></a>
|
||||
<a id="release-summary-10"></a>
|
||||
### Release Summary
|
||||
|
||||
This is release 8\.0\.0 of <code>community\.general</code>\, released on 2023\-11\-01\.
|
||||
@@ -674,7 +705,7 @@ This is release 8\.0\.0 of <code>community\.general</code>\, released on 2023\-1
|
||||
* proxmox module utils \- removed unused imports \([https\://github\.com/ansible\-collections/community\.general/pull/6873](https\://github\.com/ansible\-collections/community\.general/pull/6873)\)\.
|
||||
* xfconf \- the deprecated <code>disable\_facts</code> option was removed \([https\://github\.com/ansible\-collections/community\.general/pull/7358](https\://github\.com/ansible\-collections/community\.general/pull/7358)\)\.
|
||||
|
||||
<a id="bugfixes-9"></a>
|
||||
<a id="bugfixes-10"></a>
|
||||
### Bugfixes
|
||||
|
||||
* CmdRunner module utils \- does not attempt to resolve path if executable is a relative or absolute path \([https\://github\.com/ansible\-collections/community\.general/pull/7200](https\://github\.com/ansible\-collections/community\.general/pull/7200)\)\.
|
||||
@@ -756,7 +787,7 @@ This is release 8\.0\.0 of <code>community\.general</code>\, released on 2023\-1
|
||||
* tss lookup plugin \- fix multiple issues when using <code>fetch\_attachments\=true</code> \([https\://github\.com/ansible\-collections/community\.general/pull/6720](https\://github\.com/ansible\-collections/community\.general/pull/6720)\)\.
|
||||
* zypper \- added handling of zypper exitcode 102\. Changed state is set correctly now and rc 102 is still preserved to be evaluated by the playbook \([https\://github\.com/ansible\-collections/community\.general/pull/6534](https\://github\.com/ansible\-collections/community\.general/pull/6534)\)\.
|
||||
|
||||
<a id="known-issues"></a>
|
||||
<a id="known-issues-1"></a>
|
||||
### Known Issues
|
||||
|
||||
* Ansible markup will show up in raw form on ansible\-doc text output for ansible\-core before 2\.15\. If you have trouble deciphering the documentation markup\, please upgrade to ansible\-core 2\.15 \(or newer\)\, or read the HTML documentation on [https\://docs\.ansible\.com/ansible/devel/collections/community/general/](https\://docs\.ansible\.com/ansible/devel/collections/community/general/) \([https\://github\.com/ansible\-collections/community\.general/pull/6539](https\://github\.com/ansible\-collections/community\.general/pull/6539)\)\.
|
||||
|
||||
@@ -6,6 +6,33 @@ Community General Release Notes
|
||||
|
||||
This changelog describes changes after version 7.0.0.
|
||||
|
||||
v8.6.2
|
||||
======
|
||||
|
||||
Release Summary
|
||||
---------------
|
||||
|
||||
Regular bugfix release.
|
||||
|
||||
Bugfixes
|
||||
--------
|
||||
|
||||
- git_config - fix behavior of ``state=absent`` if ``value`` is present (https://github.com/ansible-collections/community.general/issues/8436, https://github.com/ansible-collections/community.general/pull/8452).
|
||||
- homebrew - do not fail when brew prints warnings (https://github.com/ansible-collections/community.general/pull/8406, https://github.com/ansible-collections/community.general/issues/7044).
|
||||
- keycloak_client - fix TypeError when sanitizing the ``saml.signing.private.key`` attribute in the module's diff or state output. The ``sanitize_cr`` function expected a dict where in some cases a list might occur (https://github.com/ansible-collections/community.general/pull/8403).
|
||||
- keycloak_realm - add normalizations for ``attributes`` and ``protocol_mappers`` (https://github.com/ansible-collections/community.general/pull/8496).
|
||||
- launched - correctly report changed status in check mode (https://github.com/ansible-collections/community.general/pull/8406).
|
||||
- opennebula inventory plugin - fix invalid reference to IP when inventory runs against NICs with no IPv4 address (https://github.com/ansible-collections/community.general/pull/8489).
|
||||
- opentelemetry callback - do not save the JSON response when using the ``ansible.builtin.uri`` module (https://github.com/ansible-collections/community.general/pull/8430).
|
||||
- opentelemetry callback - do not save the content response when using the ``ansible.builtin.slurp`` module (https://github.com/ansible-collections/community.general/pull/8430).
|
||||
- paman - do not fail if an empty list of packages has been provided and there is nothing to do (https://github.com/ansible-collections/community.general/pull/8514).
|
||||
|
||||
Known Issues
|
||||
------------
|
||||
|
||||
- homectl - the module does not work under Python 3.13 or newer, since it relies on the removed ``crypt`` standard library module (https://github.com/ansible-collections/community.general/issues/4691, https://github.com/ansible-collections/community.general/pull/8497).
|
||||
- udm_user - the module does not work under Python 3.13 or newer, since it relies on the removed ``crypt`` standard library module (https://github.com/ansible-collections/community.general/issues/4690, https://github.com/ansible-collections/community.general/pull/8497).
|
||||
|
||||
v8.6.1
|
||||
======
|
||||
|
||||
|
||||
@@ -1455,3 +1455,44 @@ releases:
|
||||
- 8367-fix-close-span-if-no-logs.yaml
|
||||
- 8373-honour-disable-logs.yaml
|
||||
release_date: '2024-05-20'
|
||||
8.6.2:
|
||||
changes:
|
||||
bugfixes:
|
||||
- git_config - fix behavior of ``state=absent`` if ``value`` is present (https://github.com/ansible-collections/community.general/issues/8436,
|
||||
https://github.com/ansible-collections/community.general/pull/8452).
|
||||
- homebrew - do not fail when brew prints warnings (https://github.com/ansible-collections/community.general/pull/8406,
|
||||
https://github.com/ansible-collections/community.general/issues/7044).
|
||||
- keycloak_client - fix TypeError when sanitizing the ``saml.signing.private.key``
|
||||
attribute in the module's diff or state output. The ``sanitize_cr`` function
|
||||
expected a dict where in some cases a list might occur (https://github.com/ansible-collections/community.general/pull/8403).
|
||||
- keycloak_realm - add normalizations for ``attributes`` and ``protocol_mappers``
|
||||
(https://github.com/ansible-collections/community.general/pull/8496).
|
||||
- launched - correctly report changed status in check mode (https://github.com/ansible-collections/community.general/pull/8406).
|
||||
- opennebula inventory plugin - fix invalid reference to IP when inventory runs
|
||||
against NICs with no IPv4 address (https://github.com/ansible-collections/community.general/pull/8489).
|
||||
- opentelemetry callback - do not save the JSON response when using the ``ansible.builtin.uri``
|
||||
module (https://github.com/ansible-collections/community.general/pull/8430).
|
||||
- opentelemetry callback - do not save the content response when using the ``ansible.builtin.slurp``
|
||||
module (https://github.com/ansible-collections/community.general/pull/8430).
|
||||
- paman - do not fail if an empty list of packages has been provided and there
|
||||
is nothing to do (https://github.com/ansible-collections/community.general/pull/8514).
|
||||
known_issues:
|
||||
- homectl - the module does not work under Python 3.13 or newer, since it relies
|
||||
on the removed ``crypt`` standard library module (https://github.com/ansible-collections/community.general/issues/4691,
|
||||
https://github.com/ansible-collections/community.general/pull/8497).
|
||||
- udm_user - the module does not work under Python 3.13 or newer, since it relies
|
||||
on the removed ``crypt`` standard library module (https://github.com/ansible-collections/community.general/issues/4690,
|
||||
https://github.com/ansible-collections/community.general/pull/8497).
|
||||
release_summary: Regular bugfix release.
|
||||
fragments:
|
||||
- 8.6.2.yml
|
||||
- 8403-fix-typeerror-in-keycloak-client.yaml
|
||||
- 8406-fix-homebrew-cask-warning.yaml
|
||||
- 8430-fix-opentelemetry-when-using-logs-with-uri-or-slurp-tasks.yaml
|
||||
- 8452-git_config-absent.yml
|
||||
- 8476-launchd-check-mode-changed.yaml
|
||||
- 8489-fix-opennebula-inventory-crash-when-nic-has-no-ip.yml
|
||||
- 8496-keycloak_clientscope-add-normalizations.yaml
|
||||
- 8497-crypt.yml
|
||||
- 8514-pacman-empty.yml
|
||||
release_date: '2024-06-17'
|
||||
|
||||
@@ -2,17 +2,11 @@
|
||||
# Copyright (c) Ansible Project
|
||||
# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
|
||||
# SPDX-License-Identifier: GPL-3.0-or-later
|
||||
|
||||
list1:
|
||||
- name: foo
|
||||
extra: true
|
||||
- name: bar
|
||||
extra: false
|
||||
- name: meh
|
||||
extra: true
|
||||
- {name: foo, extra: true}
|
||||
- {name: bar, extra: false}
|
||||
- {name: meh, extra: true}
|
||||
|
||||
list2:
|
||||
- name: foo
|
||||
path: /foo
|
||||
- name: baz
|
||||
path: /baz
|
||||
- {name: foo, path: /foo}
|
||||
- {name: baz, path: /baz}
|
||||
|
||||
@@ -2,14 +2,12 @@
|
||||
# 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
|
||||
|
||||
list1:
|
||||
- name: myname01
|
||||
param01:
|
||||
x: default_value
|
||||
y: default_value
|
||||
list:
|
||||
- default_value
|
||||
list: [default_value]
|
||||
- name: myname02
|
||||
param01: [1, 1, 2, 3]
|
||||
|
||||
@@ -18,7 +16,6 @@ list2:
|
||||
param01:
|
||||
y: patch_value
|
||||
z: patch_value
|
||||
list:
|
||||
- patch_value
|
||||
list: [patch_value]
|
||||
- name: myname02
|
||||
param01: [3, 4, 4, {key: value}]
|
||||
param01: [3, 4, 4]
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
dir: example-001_vars
|
||||
- debug:
|
||||
var: list3
|
||||
when: debug|d(false)|bool
|
||||
when: debug | d(false) | bool
|
||||
- template:
|
||||
src: list3.out.j2
|
||||
dest: example-001.out
|
||||
|
||||
@@ -2,6 +2,5 @@
|
||||
# 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
|
||||
|
||||
list3: "{{ list1|
|
||||
list3: "{{ list1 |
|
||||
community.general.lists_mergeby(list2, 'name') }}"
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
dir: example-002_vars
|
||||
- debug:
|
||||
var: list3
|
||||
when: debug|d(false)|bool
|
||||
when: debug | d(false) | bool
|
||||
- template:
|
||||
src: list3.out.j2
|
||||
dest: example-002.out
|
||||
|
||||
@@ -2,6 +2,5 @@
|
||||
# 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
|
||||
|
||||
list3: "{{ [list1, list2]|
|
||||
list3: "{{ [list1, list2] |
|
||||
community.general.lists_mergeby('name') }}"
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
dir: example-003_vars
|
||||
- debug:
|
||||
var: list3
|
||||
when: debug|d(false)|bool
|
||||
when: debug | d(false) | bool
|
||||
- template:
|
||||
src: list3.out.j2
|
||||
dest: example-003.out
|
||||
|
||||
@@ -2,7 +2,6 @@
|
||||
# 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
|
||||
|
||||
list3: "{{ [list1, list2]|
|
||||
list3: "{{ [list1, list2] |
|
||||
community.general.lists_mergeby('name',
|
||||
recursive=true) }}"
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
dir: example-004_vars
|
||||
- debug:
|
||||
var: list3
|
||||
when: debug|d(false)|bool
|
||||
when: debug | d(false) | bool
|
||||
- template:
|
||||
src: list3.out.j2
|
||||
dest: example-004.out
|
||||
|
||||
@@ -2,8 +2,7 @@
|
||||
# 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
|
||||
|
||||
list3: "{{ [list1, list2]|
|
||||
list3: "{{ [list1, list2] |
|
||||
community.general.lists_mergeby('name',
|
||||
recursive=true,
|
||||
list_merge='keep') }}"
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
dir: example-005_vars
|
||||
- debug:
|
||||
var: list3
|
||||
when: debug|d(false)|bool
|
||||
when: debug | d(false) | bool
|
||||
- template:
|
||||
src: list3.out.j2
|
||||
dest: example-005.out
|
||||
|
||||
@@ -2,8 +2,7 @@
|
||||
# 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
|
||||
|
||||
list3: "{{ [list1, list2]|
|
||||
list3: "{{ [list1, list2] |
|
||||
community.general.lists_mergeby('name',
|
||||
recursive=true,
|
||||
list_merge='append') }}"
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
dir: example-006_vars
|
||||
- debug:
|
||||
var: list3
|
||||
when: debug|d(false)|bool
|
||||
when: debug | d(false) | bool
|
||||
- template:
|
||||
src: list3.out.j2
|
||||
dest: example-006.out
|
||||
|
||||
@@ -2,8 +2,7 @@
|
||||
# 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
|
||||
|
||||
list3: "{{ [list1, list2]|
|
||||
list3: "{{ [list1, list2] |
|
||||
community.general.lists_mergeby('name',
|
||||
recursive=true,
|
||||
list_merge='prepend') }}"
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
dir: example-007_vars
|
||||
- debug:
|
||||
var: list3
|
||||
when: debug|d(false)|bool
|
||||
when: debug|d(false) | bool
|
||||
- template:
|
||||
src: list3.out.j2
|
||||
dest: example-007.out
|
||||
|
||||
@@ -2,8 +2,7 @@
|
||||
# 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
|
||||
|
||||
list3: "{{ [list1, list2]|
|
||||
list3: "{{ [list1, list2] |
|
||||
community.general.lists_mergeby('name',
|
||||
recursive=true,
|
||||
list_merge='append_rp') }}"
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
dir: example-008_vars
|
||||
- debug:
|
||||
var: list3
|
||||
when: debug|d(false)|bool
|
||||
when: debug | d(false) | bool
|
||||
- template:
|
||||
src: list3.out.j2
|
||||
dest: example-008.out
|
||||
|
||||
@@ -2,8 +2,7 @@
|
||||
# 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
|
||||
|
||||
list3: "{{ [list1, list2]|
|
||||
list3: "{{ [list1, list2] |
|
||||
community.general.lists_mergeby('name',
|
||||
recursive=true,
|
||||
list_merge='prepend_rp') }}"
|
||||
|
||||
14
docs/docsite/helper/lists_mergeby/example-009.yml
Normal file
14
docs/docsite/helper/lists_mergeby/example-009.yml
Normal file
@@ -0,0 +1,14 @@
|
||||
---
|
||||
# Copyright (c) Ansible Project
|
||||
# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
|
||||
# SPDX-License-Identifier: GPL-3.0-or-later
|
||||
|
||||
- name: 9. Merge single list by common attribute 'name'
|
||||
include_vars:
|
||||
dir: example-009_vars
|
||||
- debug:
|
||||
var: list3
|
||||
when: debug | d(false) | bool
|
||||
- template:
|
||||
src: list3.out.j2
|
||||
dest: example-009.out
|
||||
@@ -0,0 +1 @@
|
||||
../default-common.yml
|
||||
@@ -0,0 +1,6 @@
|
||||
---
|
||||
# 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
|
||||
list3: "{{ [list1 + list2, []] |
|
||||
community.general.lists_mergeby('name') }}"
|
||||
@@ -4,51 +4,75 @@
|
||||
# SPDX-License-Identifier: GPL-3.0-or-later
|
||||
|
||||
examples:
|
||||
- label: 'In the example below the lists are merged by the attribute ``name``:'
|
||||
- title: Two lists
|
||||
description: 'In the example below the lists are merged by the attribute ``name``:'
|
||||
file: example-001_vars/list3.yml
|
||||
lang: 'yaml+jinja'
|
||||
- label: 'This produces:'
|
||||
- title:
|
||||
description: 'This produces:'
|
||||
file: example-001.out
|
||||
lang: 'yaml'
|
||||
- label: 'It is possible to use a list of lists as an input of the filter:'
|
||||
- title: List of two lists
|
||||
description: 'It is possible to use a list of lists as an input of the filter:'
|
||||
file: example-002_vars/list3.yml
|
||||
lang: 'yaml+jinja'
|
||||
- label: 'This produces the same result as in the previous example:'
|
||||
- title:
|
||||
description: 'This produces the same result as in the previous example:'
|
||||
file: example-002.out
|
||||
lang: 'yaml'
|
||||
- label: 'Example ``list_merge=replace`` (default):'
|
||||
- title: Single list
|
||||
description: 'It is possible to merge single list:'
|
||||
file: example-009_vars/list3.yml
|
||||
lang: 'yaml+jinja'
|
||||
- title:
|
||||
description: 'This produces the same result as in the previous example:'
|
||||
file: example-009.out
|
||||
lang: 'yaml'
|
||||
- title: list_merge=replace (default)
|
||||
description: 'Example :ansopt:`community.general.lists_mergeby#filter:list_merge=replace` (default):'
|
||||
file: example-003_vars/list3.yml
|
||||
lang: 'yaml+jinja'
|
||||
- label: 'This produces:'
|
||||
- title:
|
||||
description: 'This produces:'
|
||||
file: example-003.out
|
||||
lang: 'yaml'
|
||||
- label: 'Example ``list_merge=keep``:'
|
||||
- title: list_merge=keep
|
||||
description: 'Example :ansopt:`community.general.lists_mergeby#filter:list_merge=keep`:'
|
||||
file: example-004_vars/list3.yml
|
||||
lang: 'yaml+jinja'
|
||||
- label: 'This produces:'
|
||||
- title:
|
||||
description: 'This produces:'
|
||||
file: example-004.out
|
||||
lang: 'yaml'
|
||||
- label: 'Example ``list_merge=append``:'
|
||||
- title: list_merge=append
|
||||
description: 'Example :ansopt:`community.general.lists_mergeby#filter:list_merge=append`:'
|
||||
file: example-005_vars/list3.yml
|
||||
lang: 'yaml+jinja'
|
||||
- label: 'This produces:'
|
||||
- title:
|
||||
description: 'This produces:'
|
||||
file: example-005.out
|
||||
lang: 'yaml'
|
||||
- label: 'Example ``list_merge=prepend``:'
|
||||
- title: list_merge=prepend
|
||||
description: 'Example :ansopt:`community.general.lists_mergeby#filter:list_merge=prepend`:'
|
||||
file: example-006_vars/list3.yml
|
||||
lang: 'yaml+jinja'
|
||||
- label: 'This produces:'
|
||||
- title:
|
||||
description: 'This produces:'
|
||||
file: example-006.out
|
||||
lang: 'yaml'
|
||||
- label: 'Example ``list_merge=append_rp``:'
|
||||
- title: list_merge=append_rp
|
||||
description: 'Example :ansopt:`community.general.lists_mergeby#filter:list_merge=append_rp`:'
|
||||
file: example-007_vars/list3.yml
|
||||
lang: 'yaml+jinja'
|
||||
- label: 'This produces:'
|
||||
- title:
|
||||
description: 'This produces:'
|
||||
file: example-007.out
|
||||
lang: 'yaml'
|
||||
- label: 'Example ``list_merge=prepend_rp``:'
|
||||
- title: list_merge=prepend_rp
|
||||
description: 'Example :ansopt:`community.general.lists_mergeby#filter:list_merge=prepend_rp`:'
|
||||
file: example-008_vars/list3.yml
|
||||
lang: 'yaml+jinja'
|
||||
- label: 'This produces:'
|
||||
- title:
|
||||
description: 'This produces:'
|
||||
file: example-008.out
|
||||
lang: 'yaml'
|
||||
|
||||
@@ -4,10 +4,10 @@
|
||||
SPDX-License-Identifier: GPL-3.0-or-later
|
||||
|
||||
{% for i in examples %}
|
||||
{{ i.label }}
|
||||
{{ i.description }}
|
||||
|
||||
.. code-block:: {{ i.lang }}
|
||||
|
||||
{{ lookup('file', i.file)|indent(2) }}
|
||||
{{ lookup('file', i.file) | split('\n') | reject('match', '^(#|---)') | join ('\n') | indent(2) }}
|
||||
|
||||
{% endfor %}
|
||||
|
||||
7
docs/docsite/helper/lists_mergeby/extra-vars.yml
Normal file
7
docs/docsite/helper/lists_mergeby/extra-vars.yml
Normal file
@@ -0,0 +1,7 @@
|
||||
---
|
||||
# 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
|
||||
examples_one: true
|
||||
examples_all: true
|
||||
merging_lists_of_dictionaries: true
|
||||
@@ -6,57 +6,69 @@
|
||||
Merging lists of dictionaries
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
If you have two or more lists of dictionaries and want to combine them into a list of merged dictionaries, where the dictionaries are merged by an attribute, you can use the ``lists_mergeby`` filter.
|
||||
If you have two or more lists of dictionaries and want to combine them into a list of merged dictionaries, where the dictionaries are merged by an attribute, you can use the :ansplugin:`community.general.lists_mergeby <community.general.lists_mergeby#filter>` filter.
|
||||
|
||||
.. note:: The output of the examples in this section use the YAML callback plugin. Quoting: "Ansible output that can be quite a bit easier to read than the default JSON formatting." See :ref:`the documentation for the community.general.yaml callback plugin <ansible_collections.community.general.yaml_callback>`.
|
||||
.. note:: The output of the examples in this section use the YAML callback plugin. Quoting: "Ansible output that can be quite a bit easier to read than the default JSON formatting." See the documentation for the :ansplugin:`community.general.yaml callback plugin <community.general.yaml#callback>`.
|
||||
|
||||
Let us use the lists below in the following examples:
|
||||
|
||||
.. code-block:: yaml
|
||||
|
||||
{{ lookup('file', 'default-common.yml')|indent(2) }}
|
||||
{{ lookup('file', 'default-common.yml') | split('\n') | reject('match', '^(#|---)') | join ('\n') | indent(2) }}
|
||||
|
||||
{% for i in examples[0:2] %}
|
||||
{{ i.label }}
|
||||
{% if i.title | d('', true) | length > 0 %}
|
||||
{{ i.title }}
|
||||
{{ "%s" % ('"' * i.title|length) }}
|
||||
{% endif %}
|
||||
{{ i.description }}
|
||||
|
||||
.. code-block:: {{ i.lang }}
|
||||
|
||||
{{ lookup('file', i.file)|indent(2) }}
|
||||
{{ lookup('file', i.file) | split('\n') | reject('match', '^(#|---)') | join ('\n') | indent(2) }}
|
||||
|
||||
{% endfor %}
|
||||
|
||||
.. versionadded:: 2.0.0
|
||||
|
||||
{% for i in examples[2:4] %}
|
||||
{{ i.label }}
|
||||
{% for i in examples[2:6] %}
|
||||
{% if i.title | d('', true) | length > 0 %}
|
||||
{{ i.title }}
|
||||
{{ "%s" % ('"' * i.title|length) }}
|
||||
{% endif %}
|
||||
{{ i.description }}
|
||||
|
||||
.. code-block:: {{ i.lang }}
|
||||
|
||||
{{ lookup('file', i.file)|indent(2) }}
|
||||
{{ lookup('file', i.file) | split('\n') | reject('match', '^(#|---)') | join ('\n') | indent(2) }}
|
||||
|
||||
{% endfor %}
|
||||
|
||||
The filter also accepts two optional parameters: ``recursive`` and ``list_merge``. These parameters are only supported when used with ansible-base 2.10 or ansible-core, but not with Ansible 2.9. This is available since community.general 4.4.0.
|
||||
The filter also accepts two optional parameters: :ansopt:`community.general.lists_mergeby#filter:recursive` and :ansopt:`community.general.lists_mergeby#filter:list_merge`. This is available since community.general 4.4.0.
|
||||
|
||||
**recursive**
|
||||
Is a boolean, default to ``False``. Should the ``community.general.lists_mergeby`` recursively merge nested hashes. Note: It does not depend on the value of the ``hash_behaviour`` setting in ``ansible.cfg``.
|
||||
Is a boolean, default to ``false``. Should the :ansplugin:`community.general.lists_mergeby#filter` filter recursively merge nested hashes. Note: It does not depend on the value of the ``hash_behaviour`` setting in ``ansible.cfg``.
|
||||
|
||||
**list_merge**
|
||||
Is a string, its possible values are ``replace`` (default), ``keep``, ``append``, ``prepend``, ``append_rp`` or ``prepend_rp``. It modifies the behaviour of ``community.general.lists_mergeby`` when the hashes to merge contain arrays/lists.
|
||||
Is a string, its possible values are :ansval:`replace` (default), :ansval:`keep`, :ansval:`append`, :ansval:`prepend`, :ansval:`append_rp` or :ansval:`prepend_rp`. It modifies the behaviour of :ansplugin:`community.general.lists_mergeby#filter` when the hashes to merge contain arrays/lists.
|
||||
|
||||
The examples below set ``recursive=true`` and display the differences among all six options of ``list_merge``. Functionality of the parameters is exactly the same as in the filter ``combine``. See :ref:`Combining hashes/dictionaries <combine_filter>` to learn details about these options.
|
||||
The examples below set :ansopt:`community.general.lists_mergeby#filter:recursive=true` and display the differences among all six options of :ansopt:`community.general.lists_mergeby#filter:list_merge`. Functionality of the parameters is exactly the same as in the filter :ansplugin:`ansible.builtin.combine#filter`. See :ref:`Combining hashes/dictionaries <combine_filter>` to learn details about these options.
|
||||
|
||||
Let us use the lists below in the following examples
|
||||
|
||||
.. code-block:: yaml
|
||||
|
||||
{{ lookup('file', 'default-recursive-true.yml')|indent(2) }}
|
||||
{{ lookup('file', 'default-recursive-true.yml') | split('\n') | reject('match', '^(#|---)') | join ('\n') |indent(2) }}
|
||||
|
||||
{% for i in examples[4:16] %}
|
||||
{{ i.label }}
|
||||
{% for i in examples[6:] %}
|
||||
{% if i.title | d('', true) | length > 0 %}
|
||||
{{ i.title }}
|
||||
{{ "%s" % ('"' * i.title|length) }}
|
||||
{% endif %}
|
||||
{{ i.description }}
|
||||
|
||||
.. code-block:: {{ i.lang }}
|
||||
|
||||
{{ lookup('file', i.file)|indent(2) }}
|
||||
{{ lookup('file', i.file) | split('\n') | reject('match', '^(#|---)') | join ('\n') |indent(2) }}
|
||||
|
||||
{% endfor %}
|
||||
|
||||
@@ -4,4 +4,4 @@ GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://w
|
||||
SPDX-License-Identifier: GPL-3.0-or-later
|
||||
#}
|
||||
list3:
|
||||
{{ list3|to_nice_yaml(indent=0) }}
|
||||
{{ list3 | to_yaml(indent=2, sort_keys=false) | indent(2) }}
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
|
||||
# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
# 1) Run all examples and create example-XXX.out
|
||||
# shell> ansible-playbook playbook.yml -e examples=true
|
||||
# shell> ansible-playbook playbook.yml -e examples_one=true
|
||||
#
|
||||
# 2) Optionally, for testing, create examples_all.rst
|
||||
# shell> ansible-playbook playbook.yml -e examples_all=true
|
||||
@@ -45,18 +45,20 @@
|
||||
tags: t007
|
||||
- import_tasks: example-008.yml
|
||||
tags: t008
|
||||
when: examples|d(false)|bool
|
||||
- import_tasks: example-009.yml
|
||||
tags: t009
|
||||
when: examples_one | d(false) | bool
|
||||
|
||||
- block:
|
||||
- include_vars: examples.yml
|
||||
- template:
|
||||
src: examples_all.rst.j2
|
||||
dest: examples_all.rst
|
||||
when: examples_all|d(false)|bool
|
||||
when: examples_all | d(false) | bool
|
||||
|
||||
- block:
|
||||
- include_vars: examples.yml
|
||||
- template:
|
||||
src: filter_guide_abstract_informations_merging_lists_of_dictionaries.rst.j2
|
||||
dest: filter_guide_abstract_informations_merging_lists_of_dictionaries.rst
|
||||
when: merging_lists_of_dictionaries|d(false)|bool
|
||||
when: merging_lists_of_dictionaries | d(false) | bool
|
||||
|
||||
@@ -6,33 +6,30 @@
|
||||
Merging lists of dictionaries
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
If you have two or more lists of dictionaries and want to combine them into a list of merged dictionaries, where the dictionaries are merged by an attribute, you can use the :ansplugin:`community.general.lists_mergeby filter <community.general.lists_mergeby#filter>`.
|
||||
If you have two or more lists of dictionaries and want to combine them into a list of merged dictionaries, where the dictionaries are merged by an attribute, you can use the :ansplugin:`community.general.lists_mergeby <community.general.lists_mergeby#filter>` filter.
|
||||
|
||||
.. note:: The output of the examples in this section use the YAML callback plugin. Quoting: "Ansible output that can be quite a bit easier to read than the default JSON formatting." See :ref:`the documentation for the community.general.yaml callback plugin <ansible_collections.community.general.yaml_callback>`.
|
||||
.. note:: The output of the examples in this section use the YAML callback plugin. Quoting: "Ansible output that can be quite a bit easier to read than the default JSON formatting." See the documentation for the :ansplugin:`community.general.yaml callback plugin <community.general.yaml#callback>`.
|
||||
|
||||
Let us use the lists below in the following examples:
|
||||
|
||||
.. code-block:: yaml
|
||||
|
||||
list1:
|
||||
- name: foo
|
||||
extra: true
|
||||
- name: bar
|
||||
extra: false
|
||||
- name: meh
|
||||
extra: true
|
||||
- {name: foo, extra: true}
|
||||
- {name: bar, extra: false}
|
||||
- {name: meh, extra: true}
|
||||
|
||||
list2:
|
||||
- name: foo
|
||||
path: /foo
|
||||
- name: baz
|
||||
path: /baz
|
||||
- {name: foo, path: /foo}
|
||||
- {name: baz, path: /baz}
|
||||
|
||||
Two lists
|
||||
"""""""""
|
||||
In the example below the lists are merged by the attribute ``name``:
|
||||
|
||||
.. code-block:: yaml+jinja
|
||||
|
||||
list3: "{{ list1|
|
||||
list3: "{{ list1 |
|
||||
community.general.lists_mergeby(list2, 'name') }}"
|
||||
|
||||
This produces:
|
||||
@@ -40,24 +37,21 @@ This produces:
|
||||
.. code-block:: yaml
|
||||
|
||||
list3:
|
||||
- extra: false
|
||||
name: bar
|
||||
- name: baz
|
||||
path: /baz
|
||||
- extra: true
|
||||
name: foo
|
||||
path: /foo
|
||||
- extra: true
|
||||
name: meh
|
||||
- {name: bar, extra: false}
|
||||
- {name: baz, path: /baz}
|
||||
- {name: foo, extra: true, path: /foo}
|
||||
- {name: meh, extra: true}
|
||||
|
||||
|
||||
.. versionadded:: 2.0.0
|
||||
|
||||
List of two lists
|
||||
"""""""""""""""""
|
||||
It is possible to use a list of lists as an input of the filter:
|
||||
|
||||
.. code-block:: yaml+jinja
|
||||
|
||||
list3: "{{ [list1, list2]|
|
||||
list3: "{{ [list1, list2] |
|
||||
community.general.lists_mergeby('name') }}"
|
||||
|
||||
This produces the same result as in the previous example:
|
||||
@@ -65,15 +59,29 @@ This produces the same result as in the previous example:
|
||||
.. code-block:: yaml
|
||||
|
||||
list3:
|
||||
- extra: false
|
||||
name: bar
|
||||
- name: baz
|
||||
path: /baz
|
||||
- extra: true
|
||||
name: foo
|
||||
path: /foo
|
||||
- extra: true
|
||||
name: meh
|
||||
- {name: bar, extra: false}
|
||||
- {name: baz, path: /baz}
|
||||
- {name: foo, extra: true, path: /foo}
|
||||
- {name: meh, extra: true}
|
||||
|
||||
Single list
|
||||
"""""""""""
|
||||
It is possible to merge single list:
|
||||
|
||||
.. code-block:: yaml+jinja
|
||||
|
||||
list3: "{{ [list1 + list2, []] |
|
||||
community.general.lists_mergeby('name') }}"
|
||||
|
||||
This produces the same result as in the previous example:
|
||||
|
||||
.. code-block:: yaml
|
||||
|
||||
list3:
|
||||
- {name: bar, extra: false}
|
||||
- {name: baz, path: /baz}
|
||||
- {name: foo, extra: true, path: /foo}
|
||||
- {name: meh, extra: true}
|
||||
|
||||
|
||||
The filter also accepts two optional parameters: :ansopt:`community.general.lists_mergeby#filter:recursive` and :ansopt:`community.general.lists_mergeby#filter:list_merge`. This is available since community.general 4.4.0.
|
||||
@@ -95,8 +103,7 @@ Let us use the lists below in the following examples
|
||||
param01:
|
||||
x: default_value
|
||||
y: default_value
|
||||
list:
|
||||
- default_value
|
||||
list: [default_value]
|
||||
- name: myname02
|
||||
param01: [1, 1, 2, 3]
|
||||
|
||||
@@ -105,16 +112,17 @@ Let us use the lists below in the following examples
|
||||
param01:
|
||||
y: patch_value
|
||||
z: patch_value
|
||||
list:
|
||||
- patch_value
|
||||
list: [patch_value]
|
||||
- name: myname02
|
||||
param01: [3, 4, 4, {key: value}]
|
||||
param01: [3, 4, 4]
|
||||
|
||||
list_merge=replace (default)
|
||||
""""""""""""""""""""""""""""
|
||||
Example :ansopt:`community.general.lists_mergeby#filter:list_merge=replace` (default):
|
||||
|
||||
.. code-block:: yaml+jinja
|
||||
|
||||
list3: "{{ [list1, list2]|
|
||||
list3: "{{ [list1, list2] |
|
||||
community.general.lists_mergeby('name',
|
||||
recursive=true) }}"
|
||||
|
||||
@@ -123,25 +131,22 @@ This produces:
|
||||
.. code-block:: yaml
|
||||
|
||||
list3:
|
||||
- name: myname01
|
||||
param01:
|
||||
list:
|
||||
- patch_value
|
||||
x: default_value
|
||||
y: patch_value
|
||||
z: patch_value
|
||||
- name: myname02
|
||||
param01:
|
||||
- 3
|
||||
- 4
|
||||
- 4
|
||||
- key: value
|
||||
- name: myname01
|
||||
param01:
|
||||
x: default_value
|
||||
y: patch_value
|
||||
list: [patch_value]
|
||||
z: patch_value
|
||||
- name: myname02
|
||||
param01: [3, 4, 4]
|
||||
|
||||
list_merge=keep
|
||||
"""""""""""""""
|
||||
Example :ansopt:`community.general.lists_mergeby#filter:list_merge=keep`:
|
||||
|
||||
.. code-block:: yaml+jinja
|
||||
|
||||
list3: "{{ [list1, list2]|
|
||||
list3: "{{ [list1, list2] |
|
||||
community.general.lists_mergeby('name',
|
||||
recursive=true,
|
||||
list_merge='keep') }}"
|
||||
@@ -151,25 +156,22 @@ This produces:
|
||||
.. code-block:: yaml
|
||||
|
||||
list3:
|
||||
- name: myname01
|
||||
param01:
|
||||
list:
|
||||
- default_value
|
||||
x: default_value
|
||||
y: patch_value
|
||||
z: patch_value
|
||||
- name: myname02
|
||||
param01:
|
||||
- 1
|
||||
- 1
|
||||
- 2
|
||||
- 3
|
||||
- name: myname01
|
||||
param01:
|
||||
x: default_value
|
||||
y: patch_value
|
||||
list: [default_value]
|
||||
z: patch_value
|
||||
- name: myname02
|
||||
param01: [1, 1, 2, 3]
|
||||
|
||||
list_merge=append
|
||||
"""""""""""""""""
|
||||
Example :ansopt:`community.general.lists_mergeby#filter:list_merge=append`:
|
||||
|
||||
.. code-block:: yaml+jinja
|
||||
|
||||
list3: "{{ [list1, list2]|
|
||||
list3: "{{ [list1, list2] |
|
||||
community.general.lists_mergeby('name',
|
||||
recursive=true,
|
||||
list_merge='append') }}"
|
||||
@@ -179,30 +181,22 @@ This produces:
|
||||
.. code-block:: yaml
|
||||
|
||||
list3:
|
||||
- name: myname01
|
||||
param01:
|
||||
list:
|
||||
- default_value
|
||||
- patch_value
|
||||
x: default_value
|
||||
y: patch_value
|
||||
z: patch_value
|
||||
- name: myname02
|
||||
param01:
|
||||
- 1
|
||||
- 1
|
||||
- 2
|
||||
- 3
|
||||
- 3
|
||||
- 4
|
||||
- 4
|
||||
- key: value
|
||||
- name: myname01
|
||||
param01:
|
||||
x: default_value
|
||||
y: patch_value
|
||||
list: [default_value, patch_value]
|
||||
z: patch_value
|
||||
- name: myname02
|
||||
param01: [1, 1, 2, 3, 3, 4, 4]
|
||||
|
||||
list_merge=prepend
|
||||
""""""""""""""""""
|
||||
Example :ansopt:`community.general.lists_mergeby#filter:list_merge=prepend`:
|
||||
|
||||
.. code-block:: yaml+jinja
|
||||
|
||||
list3: "{{ [list1, list2]|
|
||||
list3: "{{ [list1, list2] |
|
||||
community.general.lists_mergeby('name',
|
||||
recursive=true,
|
||||
list_merge='prepend') }}"
|
||||
@@ -212,30 +206,22 @@ This produces:
|
||||
.. code-block:: yaml
|
||||
|
||||
list3:
|
||||
- name: myname01
|
||||
param01:
|
||||
list:
|
||||
- patch_value
|
||||
- default_value
|
||||
x: default_value
|
||||
y: patch_value
|
||||
z: patch_value
|
||||
- name: myname02
|
||||
param01:
|
||||
- 3
|
||||
- 4
|
||||
- 4
|
||||
- key: value
|
||||
- 1
|
||||
- 1
|
||||
- 2
|
||||
- 3
|
||||
- name: myname01
|
||||
param01:
|
||||
x: default_value
|
||||
y: patch_value
|
||||
list: [patch_value, default_value]
|
||||
z: patch_value
|
||||
- name: myname02
|
||||
param01: [3, 4, 4, 1, 1, 2, 3]
|
||||
|
||||
list_merge=append_rp
|
||||
""""""""""""""""""""
|
||||
Example :ansopt:`community.general.lists_mergeby#filter:list_merge=append_rp`:
|
||||
|
||||
.. code-block:: yaml+jinja
|
||||
|
||||
list3: "{{ [list1, list2]|
|
||||
list3: "{{ [list1, list2] |
|
||||
community.general.lists_mergeby('name',
|
||||
recursive=true,
|
||||
list_merge='append_rp') }}"
|
||||
@@ -245,29 +231,22 @@ This produces:
|
||||
.. code-block:: yaml
|
||||
|
||||
list3:
|
||||
- name: myname01
|
||||
param01:
|
||||
list:
|
||||
- default_value
|
||||
- patch_value
|
||||
x: default_value
|
||||
y: patch_value
|
||||
z: patch_value
|
||||
- name: myname02
|
||||
param01:
|
||||
- 1
|
||||
- 1
|
||||
- 2
|
||||
- 3
|
||||
- 4
|
||||
- 4
|
||||
- key: value
|
||||
- name: myname01
|
||||
param01:
|
||||
x: default_value
|
||||
y: patch_value
|
||||
list: [default_value, patch_value]
|
||||
z: patch_value
|
||||
- name: myname02
|
||||
param01: [1, 1, 2, 3, 4, 4]
|
||||
|
||||
list_merge=prepend_rp
|
||||
"""""""""""""""""""""
|
||||
Example :ansopt:`community.general.lists_mergeby#filter:list_merge=prepend_rp`:
|
||||
|
||||
.. code-block:: yaml+jinja
|
||||
|
||||
list3: "{{ [list1, list2]|
|
||||
list3: "{{ [list1, list2] |
|
||||
community.general.lists_mergeby('name',
|
||||
recursive=true,
|
||||
list_merge='prepend_rp') }}"
|
||||
@@ -277,21 +256,12 @@ This produces:
|
||||
.. code-block:: yaml
|
||||
|
||||
list3:
|
||||
- name: myname01
|
||||
param01:
|
||||
list:
|
||||
- patch_value
|
||||
- default_value
|
||||
x: default_value
|
||||
y: patch_value
|
||||
z: patch_value
|
||||
- name: myname02
|
||||
param01:
|
||||
- 3
|
||||
- 4
|
||||
- 4
|
||||
- key: value
|
||||
- 1
|
||||
- 1
|
||||
- 2
|
||||
- name: myname01
|
||||
param01:
|
||||
x: default_value
|
||||
y: patch_value
|
||||
list: [patch_value, default_value]
|
||||
z: patch_value
|
||||
- name: myname02
|
||||
param01: [3, 4, 4, 1, 1, 2]
|
||||
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
|
||||
namespace: community
|
||||
name: general
|
||||
version: 8.6.1
|
||||
version: 8.6.2
|
||||
readme: README.md
|
||||
authors:
|
||||
- Ansible (https://github.com/ansible)
|
||||
|
||||
@@ -498,11 +498,19 @@ class CallbackModule(CallbackBase):
|
||||
# See https://github.com/open-telemetry/opentelemetry-specification/issues/740
|
||||
self.traceparent = self.get_option('traceparent')
|
||||
|
||||
def dump_results(self, result):
|
||||
def dump_results(self, task, result):
|
||||
""" dump the results if disable_logs is not enabled """
|
||||
if self.disable_logs:
|
||||
return ""
|
||||
return self._dump_results(result._result)
|
||||
# ansible.builtin.uri contains the response in the json field
|
||||
save = dict(result._result)
|
||||
|
||||
if "json" in save and task.action in ("ansible.builtin.uri", "ansible.legacy.uri", "uri"):
|
||||
save.pop("json")
|
||||
# ansible.builtin.slurp contains the response in the content field
|
||||
if "content" in save and task.action in ("ansible.builtin.slurp", "ansible.legacy.slurp", "slurp"):
|
||||
save.pop("content")
|
||||
return self._dump_results(save)
|
||||
|
||||
def v2_playbook_on_start(self, playbook):
|
||||
self.ansible_playbook = basename(playbook._file_name)
|
||||
@@ -553,7 +561,7 @@ class CallbackModule(CallbackBase):
|
||||
self.tasks_data,
|
||||
status,
|
||||
result,
|
||||
self.dump_results(result)
|
||||
self.dump_results(self.tasks_data[result._task._uuid], result)
|
||||
)
|
||||
|
||||
def v2_runner_on_ok(self, result):
|
||||
@@ -561,7 +569,7 @@ class CallbackModule(CallbackBase):
|
||||
self.tasks_data,
|
||||
'ok',
|
||||
result,
|
||||
self.dump_results(result)
|
||||
self.dump_results(self.tasks_data[result._task._uuid], result)
|
||||
)
|
||||
|
||||
def v2_runner_on_skipped(self, result):
|
||||
@@ -569,7 +577,7 @@ class CallbackModule(CallbackBase):
|
||||
self.tasks_data,
|
||||
'skipped',
|
||||
result,
|
||||
self.dump_results(result)
|
||||
self.dump_results(self.tasks_data[result._task._uuid], result)
|
||||
)
|
||||
|
||||
def v2_playbook_on_include(self, included_file):
|
||||
|
||||
@@ -19,6 +19,16 @@ DOCUMENTATION = '''
|
||||
- default_callback
|
||||
requirements:
|
||||
- set as stdout in configuration
|
||||
seealso:
|
||||
- plugin: ansible.builtin.default
|
||||
plugin_type: callback
|
||||
description: >
|
||||
There is a parameter O(ansible.builtin.default#callback:result_format) in P(ansible.builtin.default#callback)
|
||||
that allows you to change the output format to YAML.
|
||||
notes:
|
||||
- >
|
||||
With ansible-core 2.13 or newer, you can instead specify V(yaml) for the parameter O(ansible.builtin.default#callback:result_format)
|
||||
in P(ansible.builtin.default#callback).
|
||||
'''
|
||||
|
||||
import yaml
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# Copyright (c) 2020-2022, Vladimir Botka <vbotka@gmail.com>
|
||||
# Copyright (c) 2020-2024, Vladimir Botka <vbotka@gmail.com>
|
||||
# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
|
||||
# SPDX-License-Identifier: GPL-3.0-or-later
|
||||
|
||||
@@ -12,22 +12,32 @@ DOCUMENTATION = '''
|
||||
version_added: 2.0.0
|
||||
author: Vladimir Botka (@vbotka)
|
||||
description:
|
||||
- Merge two or more lists by attribute O(index). Optional parameters O(recursive) and O(list_merge)
|
||||
control the merging of the lists in values. The function merge_hash from ansible.utils.vars
|
||||
is used. To learn details on how to use the parameters O(recursive) and O(list_merge) see
|
||||
Ansible User's Guide chapter "Using filters to manipulate data" section "Combining
|
||||
hashes/dictionaries".
|
||||
- Merge two or more lists by attribute O(index). Optional
|
||||
parameters O(recursive) and O(list_merge) control the merging of
|
||||
the nested dictionaries and lists.
|
||||
- The function C(merge_hash) from C(ansible.utils.vars) is used.
|
||||
- To learn details on how to use the parameters O(recursive) and
|
||||
O(list_merge) see Ansible User's Guide chapter "Using filters to
|
||||
manipulate data" section R(Combining hashes/dictionaries, combine_filter) or the
|
||||
filter P(ansible.builtin.combine#filter).
|
||||
|
||||
positional: another_list, index
|
||||
options:
|
||||
_input:
|
||||
description: A list of dictionaries.
|
||||
description:
|
||||
- A list of dictionaries, or a list of lists of dictionaries.
|
||||
- The required type of the C(elements) is set to C(raw)
|
||||
because all elements of O(_input) can be either dictionaries
|
||||
or lists.
|
||||
type: list
|
||||
elements: dictionary
|
||||
elements: raw
|
||||
required: true
|
||||
another_list:
|
||||
description: Another list of dictionaries. This parameter can be specified multiple times.
|
||||
description:
|
||||
- Another list of dictionaries, or a list of lists of dictionaries.
|
||||
- This parameter can be specified multiple times.
|
||||
type: list
|
||||
elements: dictionary
|
||||
elements: raw
|
||||
index:
|
||||
description:
|
||||
- The dictionary key that must be present in every dictionary in every list that is used to
|
||||
@@ -55,40 +65,134 @@ DOCUMENTATION = '''
|
||||
'''
|
||||
|
||||
EXAMPLES = '''
|
||||
- name: Merge two lists
|
||||
# Some results below are manually formatted for better readability. The
|
||||
# dictionaries' keys will be sorted alphabetically in real output.
|
||||
|
||||
- name: Example 1. Merge two lists. The results r1 and r2 are the same.
|
||||
ansible.builtin.debug:
|
||||
msg: >-
|
||||
{{ list1 | community.general.lists_mergeby(
|
||||
list2,
|
||||
'index',
|
||||
recursive=True,
|
||||
list_merge='append'
|
||||
) }}"
|
||||
msg: |
|
||||
r1: {{ r1 }}
|
||||
r2: {{ r2 }}
|
||||
vars:
|
||||
list1:
|
||||
- index: a
|
||||
value: 123
|
||||
- index: b
|
||||
value: 42
|
||||
- {index: a, value: 123}
|
||||
- {index: b, value: 4}
|
||||
list2:
|
||||
- index: a
|
||||
foo: bar
|
||||
- index: c
|
||||
foo: baz
|
||||
# Produces the following list of dictionaries:
|
||||
# {
|
||||
# "index": "a",
|
||||
# "foo": "bar",
|
||||
# "value": 123
|
||||
# },
|
||||
# {
|
||||
# "index": "b",
|
||||
# "value": 42
|
||||
# },
|
||||
# {
|
||||
# "index": "c",
|
||||
# "foo": "baz"
|
||||
# }
|
||||
- {index: a, foo: bar}
|
||||
- {index: c, foo: baz}
|
||||
r1: "{{ list1 | community.general.lists_mergeby(list2, 'index') }}"
|
||||
r2: "{{ [list1, list2] | community.general.lists_mergeby('index') }}"
|
||||
|
||||
# r1:
|
||||
# - {index: a, foo: bar, value: 123}
|
||||
# - {index: b, value: 4}
|
||||
# - {index: c, foo: baz}
|
||||
# r2:
|
||||
# - {index: a, foo: bar, value: 123}
|
||||
# - {index: b, value: 4}
|
||||
# - {index: c, foo: baz}
|
||||
|
||||
- name: Example 2. Merge three lists
|
||||
ansible.builtin.debug:
|
||||
var: r
|
||||
vars:
|
||||
list1:
|
||||
- {index: a, value: 123}
|
||||
- {index: b, value: 4}
|
||||
list2:
|
||||
- {index: a, foo: bar}
|
||||
- {index: c, foo: baz}
|
||||
list3:
|
||||
- {index: d, foo: qux}
|
||||
r: "{{ [list1, list2, list3] | community.general.lists_mergeby('index') }}"
|
||||
|
||||
# r:
|
||||
# - {index: a, foo: bar, value: 123}
|
||||
# - {index: b, value: 4}
|
||||
# - {index: c, foo: baz}
|
||||
# - {index: d, foo: qux}
|
||||
|
||||
- name: Example 3. Merge single list. The result is the same as 2.
|
||||
ansible.builtin.debug:
|
||||
var: r
|
||||
vars:
|
||||
list1:
|
||||
- {index: a, value: 123}
|
||||
- {index: b, value: 4}
|
||||
- {index: a, foo: bar}
|
||||
- {index: c, foo: baz}
|
||||
- {index: d, foo: qux}
|
||||
r: "{{ [list1, []] | community.general.lists_mergeby('index') }}"
|
||||
|
||||
# r:
|
||||
# - {index: a, foo: bar, value: 123}
|
||||
# - {index: b, value: 4}
|
||||
# - {index: c, foo: baz}
|
||||
# - {index: d, foo: qux}
|
||||
|
||||
- name: Example 4. Merge two lists. By default, replace nested lists.
|
||||
ansible.builtin.debug:
|
||||
var: r
|
||||
vars:
|
||||
list1:
|
||||
- {index: a, foo: [X1, X2]}
|
||||
- {index: b, foo: [X1, X2]}
|
||||
list2:
|
||||
- {index: a, foo: [Y1, Y2]}
|
||||
- {index: b, foo: [Y1, Y2]}
|
||||
r: "{{ [list1, list2] | community.general.lists_mergeby('index') }}"
|
||||
|
||||
# r:
|
||||
# - {index: a, foo: [Y1, Y2]}
|
||||
# - {index: b, foo: [Y1, Y2]}
|
||||
|
||||
- name: Example 5. Merge two lists. Append nested lists.
|
||||
ansible.builtin.debug:
|
||||
var: r
|
||||
vars:
|
||||
list1:
|
||||
- {index: a, foo: [X1, X2]}
|
||||
- {index: b, foo: [X1, X2]}
|
||||
list2:
|
||||
- {index: a, foo: [Y1, Y2]}
|
||||
- {index: b, foo: [Y1, Y2]}
|
||||
r: "{{ [list1, list2] | community.general.lists_mergeby('index', list_merge='append') }}"
|
||||
|
||||
# r:
|
||||
# - {index: a, foo: [X1, X2, Y1, Y2]}
|
||||
# - {index: b, foo: [X1, X2, Y1, Y2]}
|
||||
|
||||
- name: Example 6. Merge two lists. By default, do not merge nested dictionaries.
|
||||
ansible.builtin.debug:
|
||||
var: r
|
||||
vars:
|
||||
list1:
|
||||
- {index: a, foo: {x: 1, y: 2}}
|
||||
- {index: b, foo: [X1, X2]}
|
||||
list2:
|
||||
- {index: a, foo: {y: 3, z: 4}}
|
||||
- {index: b, foo: [Y1, Y2]}
|
||||
r: "{{ [list1, list2] | community.general.lists_mergeby('index') }}"
|
||||
|
||||
# r:
|
||||
# - {index: a, foo: {y: 3, z: 4}}
|
||||
# - {index: b, foo: [Y1, Y2]}
|
||||
|
||||
- name: Example 7. Merge two lists. Merge nested dictionaries too.
|
||||
ansible.builtin.debug:
|
||||
var: r
|
||||
vars:
|
||||
list1:
|
||||
- {index: a, foo: {x: 1, y: 2}}
|
||||
- {index: b, foo: [X1, X2]}
|
||||
list2:
|
||||
- {index: a, foo: {y: 3, z: 4}}
|
||||
- {index: b, foo: [Y1, Y2]}
|
||||
r: "{{ [list1, list2] | community.general.lists_mergeby('index', recursive=true) }}"
|
||||
|
||||
# r:
|
||||
# - {index: a, foo: {x:1, y: 3, z: 4}}
|
||||
# - {index: b, foo: [Y1, Y2]}
|
||||
'''
|
||||
|
||||
RETURN = '''
|
||||
@@ -108,13 +212,14 @@ from operator import itemgetter
|
||||
|
||||
|
||||
def list_mergeby(x, y, index, recursive=False, list_merge='replace'):
|
||||
''' Merge 2 lists by attribute 'index'. The function merge_hash from ansible.utils.vars is used.
|
||||
This function is used by the function lists_mergeby.
|
||||
'''Merge 2 lists by attribute 'index'. The function 'merge_hash'
|
||||
from ansible.utils.vars is used. This function is used by the
|
||||
function lists_mergeby.
|
||||
'''
|
||||
|
||||
d = defaultdict(dict)
|
||||
for l in (x, y):
|
||||
for elem in l:
|
||||
for lst in (x, y):
|
||||
for elem in lst:
|
||||
if not isinstance(elem, Mapping):
|
||||
msg = "Elements of list arguments for lists_mergeby must be dictionaries. %s is %s"
|
||||
raise AnsibleFilterError(msg % (elem, type(elem)))
|
||||
@@ -124,20 +229,9 @@ def list_mergeby(x, y, index, recursive=False, list_merge='replace'):
|
||||
|
||||
|
||||
def lists_mergeby(*terms, **kwargs):
|
||||
''' Merge 2 or more lists by attribute 'index'. Optional parameters 'recursive' and 'list_merge'
|
||||
control the merging of the lists in values. The function merge_hash from ansible.utils.vars
|
||||
is used. To learn details on how to use the parameters 'recursive' and 'list_merge' see
|
||||
Ansible User's Guide chapter "Using filters to manipulate data" section "Combining
|
||||
hashes/dictionaries".
|
||||
|
||||
Example:
|
||||
- debug:
|
||||
msg: "{{ list1|
|
||||
community.general.lists_mergeby(list2,
|
||||
'index',
|
||||
recursive=True,
|
||||
list_merge='append')|
|
||||
list }}"
|
||||
'''Merge 2 or more lists by attribute 'index'. To learn details
|
||||
on how to use the parameters 'recursive' and 'list_merge' see
|
||||
the filter ansible.builtin.combine.
|
||||
'''
|
||||
|
||||
recursive = kwargs.pop('recursive', False)
|
||||
@@ -155,7 +249,7 @@ def lists_mergeby(*terms, **kwargs):
|
||||
"must be lists. %s is %s")
|
||||
raise AnsibleFilterError(msg % (sublist, type(sublist)))
|
||||
if len(sublist) > 0:
|
||||
if all(isinstance(l, Sequence) for l in sublist):
|
||||
if all(isinstance(lst, Sequence) for lst in sublist):
|
||||
for item in sublist:
|
||||
flat_list.append(item)
|
||||
else:
|
||||
|
||||
@@ -143,7 +143,8 @@ class InventoryModule(BaseInventoryPlugin, Constructable):
|
||||
nic = [nic]
|
||||
|
||||
for net in nic:
|
||||
return net['IP']
|
||||
if net.get('IP'):
|
||||
return net['IP']
|
||||
|
||||
return False
|
||||
|
||||
|
||||
@@ -263,7 +263,7 @@ def main():
|
||||
module.exit_json(changed=False, msg='', config_value=old_values[0] if old_values else '')
|
||||
elif unset and not out:
|
||||
module.exit_json(changed=False, msg='no setting to unset')
|
||||
elif new_value in old_values and (len(old_values) == 1 or add_mode == "add"):
|
||||
elif new_value in old_values and (len(old_values) == 1 or add_mode == "add") and not unset:
|
||||
module.exit_json(changed=False, msg="")
|
||||
|
||||
# Until this point, the git config was just read and in case no change is needed, the module has already exited.
|
||||
|
||||
@@ -488,9 +488,9 @@ class Homebrew(object):
|
||||
self.current_package,
|
||||
]
|
||||
rc, out, err = self.module.run_command(cmd)
|
||||
if err:
|
||||
if rc != 0:
|
||||
self.failed = True
|
||||
self.message = err.strip()
|
||||
self.message = err.strip() or ("Unknown failure with exit code %d" % rc)
|
||||
raise HomebrewException(self.message)
|
||||
data = json.loads(out)
|
||||
|
||||
|
||||
@@ -17,6 +17,12 @@ short_description: Manage user accounts with systemd-homed
|
||||
version_added: 4.4.0
|
||||
description:
|
||||
- Manages a user's home directory managed by systemd-homed.
|
||||
notes:
|
||||
- This module does B(not) work with Python 3.13 or newer. It uses the deprecated L(crypt Python module,
|
||||
https://docs.python.org/3.12/library/crypt.html) from the Python standard library, which was removed
|
||||
from Python 3.13.
|
||||
requirements:
|
||||
- Python 3.12 or earlier
|
||||
extends_documentation_fragment:
|
||||
- community.general.attributes
|
||||
attributes:
|
||||
@@ -263,12 +269,21 @@ data:
|
||||
}
|
||||
'''
|
||||
|
||||
import crypt
|
||||
import json
|
||||
from ansible.module_utils.basic import AnsibleModule
|
||||
import traceback
|
||||
from ansible.module_utils.basic import AnsibleModule, missing_required_lib
|
||||
from ansible.module_utils.basic import jsonify
|
||||
from ansible.module_utils.common.text.formatters import human_to_bytes
|
||||
|
||||
try:
|
||||
import crypt
|
||||
except ImportError:
|
||||
HAS_CRYPT = False
|
||||
CRYPT_IMPORT_ERROR = traceback.format_exc()
|
||||
else:
|
||||
HAS_CRYPT = True
|
||||
CRYPT_IMPORT_ERROR = None
|
||||
|
||||
|
||||
class Homectl(object):
|
||||
'''#TODO DOC STRINGS'''
|
||||
@@ -591,6 +606,12 @@ def main():
|
||||
]
|
||||
)
|
||||
|
||||
if not HAS_CRYPT:
|
||||
module.fail_json(
|
||||
msg=missing_required_lib('crypt (part of Python 3.13 standard library)'),
|
||||
exception=CRYPT_IMPORT_ERROR,
|
||||
)
|
||||
|
||||
homectl = Homectl(module)
|
||||
homectl.result['state'] = homectl.state
|
||||
|
||||
|
||||
@@ -775,8 +775,9 @@ def sanitize_cr(clientrep):
|
||||
if 'secret' in result:
|
||||
result['secret'] = 'no_log'
|
||||
if 'attributes' in result:
|
||||
if 'saml.signing.private.key' in result['attributes']:
|
||||
result['attributes']['saml.signing.private.key'] = 'no_log'
|
||||
attributes = result['attributes']
|
||||
if isinstance(attributes, dict) and 'saml.signing.private.key' in attributes:
|
||||
attributes['saml.signing.private.key'] = 'no_log'
|
||||
return normalise_cr(result)
|
||||
|
||||
|
||||
|
||||
@@ -301,10 +301,37 @@ end_state:
|
||||
'''
|
||||
|
||||
from ansible_collections.community.general.plugins.module_utils.identity.keycloak.keycloak import KeycloakAPI, camel, \
|
||||
keycloak_argument_spec, get_token, KeycloakError
|
||||
keycloak_argument_spec, get_token, KeycloakError, is_struct_included
|
||||
from ansible.module_utils.basic import AnsibleModule
|
||||
|
||||
|
||||
def normalise_cr(clientscoperep, remove_ids=False):
|
||||
""" Re-sorts any properties where the order so that diff's is minimised, and adds default values where appropriate so that the
|
||||
the change detection is more effective.
|
||||
|
||||
:param clientscoperep: the clientscoperep dict to be sanitized
|
||||
:param remove_ids: If set to true, then the unique ID's of objects is removed to make the diff and checks for changed
|
||||
not alert when the ID's of objects are not usually known, (e.g. for protocol_mappers)
|
||||
:return: normalised clientscoperep dict
|
||||
"""
|
||||
# Avoid the dict passed in to be modified
|
||||
clientscoperep = clientscoperep.copy()
|
||||
|
||||
if 'attributes' in clientscoperep:
|
||||
clientscoperep['attributes'] = list(sorted(clientscoperep['attributes']))
|
||||
|
||||
if 'protocolMappers' in clientscoperep:
|
||||
clientscoperep['protocolMappers'] = sorted(clientscoperep['protocolMappers'], key=lambda x: (x.get('name'), x.get('protocol'), x.get('protocolMapper')))
|
||||
for mapper in clientscoperep['protocolMappers']:
|
||||
if remove_ids:
|
||||
mapper.pop('id', None)
|
||||
|
||||
# Set to a default value.
|
||||
mapper['consentRequired'] = mapper.get('consentRequired', False)
|
||||
|
||||
return clientscoperep
|
||||
|
||||
|
||||
def sanitize_cr(clientscoperep):
|
||||
""" Removes probably sensitive details from a clientscoperep representation.
|
||||
|
||||
@@ -317,7 +344,7 @@ def sanitize_cr(clientscoperep):
|
||||
if 'attributes' in result:
|
||||
if 'saml.signing.private.key' in result['attributes']:
|
||||
result['attributes']['saml.signing.private.key'] = 'no_log'
|
||||
return result
|
||||
return normalise_cr(result)
|
||||
|
||||
|
||||
def main():
|
||||
@@ -458,6 +485,13 @@ def main():
|
||||
result['diff'] = dict(before=sanitize_cr(before_clientscope), after=sanitize_cr(desired_clientscope))
|
||||
|
||||
if module.check_mode:
|
||||
# We can only compare the current clientscope with the proposed updates we have
|
||||
before_norm = normalise_cr(before_clientscope, remove_ids=True)
|
||||
desired_norm = normalise_cr(desired_clientscope, remove_ids=True)
|
||||
if module._diff:
|
||||
result['diff'] = dict(before=sanitize_cr(before_norm),
|
||||
after=sanitize_cr(desired_norm))
|
||||
result['changed'] = not is_struct_included(desired_norm, before_norm)
|
||||
module.exit_json(**result)
|
||||
|
||||
# do the update
|
||||
|
||||
@@ -514,7 +514,8 @@ def main():
|
||||
result['status']['current_pid'] != result['status']['previous_pid']):
|
||||
result['changed'] = True
|
||||
if module.check_mode:
|
||||
result['changed'] = True
|
||||
if result['status']['current_state'] != action:
|
||||
result['changed'] = True
|
||||
module.exit_json(**result)
|
||||
|
||||
|
||||
|
||||
@@ -400,7 +400,7 @@ EXAMPLES = '''
|
||||
protocol: simplestreams
|
||||
type: image
|
||||
mode: pull
|
||||
server: https://images.linuxcontainers.org
|
||||
server: [...] # URL to the image server
|
||||
alias: debian/11
|
||||
timeout: 600
|
||||
'''
|
||||
|
||||
@@ -367,8 +367,9 @@ class Pacman(object):
|
||||
self.install_packages(pkgs)
|
||||
self.success()
|
||||
|
||||
# This shouldn't happen...
|
||||
self.fail("This is a bug")
|
||||
# This happens if an empty list has been provided for name
|
||||
self.add_exit_infos(msg='Nothing to do')
|
||||
self.success()
|
||||
|
||||
def install_packages(self, pkgs):
|
||||
pkgs_to_install = []
|
||||
|
||||
@@ -172,6 +172,7 @@ options:
|
||||
- Allow to force stop VM.
|
||||
- Can be used with states V(stopped), V(restarted), and V(absent).
|
||||
- This option has no default unless O(proxmox_default_behavior) is set to V(compatibility); then the default is V(false).
|
||||
- Requires parameter O(archive).
|
||||
type: bool
|
||||
format:
|
||||
description:
|
||||
|
||||
@@ -20,6 +20,12 @@ description:
|
||||
- "This module allows to manage posix users on a univention corporate
|
||||
server (UCS).
|
||||
It uses the python API of the UCS to create a new object or edit it."
|
||||
notes:
|
||||
- This module does B(not) work with Python 3.13 or newer. It uses the deprecated L(crypt Python module,
|
||||
https://docs.python.org/3.12/library/crypt.html) from the Python standard library, which was removed
|
||||
from Python 3.13.
|
||||
requirements:
|
||||
- Python 3.12 or earlier
|
||||
extends_documentation_fragment:
|
||||
- community.general.attributes
|
||||
attributes:
|
||||
@@ -324,10 +330,10 @@ EXAMPLES = '''
|
||||
|
||||
RETURN = '''# '''
|
||||
|
||||
import crypt
|
||||
from datetime import date, timedelta
|
||||
import traceback
|
||||
|
||||
from ansible.module_utils.basic import AnsibleModule
|
||||
from ansible.module_utils.basic import AnsibleModule, missing_required_lib
|
||||
from ansible_collections.community.general.plugins.module_utils.univention_umc import (
|
||||
umc_module_for_add,
|
||||
umc_module_for_edit,
|
||||
@@ -335,6 +341,15 @@ from ansible_collections.community.general.plugins.module_utils.univention_umc i
|
||||
base_dn,
|
||||
)
|
||||
|
||||
try:
|
||||
import crypt
|
||||
except ImportError:
|
||||
HAS_CRYPT = False
|
||||
CRYPT_IMPORT_ERROR = traceback.format_exc()
|
||||
else:
|
||||
HAS_CRYPT = True
|
||||
CRYPT_IMPORT_ERROR = None
|
||||
|
||||
|
||||
def main():
|
||||
expiry = date.strftime(date.today() + timedelta(days=365), "%Y-%m-%d")
|
||||
@@ -451,6 +466,13 @@ def main():
|
||||
('state', 'present', ['firstname', 'lastname', 'password'])
|
||||
])
|
||||
)
|
||||
|
||||
if not HAS_CRYPT:
|
||||
module.fail_json(
|
||||
msg=missing_required_lib('crypt (part of Python 3.13 standard library)'),
|
||||
exception=CRYPT_IMPORT_ERROR,
|
||||
)
|
||||
|
||||
username = module.params['username']
|
||||
position = module.params['position']
|
||||
ou = module.params['ou']
|
||||
|
||||
@@ -18,6 +18,30 @@
|
||||
scope: "{{ option_scope }}"
|
||||
register: get_result
|
||||
|
||||
- name: assert unset changed and deleted value
|
||||
assert:
|
||||
that:
|
||||
- unset_result is changed
|
||||
- unset_result.diff.before == option_value + "\n"
|
||||
- unset_result.diff.after == "\n"
|
||||
- get_result.config_value == ''
|
||||
|
||||
- import_tasks: setup_value.yml
|
||||
|
||||
- name: unsetting value with value specified
|
||||
git_config:
|
||||
name: "{{ option_name }}"
|
||||
scope: "{{ option_scope }}"
|
||||
value: "{{ option_value }}"
|
||||
state: absent
|
||||
register: unset_result
|
||||
|
||||
- name: getting value
|
||||
git_config:
|
||||
name: "{{ option_name }}"
|
||||
scope: "{{ option_scope }}"
|
||||
register: get_result
|
||||
|
||||
- name: assert unset changed and deleted value
|
||||
assert:
|
||||
that:
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
.azure-pipelines/scripts/publish-codecov.py replace-urlopen
|
||||
plugins/callback/yaml.py validate-modules:invalid-documentation
|
||||
plugins/lookup/etcd.py validate-modules:invalid-documentation
|
||||
plugins/lookup/etcd3.py validate-modules:invalid-documentation
|
||||
plugins/modules/consul_session.py validate-modules:parameter-state-invalid-choice
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
.azure-pipelines/scripts/publish-codecov.py replace-urlopen
|
||||
plugins/callback/yaml.py validate-modules:invalid-documentation
|
||||
plugins/lookup/etcd.py validate-modules:invalid-documentation
|
||||
plugins/lookup/etcd3.py validate-modules:invalid-documentation
|
||||
plugins/modules/consul_session.py validate-modules:parameter-state-invalid-choice
|
||||
|
||||
Reference in New Issue
Block a user