summaryrefslogtreecommitdiffstats
path: root/ansible_collections/community/general/docs
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-13 12:04:41 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-13 12:04:41 +0000
commit975f66f2eebe9dadba04f275774d4ab83f74cf25 (patch)
tree89bd26a93aaae6a25749145b7e4bca4a1e75b2be /ansible_collections/community/general/docs
parentInitial commit. (diff)
downloadansible-975f66f2eebe9dadba04f275774d4ab83f74cf25.tar.xz
ansible-975f66f2eebe9dadba04f275774d4ab83f74cf25.zip
Adding upstream version 7.7.0+dfsg.upstream/7.7.0+dfsg
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'ansible_collections/community/general/docs')
-rw-r--r--ansible_collections/community/general/docs/docsite/extra-docs.yml10
-rw-r--r--ansible_collections/community/general/docs/docsite/helper/lists_mergeby/default-common.yml18
-rw-r--r--ansible_collections/community/general/docs/docsite/helper/lists_mergeby/default-recursive-true.yml24
-rw-r--r--ansible_collections/community/general/docs/docsite/helper/lists_mergeby/example-001.yml14
-rw-r--r--ansible_collections/community/general/docs/docsite/helper/lists_mergeby/example-001_vars/default-common.yml18
-rw-r--r--ansible_collections/community/general/docs/docsite/helper/lists_mergeby/example-001_vars/list3.yml7
-rw-r--r--ansible_collections/community/general/docs/docsite/helper/lists_mergeby/example-002.yml14
-rw-r--r--ansible_collections/community/general/docs/docsite/helper/lists_mergeby/example-002_vars/default-common.yml18
-rw-r--r--ansible_collections/community/general/docs/docsite/helper/lists_mergeby/example-002_vars/list3.yml7
-rw-r--r--ansible_collections/community/general/docs/docsite/helper/lists_mergeby/example-003.yml14
-rw-r--r--ansible_collections/community/general/docs/docsite/helper/lists_mergeby/example-003_vars/default-recursive-true.yml24
-rw-r--r--ansible_collections/community/general/docs/docsite/helper/lists_mergeby/example-003_vars/list3.yml8
-rw-r--r--ansible_collections/community/general/docs/docsite/helper/lists_mergeby/example-004.yml14
-rw-r--r--ansible_collections/community/general/docs/docsite/helper/lists_mergeby/example-004_vars/default-recursive-true.yml24
-rw-r--r--ansible_collections/community/general/docs/docsite/helper/lists_mergeby/example-004_vars/list3.yml9
-rw-r--r--ansible_collections/community/general/docs/docsite/helper/lists_mergeby/example-005.yml14
-rw-r--r--ansible_collections/community/general/docs/docsite/helper/lists_mergeby/example-005_vars/default-recursive-true.yml24
-rw-r--r--ansible_collections/community/general/docs/docsite/helper/lists_mergeby/example-005_vars/list3.yml9
-rw-r--r--ansible_collections/community/general/docs/docsite/helper/lists_mergeby/example-006.yml14
-rw-r--r--ansible_collections/community/general/docs/docsite/helper/lists_mergeby/example-006_vars/default-recursive-true.yml24
-rw-r--r--ansible_collections/community/general/docs/docsite/helper/lists_mergeby/example-006_vars/list3.yml9
-rw-r--r--ansible_collections/community/general/docs/docsite/helper/lists_mergeby/example-007.yml14
-rw-r--r--ansible_collections/community/general/docs/docsite/helper/lists_mergeby/example-007_vars/default-recursive-true.yml24
-rw-r--r--ansible_collections/community/general/docs/docsite/helper/lists_mergeby/example-007_vars/list3.yml9
-rw-r--r--ansible_collections/community/general/docs/docsite/helper/lists_mergeby/example-008.yml14
-rw-r--r--ansible_collections/community/general/docs/docsite/helper/lists_mergeby/example-008_vars/default-recursive-true.yml24
-rw-r--r--ansible_collections/community/general/docs/docsite/helper/lists_mergeby/example-008_vars/list3.yml9
-rw-r--r--ansible_collections/community/general/docs/docsite/helper/lists_mergeby/examples.yml54
-rw-r--r--ansible_collections/community/general/docs/docsite/helper/lists_mergeby/examples_all.rst.j213
-rw-r--r--ansible_collections/community/general/docs/docsite/helper/lists_mergeby/filter_guide_abstract_informations_merging_lists_of_dictionaries.rst.j262
-rw-r--r--ansible_collections/community/general/docs/docsite/helper/lists_mergeby/list3.out.j27
-rw-r--r--ansible_collections/community/general/docs/docsite/helper/lists_mergeby/playbook.yml62
-rw-r--r--ansible_collections/community/general/docs/docsite/links.yml27
-rw-r--r--ansible_collections/community/general/docs/docsite/rst/filter_guide.rst23
-rw-r--r--ansible_collections/community/general/docs/docsite/rst/filter_guide_abstract_informations.rst15
-rw-r--r--ansible_collections/community/general/docs/docsite/rst/filter_guide_abstract_informations_counting_elements_in_sequence.rst82
-rw-r--r--ansible_collections/community/general/docs/docsite/rst/filter_guide_abstract_informations_dictionaries.rst124
-rw-r--r--ansible_collections/community/general/docs/docsite/rst/filter_guide_abstract_informations_grouping.rst103
-rw-r--r--ansible_collections/community/general/docs/docsite/rst/filter_guide_abstract_informations_merging_lists_of_dictionaries.rst297
-rw-r--r--ansible_collections/community/general/docs/docsite/rst/filter_guide_conversions.rst113
-rw-r--r--ansible_collections/community/general/docs/docsite/rst/filter_guide_creating_identifiers.rst85
-rw-r--r--ansible_collections/community/general/docs/docsite/rst/filter_guide_paths.rst19
-rw-r--r--ansible_collections/community/general/docs/docsite/rst/filter_guide_selecting_json_data.rst149
-rw-r--r--ansible_collections/community/general/docs/docsite/rst/filter_guide_working_with_times.rst89
-rw-r--r--ansible_collections/community/general/docs/docsite/rst/filter_guide_working_with_unicode.rst35
-rw-r--r--ansible_collections/community/general/docs/docsite/rst/filter_guide_working_with_versions.rst39
-rw-r--r--ansible_collections/community/general/docs/docsite/rst/test_guide.rst33
47 files changed, 1842 insertions, 0 deletions
diff --git a/ansible_collections/community/general/docs/docsite/extra-docs.yml b/ansible_collections/community/general/docs/docsite/extra-docs.yml
new file mode 100644
index 000000000..2171031ac
--- /dev/null
+++ b/ansible_collections/community/general/docs/docsite/extra-docs.yml
@@ -0,0 +1,10 @@
+---
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+sections:
+ - title: Guides
+ toctree:
+ - filter_guide
+ - test_guide
diff --git a/ansible_collections/community/general/docs/docsite/helper/lists_mergeby/default-common.yml b/ansible_collections/community/general/docs/docsite/helper/lists_mergeby/default-common.yml
new file mode 100644
index 000000000..fd874e5c9
--- /dev/null
+++ b/ansible_collections/community/general/docs/docsite/helper/lists_mergeby/default-common.yml
@@ -0,0 +1,18 @@
+---
+# 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
+
+list2:
+ - name: foo
+ path: /foo
+ - name: baz
+ path: /baz
diff --git a/ansible_collections/community/general/docs/docsite/helper/lists_mergeby/default-recursive-true.yml b/ansible_collections/community/general/docs/docsite/helper/lists_mergeby/default-recursive-true.yml
new file mode 100644
index 000000000..133c8f2ae
--- /dev/null
+++ b/ansible_collections/community/general/docs/docsite/helper/lists_mergeby/default-recursive-true.yml
@@ -0,0 +1,24 @@
+---
+# 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
+ - name: myname02
+ param01: [1, 1, 2, 3]
+
+list2:
+ - name: myname01
+ param01:
+ y: patch_value
+ z: patch_value
+ list:
+ - patch_value
+ - name: myname02
+ param01: [3, 4, 4, {key: value}]
diff --git a/ansible_collections/community/general/docs/docsite/helper/lists_mergeby/example-001.yml b/ansible_collections/community/general/docs/docsite/helper/lists_mergeby/example-001.yml
new file mode 100644
index 000000000..0cf6a9b8a
--- /dev/null
+++ b/ansible_collections/community/general/docs/docsite/helper/lists_mergeby/example-001.yml
@@ -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: 1. Merge two lists by common attribute 'name'
+ include_vars:
+ dir: example-001_vars
+- debug:
+ var: list3
+ when: debug|d(false)|bool
+- template:
+ src: list3.out.j2
+ dest: example-001.out
diff --git a/ansible_collections/community/general/docs/docsite/helper/lists_mergeby/example-001_vars/default-common.yml b/ansible_collections/community/general/docs/docsite/helper/lists_mergeby/example-001_vars/default-common.yml
new file mode 100644
index 000000000..fd874e5c9
--- /dev/null
+++ b/ansible_collections/community/general/docs/docsite/helper/lists_mergeby/example-001_vars/default-common.yml
@@ -0,0 +1,18 @@
+---
+# 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
+
+list2:
+ - name: foo
+ path: /foo
+ - name: baz
+ path: /baz
diff --git a/ansible_collections/community/general/docs/docsite/helper/lists_mergeby/example-001_vars/list3.yml b/ansible_collections/community/general/docs/docsite/helper/lists_mergeby/example-001_vars/list3.yml
new file mode 100644
index 000000000..0604feccb
--- /dev/null
+++ b/ansible_collections/community/general/docs/docsite/helper/lists_mergeby/example-001_vars/list3.yml
@@ -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
+
+list3: "{{ list1|
+ community.general.lists_mergeby(list2, 'name') }}"
diff --git a/ansible_collections/community/general/docs/docsite/helper/lists_mergeby/example-002.yml b/ansible_collections/community/general/docs/docsite/helper/lists_mergeby/example-002.yml
new file mode 100644
index 000000000..5e6e0315d
--- /dev/null
+++ b/ansible_collections/community/general/docs/docsite/helper/lists_mergeby/example-002.yml
@@ -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: 2. Merge two lists by common attribute 'name'
+ include_vars:
+ dir: example-002_vars
+- debug:
+ var: list3
+ when: debug|d(false)|bool
+- template:
+ src: list3.out.j2
+ dest: example-002.out
diff --git a/ansible_collections/community/general/docs/docsite/helper/lists_mergeby/example-002_vars/default-common.yml b/ansible_collections/community/general/docs/docsite/helper/lists_mergeby/example-002_vars/default-common.yml
new file mode 100644
index 000000000..fd874e5c9
--- /dev/null
+++ b/ansible_collections/community/general/docs/docsite/helper/lists_mergeby/example-002_vars/default-common.yml
@@ -0,0 +1,18 @@
+---
+# 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
+
+list2:
+ - name: foo
+ path: /foo
+ - name: baz
+ path: /baz
diff --git a/ansible_collections/community/general/docs/docsite/helper/lists_mergeby/example-002_vars/list3.yml b/ansible_collections/community/general/docs/docsite/helper/lists_mergeby/example-002_vars/list3.yml
new file mode 100644
index 000000000..8ad752407
--- /dev/null
+++ b/ansible_collections/community/general/docs/docsite/helper/lists_mergeby/example-002_vars/list3.yml
@@ -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
+
+list3: "{{ [list1, list2]|
+ community.general.lists_mergeby('name') }}"
diff --git a/ansible_collections/community/general/docs/docsite/helper/lists_mergeby/example-003.yml b/ansible_collections/community/general/docs/docsite/helper/lists_mergeby/example-003.yml
new file mode 100644
index 000000000..2f93ab8a2
--- /dev/null
+++ b/ansible_collections/community/general/docs/docsite/helper/lists_mergeby/example-003.yml
@@ -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: 3. Merge recursive by 'name', replace lists (default)
+ include_vars:
+ dir: example-003_vars
+- debug:
+ var: list3
+ when: debug|d(false)|bool
+- template:
+ src: list3.out.j2
+ dest: example-003.out
diff --git a/ansible_collections/community/general/docs/docsite/helper/lists_mergeby/example-003_vars/default-recursive-true.yml b/ansible_collections/community/general/docs/docsite/helper/lists_mergeby/example-003_vars/default-recursive-true.yml
new file mode 100644
index 000000000..133c8f2ae
--- /dev/null
+++ b/ansible_collections/community/general/docs/docsite/helper/lists_mergeby/example-003_vars/default-recursive-true.yml
@@ -0,0 +1,24 @@
+---
+# 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
+ - name: myname02
+ param01: [1, 1, 2, 3]
+
+list2:
+ - name: myname01
+ param01:
+ y: patch_value
+ z: patch_value
+ list:
+ - patch_value
+ - name: myname02
+ param01: [3, 4, 4, {key: value}]
diff --git a/ansible_collections/community/general/docs/docsite/helper/lists_mergeby/example-003_vars/list3.yml b/ansible_collections/community/general/docs/docsite/helper/lists_mergeby/example-003_vars/list3.yml
new file mode 100644
index 000000000..d5374eece
--- /dev/null
+++ b/ansible_collections/community/general/docs/docsite/helper/lists_mergeby/example-003_vars/list3.yml
@@ -0,0 +1,8 @@
+---
+# 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',
+ recursive=true) }}"
diff --git a/ansible_collections/community/general/docs/docsite/helper/lists_mergeby/example-004.yml b/ansible_collections/community/general/docs/docsite/helper/lists_mergeby/example-004.yml
new file mode 100644
index 000000000..3ef067faf
--- /dev/null
+++ b/ansible_collections/community/general/docs/docsite/helper/lists_mergeby/example-004.yml
@@ -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: 4. Merge recursive by 'name', keep lists
+ include_vars:
+ dir: example-004_vars
+- debug:
+ var: list3
+ when: debug|d(false)|bool
+- template:
+ src: list3.out.j2
+ dest: example-004.out
diff --git a/ansible_collections/community/general/docs/docsite/helper/lists_mergeby/example-004_vars/default-recursive-true.yml b/ansible_collections/community/general/docs/docsite/helper/lists_mergeby/example-004_vars/default-recursive-true.yml
new file mode 100644
index 000000000..133c8f2ae
--- /dev/null
+++ b/ansible_collections/community/general/docs/docsite/helper/lists_mergeby/example-004_vars/default-recursive-true.yml
@@ -0,0 +1,24 @@
+---
+# 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
+ - name: myname02
+ param01: [1, 1, 2, 3]
+
+list2:
+ - name: myname01
+ param01:
+ y: patch_value
+ z: patch_value
+ list:
+ - patch_value
+ - name: myname02
+ param01: [3, 4, 4, {key: value}]
diff --git a/ansible_collections/community/general/docs/docsite/helper/lists_mergeby/example-004_vars/list3.yml b/ansible_collections/community/general/docs/docsite/helper/lists_mergeby/example-004_vars/list3.yml
new file mode 100644
index 000000000..a054ea1e7
--- /dev/null
+++ b/ansible_collections/community/general/docs/docsite/helper/lists_mergeby/example-004_vars/list3.yml
@@ -0,0 +1,9 @@
+---
+# 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',
+ recursive=true,
+ list_merge='keep') }}"
diff --git a/ansible_collections/community/general/docs/docsite/helper/lists_mergeby/example-005.yml b/ansible_collections/community/general/docs/docsite/helper/lists_mergeby/example-005.yml
new file mode 100644
index 000000000..57e7a779d
--- /dev/null
+++ b/ansible_collections/community/general/docs/docsite/helper/lists_mergeby/example-005.yml
@@ -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: 5. Merge recursive by 'name', append lists
+ include_vars:
+ dir: example-005_vars
+- debug:
+ var: list3
+ when: debug|d(false)|bool
+- template:
+ src: list3.out.j2
+ dest: example-005.out
diff --git a/ansible_collections/community/general/docs/docsite/helper/lists_mergeby/example-005_vars/default-recursive-true.yml b/ansible_collections/community/general/docs/docsite/helper/lists_mergeby/example-005_vars/default-recursive-true.yml
new file mode 100644
index 000000000..133c8f2ae
--- /dev/null
+++ b/ansible_collections/community/general/docs/docsite/helper/lists_mergeby/example-005_vars/default-recursive-true.yml
@@ -0,0 +1,24 @@
+---
+# 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
+ - name: myname02
+ param01: [1, 1, 2, 3]
+
+list2:
+ - name: myname01
+ param01:
+ y: patch_value
+ z: patch_value
+ list:
+ - patch_value
+ - name: myname02
+ param01: [3, 4, 4, {key: value}]
diff --git a/ansible_collections/community/general/docs/docsite/helper/lists_mergeby/example-005_vars/list3.yml b/ansible_collections/community/general/docs/docsite/helper/lists_mergeby/example-005_vars/list3.yml
new file mode 100644
index 000000000..3480bf658
--- /dev/null
+++ b/ansible_collections/community/general/docs/docsite/helper/lists_mergeby/example-005_vars/list3.yml
@@ -0,0 +1,9 @@
+---
+# 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',
+ recursive=true,
+ list_merge='append') }}"
diff --git a/ansible_collections/community/general/docs/docsite/helper/lists_mergeby/example-006.yml b/ansible_collections/community/general/docs/docsite/helper/lists_mergeby/example-006.yml
new file mode 100644
index 000000000..41fc88e49
--- /dev/null
+++ b/ansible_collections/community/general/docs/docsite/helper/lists_mergeby/example-006.yml
@@ -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: 6. Merge recursive by 'name', prepend lists
+ include_vars:
+ dir: example-006_vars
+- debug:
+ var: list3
+ when: debug|d(false)|bool
+- template:
+ src: list3.out.j2
+ dest: example-006.out
diff --git a/ansible_collections/community/general/docs/docsite/helper/lists_mergeby/example-006_vars/default-recursive-true.yml b/ansible_collections/community/general/docs/docsite/helper/lists_mergeby/example-006_vars/default-recursive-true.yml
new file mode 100644
index 000000000..133c8f2ae
--- /dev/null
+++ b/ansible_collections/community/general/docs/docsite/helper/lists_mergeby/example-006_vars/default-recursive-true.yml
@@ -0,0 +1,24 @@
+---
+# 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
+ - name: myname02
+ param01: [1, 1, 2, 3]
+
+list2:
+ - name: myname01
+ param01:
+ y: patch_value
+ z: patch_value
+ list:
+ - patch_value
+ - name: myname02
+ param01: [3, 4, 4, {key: value}]
diff --git a/ansible_collections/community/general/docs/docsite/helper/lists_mergeby/example-006_vars/list3.yml b/ansible_collections/community/general/docs/docsite/helper/lists_mergeby/example-006_vars/list3.yml
new file mode 100644
index 000000000..97513b559
--- /dev/null
+++ b/ansible_collections/community/general/docs/docsite/helper/lists_mergeby/example-006_vars/list3.yml
@@ -0,0 +1,9 @@
+---
+# 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',
+ recursive=true,
+ list_merge='prepend') }}"
diff --git a/ansible_collections/community/general/docs/docsite/helper/lists_mergeby/example-007.yml b/ansible_collections/community/general/docs/docsite/helper/lists_mergeby/example-007.yml
new file mode 100644
index 000000000..3de715844
--- /dev/null
+++ b/ansible_collections/community/general/docs/docsite/helper/lists_mergeby/example-007.yml
@@ -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: 7. Merge recursive by 'name', append lists 'remove present'
+ include_vars:
+ dir: example-007_vars
+- debug:
+ var: list3
+ when: debug|d(false)|bool
+- template:
+ src: list3.out.j2
+ dest: example-007.out
diff --git a/ansible_collections/community/general/docs/docsite/helper/lists_mergeby/example-007_vars/default-recursive-true.yml b/ansible_collections/community/general/docs/docsite/helper/lists_mergeby/example-007_vars/default-recursive-true.yml
new file mode 100644
index 000000000..133c8f2ae
--- /dev/null
+++ b/ansible_collections/community/general/docs/docsite/helper/lists_mergeby/example-007_vars/default-recursive-true.yml
@@ -0,0 +1,24 @@
+---
+# 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
+ - name: myname02
+ param01: [1, 1, 2, 3]
+
+list2:
+ - name: myname01
+ param01:
+ y: patch_value
+ z: patch_value
+ list:
+ - patch_value
+ - name: myname02
+ param01: [3, 4, 4, {key: value}]
diff --git a/ansible_collections/community/general/docs/docsite/helper/lists_mergeby/example-007_vars/list3.yml b/ansible_collections/community/general/docs/docsite/helper/lists_mergeby/example-007_vars/list3.yml
new file mode 100644
index 000000000..cb51653b4
--- /dev/null
+++ b/ansible_collections/community/general/docs/docsite/helper/lists_mergeby/example-007_vars/list3.yml
@@ -0,0 +1,9 @@
+---
+# 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',
+ recursive=true,
+ list_merge='append_rp') }}"
diff --git a/ansible_collections/community/general/docs/docsite/helper/lists_mergeby/example-008.yml b/ansible_collections/community/general/docs/docsite/helper/lists_mergeby/example-008.yml
new file mode 100644
index 000000000..e33828bf9
--- /dev/null
+++ b/ansible_collections/community/general/docs/docsite/helper/lists_mergeby/example-008.yml
@@ -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: 8. Merge recursive by 'name', prepend lists 'remove present'
+ include_vars:
+ dir: example-008_vars
+- debug:
+ var: list3
+ when: debug|d(false)|bool
+- template:
+ src: list3.out.j2
+ dest: example-008.out
diff --git a/ansible_collections/community/general/docs/docsite/helper/lists_mergeby/example-008_vars/default-recursive-true.yml b/ansible_collections/community/general/docs/docsite/helper/lists_mergeby/example-008_vars/default-recursive-true.yml
new file mode 100644
index 000000000..133c8f2ae
--- /dev/null
+++ b/ansible_collections/community/general/docs/docsite/helper/lists_mergeby/example-008_vars/default-recursive-true.yml
@@ -0,0 +1,24 @@
+---
+# 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
+ - name: myname02
+ param01: [1, 1, 2, 3]
+
+list2:
+ - name: myname01
+ param01:
+ y: patch_value
+ z: patch_value
+ list:
+ - patch_value
+ - name: myname02
+ param01: [3, 4, 4, {key: value}]
diff --git a/ansible_collections/community/general/docs/docsite/helper/lists_mergeby/example-008_vars/list3.yml b/ansible_collections/community/general/docs/docsite/helper/lists_mergeby/example-008_vars/list3.yml
new file mode 100644
index 000000000..af7001fc4
--- /dev/null
+++ b/ansible_collections/community/general/docs/docsite/helper/lists_mergeby/example-008_vars/list3.yml
@@ -0,0 +1,9 @@
+---
+# 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',
+ recursive=true,
+ list_merge='prepend_rp') }}"
diff --git a/ansible_collections/community/general/docs/docsite/helper/lists_mergeby/examples.yml b/ansible_collections/community/general/docs/docsite/helper/lists_mergeby/examples.yml
new file mode 100644
index 000000000..83b985084
--- /dev/null
+++ b/ansible_collections/community/general/docs/docsite/helper/lists_mergeby/examples.yml
@@ -0,0 +1,54 @@
+---
+# 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:
+ - label: 'In the example below the lists are merged by the attribute ``name``:'
+ file: example-001_vars/list3.yml
+ lang: 'yaml+jinja'
+ - label: 'This produces:'
+ file: example-001.out
+ lang: 'yaml'
+ - label: '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:'
+ file: example-002.out
+ lang: 'yaml'
+ - label: 'Example ``list_merge=replace`` (default):'
+ file: example-003_vars/list3.yml
+ lang: 'yaml+jinja'
+ - label: 'This produces:'
+ file: example-003.out
+ lang: 'yaml'
+ - label: 'Example ``list_merge=keep``:'
+ file: example-004_vars/list3.yml
+ lang: 'yaml+jinja'
+ - label: 'This produces:'
+ file: example-004.out
+ lang: 'yaml'
+ - label: 'Example ``list_merge=append``:'
+ file: example-005_vars/list3.yml
+ lang: 'yaml+jinja'
+ - label: 'This produces:'
+ file: example-005.out
+ lang: 'yaml'
+ - label: 'Example ``list_merge=prepend``:'
+ file: example-006_vars/list3.yml
+ lang: 'yaml+jinja'
+ - label: 'This produces:'
+ file: example-006.out
+ lang: 'yaml'
+ - label: 'Example ``list_merge=append_rp``:'
+ file: example-007_vars/list3.yml
+ lang: 'yaml+jinja'
+ - label: 'This produces:'
+ file: example-007.out
+ lang: 'yaml'
+ - label: 'Example ``list_merge=prepend_rp``:'
+ file: example-008_vars/list3.yml
+ lang: 'yaml+jinja'
+ - label: 'This produces:'
+ file: example-008.out
+ lang: 'yaml'
diff --git a/ansible_collections/community/general/docs/docsite/helper/lists_mergeby/examples_all.rst.j2 b/ansible_collections/community/general/docs/docsite/helper/lists_mergeby/examples_all.rst.j2
new file mode 100644
index 000000000..95a0fafdd
--- /dev/null
+++ b/ansible_collections/community/general/docs/docsite/helper/lists_mergeby/examples_all.rst.j2
@@ -0,0 +1,13 @@
+..
+ Copyright (c) Ansible Project
+ GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+ SPDX-License-Identifier: GPL-3.0-or-later
+
+{% for i in examples %}
+{{ i.label }}
+
+.. code-block:: {{ i.lang }}
+
+ {{ lookup('file', i.file)|indent(2) }}
+
+{% endfor %}
diff --git a/ansible_collections/community/general/docs/docsite/helper/lists_mergeby/filter_guide_abstract_informations_merging_lists_of_dictionaries.rst.j2 b/ansible_collections/community/general/docs/docsite/helper/lists_mergeby/filter_guide_abstract_informations_merging_lists_of_dictionaries.rst.j2
new file mode 100644
index 000000000..71d0d5da6
--- /dev/null
+++ b/ansible_collections/community/general/docs/docsite/helper/lists_mergeby/filter_guide_abstract_informations_merging_lists_of_dictionaries.rst.j2
@@ -0,0 +1,62 @@
+..
+ 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
+
+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.
+
+.. 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>`.
+
+Let us use the lists below in the following examples:
+
+.. code-block:: yaml
+
+ {{ lookup('file', 'default-common.yml')|indent(2) }}
+
+{% for i in examples[0:2] %}
+{{ i.label }}
+
+.. code-block:: {{ i.lang }}
+
+ {{ lookup('file', i.file)|indent(2) }}
+
+{% endfor %}
+
+.. versionadded:: 2.0.0
+
+{% for i in examples[2:4] %}
+{{ i.label }}
+
+.. code-block:: {{ i.lang }}
+
+ {{ lookup('file', i.file)|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.
+
+**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``.
+
+**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.
+
+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.
+
+Let us use the lists below in the following examples
+
+.. code-block:: yaml
+
+ {{ lookup('file', 'default-recursive-true.yml')|indent(2) }}
+
+{% for i in examples[4:16] %}
+{{ i.label }}
+
+.. code-block:: {{ i.lang }}
+
+ {{ lookup('file', i.file)|indent(2) }}
+
+{% endfor %}
diff --git a/ansible_collections/community/general/docs/docsite/helper/lists_mergeby/list3.out.j2 b/ansible_collections/community/general/docs/docsite/helper/lists_mergeby/list3.out.j2
new file mode 100644
index 000000000..b51f6b868
--- /dev/null
+++ b/ansible_collections/community/general/docs/docsite/helper/lists_mergeby/list3.out.j2
@@ -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
+#}
+list3:
+{{ list3|to_nice_yaml(indent=0) }}
diff --git a/ansible_collections/community/general/docs/docsite/helper/lists_mergeby/playbook.yml b/ansible_collections/community/general/docs/docsite/helper/lists_mergeby/playbook.yml
new file mode 100644
index 000000000..793d23348
--- /dev/null
+++ b/ansible_collections/community/general/docs/docsite/helper/lists_mergeby/playbook.yml
@@ -0,0 +1,62 @@
+---
+# 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
+
+# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+# 1) Run all examples and create example-XXX.out
+# shell> ansible-playbook playbook.yml -e examples=true
+#
+# 2) Optionally, for testing, create examples_all.rst
+# shell> ansible-playbook playbook.yml -e examples_all=true
+#
+# 3) Create docs REST files
+# shell> ansible-playbook playbook.yml -e merging_lists_of_dictionaries=true
+#
+# Notes:
+# * Use YAML callback, e.g. set ANSIBLE_STDOUT_CALLBACK=community.general.yaml
+# * Use sphinx-view to render and review the REST files
+# shell> sphinx-view <path_to_helper>/examples_all.rst
+# * Proofread and copy completed docs *.rst files into the directory rst.
+# * Then delete the *.rst and *.out files from this directory. Do not
+# add *.rst and *.out in this directory to the version control.
+#
+# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+# community.general/docs/docsite/helper/lists_mergeby/playbook.yml
+
+- hosts: localhost
+ gather_facts: false
+ tasks:
+
+ - block:
+ - import_tasks: example-001.yml
+ tags: t001
+ - import_tasks: example-002.yml
+ tags: t002
+ - import_tasks: example-003.yml
+ tags: t003
+ - import_tasks: example-004.yml
+ tags: t004
+ - import_tasks: example-005.yml
+ tags: t005
+ - import_tasks: example-006.yml
+ tags: t006
+ - import_tasks: example-007.yml
+ tags: t007
+ - import_tasks: example-008.yml
+ tags: t008
+ when: examples|d(false)|bool
+
+ - block:
+ - include_vars: examples.yml
+ - template:
+ src: examples_all.rst.j2
+ dest: examples_all.rst
+ 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
diff --git a/ansible_collections/community/general/docs/docsite/links.yml b/ansible_collections/community/general/docs/docsite/links.yml
new file mode 100644
index 000000000..bd954c409
--- /dev/null
+++ b/ansible_collections/community/general/docs/docsite/links.yml
@@ -0,0 +1,27 @@
+---
+# 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
+
+edit_on_github:
+ repository: ansible-collections/community.general
+ branch: main
+ path_prefix: ''
+
+extra_links:
+ - description: Submit a bug report
+ url: https://github.com/ansible-collections/community.general/issues/new?assignees=&labels=&template=bug_report.yml
+ - description: Request a feature
+ url: https://github.com/ansible-collections/community.general/issues/new?assignees=&labels=&template=feature_request.yml
+
+communication:
+ matrix_rooms:
+ - topic: General usage and support questions
+ room: '#users:ansible.im'
+ irc_channels:
+ - topic: General usage and support questions
+ network: Libera
+ channel: '#ansible'
+ mailing_lists:
+ - topic: Ansible Project List
+ url: https://groups.google.com/g/ansible-project
diff --git a/ansible_collections/community/general/docs/docsite/rst/filter_guide.rst b/ansible_collections/community/general/docs/docsite/rst/filter_guide.rst
new file mode 100644
index 000000000..1c6468dde
--- /dev/null
+++ b/ansible_collections/community/general/docs/docsite/rst/filter_guide.rst
@@ -0,0 +1,23 @@
+..
+ Copyright (c) Ansible Project
+ GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+ SPDX-License-Identifier: GPL-3.0-or-later
+
+.. _ansible_collections.community.general.docsite.filter_guide:
+
+community.general Filter Guide
+==============================
+
+The :ref:`community.general collection <plugins_in_community.general>` offers several useful filter plugins.
+
+.. toctree::
+ :maxdepth: 2
+
+ filter_guide_paths
+ filter_guide_abstract_informations
+ filter_guide_working_with_times
+ filter_guide_working_with_versions
+ filter_guide_creating_identifiers
+ filter_guide_conversions
+ filter_guide_selecting_json_data
+ filter_guide_working_with_unicode
diff --git a/ansible_collections/community/general/docs/docsite/rst/filter_guide_abstract_informations.rst b/ansible_collections/community/general/docs/docsite/rst/filter_guide_abstract_informations.rst
new file mode 100644
index 000000000..8f997f163
--- /dev/null
+++ b/ansible_collections/community/general/docs/docsite/rst/filter_guide_abstract_informations.rst
@@ -0,0 +1,15 @@
+..
+ 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
+
+Abstract transformations
+------------------------
+
+.. toctree::
+ :maxdepth: 1
+
+ filter_guide_abstract_informations_dictionaries
+ filter_guide_abstract_informations_grouping
+ filter_guide_abstract_informations_merging_lists_of_dictionaries
+ filter_guide_abstract_informations_counting_elements_in_sequence
diff --git a/ansible_collections/community/general/docs/docsite/rst/filter_guide_abstract_informations_counting_elements_in_sequence.rst b/ansible_collections/community/general/docs/docsite/rst/filter_guide_abstract_informations_counting_elements_in_sequence.rst
new file mode 100644
index 000000000..dcadd5a79
--- /dev/null
+++ b/ansible_collections/community/general/docs/docsite/rst/filter_guide_abstract_informations_counting_elements_in_sequence.rst
@@ -0,0 +1,82 @@
+..
+ 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
+
+Counting elements in a sequence
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+The ``community.general.counter`` filter plugin allows you to count (hashable) elements in a sequence. Elements are returned as dictionary keys and their counts are stored as dictionary values.
+
+.. code-block:: yaml+jinja
+
+ - name: Count character occurrences in a string
+ debug:
+ msg: "{{ 'abccbaabca' | community.general.counter }}"
+
+ - name: Count items in a list
+ debug:
+ msg: "{{ ['car', 'car', 'bike', 'plane', 'bike'] | community.general.counter }}"
+
+This produces:
+
+.. code-block:: ansible-output
+
+ TASK [Count character occurrences in a string] ********************************************
+ ok: [localhost] => {
+ "msg": {
+ "a": 4,
+ "b": 3,
+ "c": 3
+ }
+ }
+
+ TASK [Count items in a list] **************************************************************
+ ok: [localhost] => {
+ "msg": {
+ "bike": 2,
+ "car": 2,
+ "plane": 1
+ }
+ }
+
+This plugin is useful for selecting resources based on current allocation:
+
+.. code-block:: yaml+jinja
+
+ - name: Get ID of SCSI controller(s) with less than 4 disks attached and choose the one with the least disks
+ debug:
+ msg: >-
+ {{
+ ( disks | dict2items | map(attribute='value.adapter') | list
+ | community.general.counter | dict2items
+ | rejectattr('value', '>=', 4) | sort(attribute='value') | first
+ ).key
+ }}
+ vars:
+ disks:
+ sda:
+ adapter: scsi_1
+ sdb:
+ adapter: scsi_1
+ sdc:
+ adapter: scsi_1
+ sdd:
+ adapter: scsi_1
+ sde:
+ adapter: scsi_2
+ sdf:
+ adapter: scsi_3
+ sdg:
+ adapter: scsi_3
+
+This produces:
+
+.. code-block:: ansible-output
+
+ TASK [Get ID of SCSI controller(s) with less than 4 disks attached and choose the one with the least disks]
+ ok: [localhost] => {
+ "msg": "scsi_2"
+ }
+
+.. versionadded:: 4.3.0
diff --git a/ansible_collections/community/general/docs/docsite/rst/filter_guide_abstract_informations_dictionaries.rst b/ansible_collections/community/general/docs/docsite/rst/filter_guide_abstract_informations_dictionaries.rst
new file mode 100644
index 000000000..840bd1542
--- /dev/null
+++ b/ansible_collections/community/general/docs/docsite/rst/filter_guide_abstract_informations_dictionaries.rst
@@ -0,0 +1,124 @@
+..
+ 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
+
+Dictionaries
+^^^^^^^^^^^^
+
+You can use the ``dict_kv`` filter to create a single-entry dictionary with ``value | community.general.dict_kv(key)``:
+
+.. code-block:: yaml+jinja
+
+ - name: Create a single-entry dictionary
+ debug:
+ msg: "{{ myvar | community.general.dict_kv('thatsmyvar') }}"
+ vars:
+ myvar: myvalue
+
+ - name: Create a list of dictionaries where the 'server' field is taken from a list
+ debug:
+ msg: >-
+ {{ myservers | map('community.general.dict_kv', 'server')
+ | map('combine', common_config) }}
+ vars:
+ common_config:
+ type: host
+ database: all
+ myservers:
+ - server1
+ - server2
+
+This produces:
+
+.. code-block:: ansible-output
+
+ TASK [Create a single-entry dictionary] **************************************************
+ ok: [localhost] => {
+ "msg": {
+ "thatsmyvar": "myvalue"
+ }
+ }
+
+ TASK [Create a list of dictionaries where the 'server' field is taken from a list] *******
+ ok: [localhost] => {
+ "msg": [
+ {
+ "database": "all",
+ "server": "server1",
+ "type": "host"
+ },
+ {
+ "database": "all",
+ "server": "server2",
+ "type": "host"
+ }
+ ]
+ }
+
+.. versionadded:: 2.0.0
+
+If you need to convert a list of key-value pairs to a dictionary, you can use the ``dict`` function. Unfortunately, this function cannot be used with ``map``. For this, the ``community.general.dict`` filter can be used:
+
+.. code-block:: yaml+jinja
+
+ - name: Create a dictionary with the dict function
+ debug:
+ msg: "{{ dict([[1, 2], ['a', 'b']]) }}"
+
+ - name: Create a dictionary with the community.general.dict filter
+ debug:
+ msg: "{{ [[1, 2], ['a', 'b']] | community.general.dict }}"
+
+ - name: Create a list of dictionaries with map and the community.general.dict filter
+ debug:
+ msg: >-
+ {{ values | map('zip', ['k1', 'k2', 'k3'])
+ | map('map', 'reverse')
+ | map('community.general.dict') }}
+ vars:
+ values:
+ - - foo
+ - 23
+ - a
+ - - bar
+ - 42
+ - b
+
+This produces:
+
+.. code-block:: ansible-output
+
+ TASK [Create a dictionary with the dict function] ****************************************
+ ok: [localhost] => {
+ "msg": {
+ "1": 2,
+ "a": "b"
+ }
+ }
+
+ TASK [Create a dictionary with the community.general.dict filter] ************************
+ ok: [localhost] => {
+ "msg": {
+ "1": 2,
+ "a": "b"
+ }
+ }
+
+ TASK [Create a list of dictionaries with map and the community.general.dict filter] ******
+ ok: [localhost] => {
+ "msg": [
+ {
+ "k1": "foo",
+ "k2": 23,
+ "k3": "a"
+ },
+ {
+ "k1": "bar",
+ "k2": 42,
+ "k3": "b"
+ }
+ ]
+ }
+
+.. versionadded:: 3.0.0
diff --git a/ansible_collections/community/general/docs/docsite/rst/filter_guide_abstract_informations_grouping.rst b/ansible_collections/community/general/docs/docsite/rst/filter_guide_abstract_informations_grouping.rst
new file mode 100644
index 000000000..2cea7f9ba
--- /dev/null
+++ b/ansible_collections/community/general/docs/docsite/rst/filter_guide_abstract_informations_grouping.rst
@@ -0,0 +1,103 @@
+..
+ 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
+
+Grouping
+^^^^^^^^
+
+If you have a list of dictionaries, the Jinja2 ``groupby`` filter allows to group the list by an attribute. This results in a list of ``(grouper, list)`` namedtuples, where ``list`` contains all dictionaries where the selected attribute equals ``grouper``. If you know that for every ``grouper``, there will be a most one entry in that list, you can use the ``community.general.groupby_as_dict`` filter to convert the original list into a dictionary which maps ``grouper`` to the corresponding dictionary.
+
+One example is ``ansible_facts.mounts``, which is a list of dictionaries where each has one ``device`` element to indicate the device which is mounted. Therefore, ``ansible_facts.mounts | community.general.groupby_as_dict('device')`` is a dictionary mapping a device to the mount information:
+
+.. code-block:: yaml+jinja
+
+ - name: Output mount facts grouped by device name
+ debug:
+ var: ansible_facts.mounts | community.general.groupby_as_dict('device')
+
+ - name: Output mount facts grouped by mount point
+ debug:
+ var: ansible_facts.mounts | community.general.groupby_as_dict('mount')
+
+This produces:
+
+.. code-block:: ansible-output
+
+ TASK [Output mount facts grouped by device name] ******************************************
+ ok: [localhost] => {
+ "ansible_facts.mounts | community.general.groupby_as_dict('device')": {
+ "/dev/sda1": {
+ "block_available": 2000,
+ "block_size": 4096,
+ "block_total": 2345,
+ "block_used": 345,
+ "device": "/dev/sda1",
+ "fstype": "ext4",
+ "inode_available": 500,
+ "inode_total": 512,
+ "inode_used": 12,
+ "mount": "/boot",
+ "options": "rw,relatime,data=ordered",
+ "size_available": 56821,
+ "size_total": 543210,
+ "uuid": "ab31cade-d9c1-484d-8482-8a4cbee5241a"
+ },
+ "/dev/sda2": {
+ "block_available": 1234,
+ "block_size": 4096,
+ "block_total": 12345,
+ "block_used": 11111,
+ "device": "/dev/sda2",
+ "fstype": "ext4",
+ "inode_available": 1111,
+ "inode_total": 1234,
+ "inode_used": 123,
+ "mount": "/",
+ "options": "rw,relatime",
+ "size_available": 42143,
+ "size_total": 543210,
+ "uuid": "abcdef01-2345-6789-0abc-def012345678"
+ }
+ }
+ }
+
+ TASK [Output mount facts grouped by mount point] ******************************************
+ ok: [localhost] => {
+ "ansible_facts.mounts | community.general.groupby_as_dict('mount')": {
+ "/": {
+ "block_available": 1234,
+ "block_size": 4096,
+ "block_total": 12345,
+ "block_used": 11111,
+ "device": "/dev/sda2",
+ "fstype": "ext4",
+ "inode_available": 1111,
+ "inode_total": 1234,
+ "inode_used": 123,
+ "mount": "/",
+ "options": "rw,relatime",
+ "size_available": 42143,
+ "size_total": 543210,
+ "uuid": "bdf50b7d-4859-40af-8665-c637ee7a7808"
+ },
+ "/boot": {
+ "block_available": 2000,
+ "block_size": 4096,
+ "block_total": 2345,
+ "block_used": 345,
+ "device": "/dev/sda1",
+ "fstype": "ext4",
+ "inode_available": 500,
+ "inode_total": 512,
+ "inode_used": 12,
+ "mount": "/boot",
+ "options": "rw,relatime,data=ordered",
+ "size_available": 56821,
+ "size_total": 543210,
+ "uuid": "ab31cade-d9c1-484d-8482-8a4cbee5241a"
+ }
+ }
+ }
+
+.. versionadded: 3.0.0
diff --git a/ansible_collections/community/general/docs/docsite/rst/filter_guide_abstract_informations_merging_lists_of_dictionaries.rst b/ansible_collections/community/general/docs/docsite/rst/filter_guide_abstract_informations_merging_lists_of_dictionaries.rst
new file mode 100644
index 000000000..9b56e98d7
--- /dev/null
+++ b/ansible_collections/community/general/docs/docsite/rst/filter_guide_abstract_informations_merging_lists_of_dictionaries.rst
@@ -0,0 +1,297 @@
+..
+ 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
+
+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.
+
+.. 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>`.
+
+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
+
+ list2:
+ - name: foo
+ path: /foo
+ - name: baz
+ path: /baz
+
+In the example below the lists are merged by the attribute ``name``:
+
+.. code-block:: yaml+jinja
+
+ list3: "{{ list1|
+ community.general.lists_mergeby(list2, 'name') }}"
+
+This produces:
+
+.. code-block:: yaml
+
+ list3:
+ - extra: false
+ name: bar
+ - name: baz
+ path: /baz
+ - extra: true
+ name: foo
+ path: /foo
+ - extra: true
+ name: meh
+
+
+.. versionadded:: 2.0.0
+
+It is possible to use a list of lists as an input of the filter:
+
+.. 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:
+ - extra: false
+ name: bar
+ - name: baz
+ path: /baz
+ - extra: true
+ name: foo
+ path: /foo
+ - extra: true
+ name: meh
+
+
+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.
+
+**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``.
+
+**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.
+
+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.
+
+Let us use the lists below in the following examples
+
+.. code-block:: yaml
+
+ list1:
+ - name: myname01
+ param01:
+ x: default_value
+ y: default_value
+ list:
+ - default_value
+ - name: myname02
+ param01: [1, 1, 2, 3]
+
+ list2:
+ - name: myname01
+ param01:
+ y: patch_value
+ z: patch_value
+ list:
+ - patch_value
+ - name: myname02
+ param01: [3, 4, 4, {key: value}]
+
+Example ``list_merge=replace`` (default):
+
+.. code-block:: yaml+jinja
+
+ list3: "{{ [list1, list2]|
+ community.general.lists_mergeby('name',
+ recursive=true) }}"
+
+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
+
+Example ``list_merge=keep``:
+
+.. code-block:: yaml+jinja
+
+ list3: "{{ [list1, list2]|
+ community.general.lists_mergeby('name',
+ recursive=true,
+ list_merge='keep') }}"
+
+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
+
+Example ``list_merge=append``:
+
+.. code-block:: yaml+jinja
+
+ list3: "{{ [list1, list2]|
+ community.general.lists_mergeby('name',
+ recursive=true,
+ list_merge='append') }}"
+
+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
+
+Example ``list_merge=prepend``:
+
+.. code-block:: yaml+jinja
+
+ list3: "{{ [list1, list2]|
+ community.general.lists_mergeby('name',
+ recursive=true,
+ list_merge='prepend') }}"
+
+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
+
+Example ``list_merge=append_rp``:
+
+.. code-block:: yaml+jinja
+
+ list3: "{{ [list1, list2]|
+ community.general.lists_mergeby('name',
+ recursive=true,
+ list_merge='append_rp') }}"
+
+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
+
+Example ``list_merge=prepend_rp``:
+
+.. code-block:: yaml+jinja
+
+ list3: "{{ [list1, list2]|
+ community.general.lists_mergeby('name',
+ recursive=true,
+ list_merge='prepend_rp') }}"
+
+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
+
diff --git a/ansible_collections/community/general/docs/docsite/rst/filter_guide_conversions.rst b/ansible_collections/community/general/docs/docsite/rst/filter_guide_conversions.rst
new file mode 100644
index 000000000..78970c17b
--- /dev/null
+++ b/ansible_collections/community/general/docs/docsite/rst/filter_guide_conversions.rst
@@ -0,0 +1,113 @@
+..
+ 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
+
+Conversions
+-----------
+
+Parsing CSV files
+^^^^^^^^^^^^^^^^^
+
+Ansible offers the :ref:`community.general.read_csv module <ansible_collections.community.general.read_csv_module>` to read CSV files. Sometimes you need to convert strings to CSV files instead. For this, the ``from_csv`` filter exists.
+
+.. code-block:: yaml+jinja
+
+ - name: "Parse CSV from string"
+ debug:
+ msg: "{{ csv_string | community.general.from_csv }}"
+ vars:
+ csv_string: |
+ foo,bar,baz
+ 1,2,3
+ you,this,then
+
+This produces:
+
+.. code-block:: ansible-output
+
+ TASK [Parse CSV from string] **************************************************************
+ ok: [localhost] => {
+ "msg": [
+ {
+ "bar": "2",
+ "baz": "3",
+ "foo": "1"
+ },
+ {
+ "bar": "this",
+ "baz": "then",
+ "foo": "you"
+ }
+ ]
+ }
+
+The ``from_csv`` filter has several keyword arguments to control its behavior:
+
+:dialect: Dialect of the CSV file. Default is ``excel``. Other possible choices are ``excel-tab`` and ``unix``. If one of ``delimiter``, ``skipinitialspace`` or ``strict`` is specified, ``dialect`` is ignored.
+:fieldnames: A set of column names to use. If not provided, the first line of the CSV is assumed to contain the column names.
+:delimiter: Sets the delimiter to use. Default depends on the dialect used.
+:skipinitialspace: Set to ``true`` to ignore space directly after the delimiter. Default depends on the dialect used (usually ``false``).
+:strict: Set to ``true`` to error out on invalid CSV input.
+
+.. versionadded: 3.0.0
+
+Converting to JSON
+^^^^^^^^^^^^^^^^^^
+
+`JC <https://pypi.org/project/jc/>`_ is a CLI tool and Python library which allows to interpret output of various CLI programs as JSON. It is also available as a filter in community.general. This filter needs the `jc Python library <https://pypi.org/project/jc/>`_ installed on the controller.
+
+.. code-block:: yaml+jinja
+
+ - name: Run 'ls' to list files in /
+ command: ls /
+ register: result
+
+ - name: Parse the ls output
+ debug:
+ msg: "{{ result.stdout | community.general.jc('ls') }}"
+
+This produces:
+
+.. code-block:: ansible-output
+
+ TASK [Run 'ls' to list files in /] ********************************************************
+ changed: [localhost]
+
+ TASK [Parse the ls output] ****************************************************************
+ ok: [localhost] => {
+ "msg": [
+ {
+ "filename": "bin"
+ },
+ {
+ "filename": "boot"
+ },
+ {
+ "filename": "dev"
+ },
+ {
+ "filename": "etc"
+ },
+ {
+ "filename": "home"
+ },
+ {
+ "filename": "lib"
+ },
+ {
+ "filename": "proc"
+ },
+ {
+ "filename": "root"
+ },
+ {
+ "filename": "run"
+ },
+ {
+ "filename": "tmp"
+ }
+ ]
+ }
+
+.. versionadded: 2.0.0
diff --git a/ansible_collections/community/general/docs/docsite/rst/filter_guide_creating_identifiers.rst b/ansible_collections/community/general/docs/docsite/rst/filter_guide_creating_identifiers.rst
new file mode 100644
index 000000000..af0a8b7ba
--- /dev/null
+++ b/ansible_collections/community/general/docs/docsite/rst/filter_guide_creating_identifiers.rst
@@ -0,0 +1,85 @@
+..
+ 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
+
+Creating identifiers
+--------------------
+
+The following filters allow to create identifiers.
+
+Hashids
+^^^^^^^
+
+`Hashids <https://hashids.org/>`_ allow to convert sequences of integers to short unique string identifiers. This filter needs the `hashids Python library <https://pypi.org/project/hashids/>`_ installed on the controller.
+
+.. code-block:: yaml+jinja
+
+ - name: "Create hashid"
+ debug:
+ msg: "{{ [1234, 5, 6] | community.general.hashids_encode }}"
+
+ - name: "Decode hashid"
+ debug:
+ msg: "{{ 'jm2Cytn' | community.general.hashids_decode }}"
+
+This produces:
+
+.. code-block:: ansible-output
+
+ TASK [Create hashid] **********************************************************************
+ ok: [localhost] => {
+ "msg": "jm2Cytn"
+ }
+
+ TASK [Decode hashid] **********************************************************************
+ ok: [localhost] => {
+ "msg": [
+ 1234,
+ 5,
+ 6
+ ]
+ }
+
+The hashids filters accept keyword arguments to allow fine-tuning the hashids generated:
+
+:salt: String to use as salt when hashing.
+:alphabet: String of 16 or more unique characters to produce a hash.
+:min_length: Minimum length of hash produced.
+
+.. versionadded: 3.0.0
+
+Random MACs
+^^^^^^^^^^^
+
+You can use the ``random_mac`` filter to complete a partial `MAC address <https://en.wikipedia.org/wiki/MAC_address>`_ to a random 6-byte MAC address.
+
+.. code-block:: yaml+jinja
+
+ - name: "Create a random MAC starting with ff:"
+ debug:
+ msg: "{{ 'FF' | community.general.random_mac }}"
+
+ - name: "Create a random MAC starting with 00:11:22:"
+ debug:
+ msg: "{{ '00:11:22' | community.general.random_mac }}"
+
+This produces:
+
+.. code-block:: ansible-output
+
+ TASK [Create a random MAC starting with ff:] **********************************************
+ ok: [localhost] => {
+ "msg": "ff:69:d3:78:7f:b4"
+ }
+
+ TASK [Create a random MAC starting with 00:11:22:] ****************************************
+ ok: [localhost] => {
+ "msg": "00:11:22:71:5d:3b"
+ }
+
+You can also initialize the random number generator from a seed to create random-but-idempotent MAC addresses:
+
+.. code-block:: yaml+jinja
+
+ "{{ '52:54:00' | community.general.random_mac(seed=inventory_hostname) }}"
diff --git a/ansible_collections/community/general/docs/docsite/rst/filter_guide_paths.rst b/ansible_collections/community/general/docs/docsite/rst/filter_guide_paths.rst
new file mode 100644
index 000000000..dac893145
--- /dev/null
+++ b/ansible_collections/community/general/docs/docsite/rst/filter_guide_paths.rst
@@ -0,0 +1,19 @@
+..
+ 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
+
+Paths
+-----
+
+The ``path_join`` filter has been added in ansible-base 2.10. If you want to use this filter, but also need to support Ansible 2.9, you can use ``community.general``'s ``path_join`` shim, ``community.general.path_join``. This filter redirects to ``path_join`` for ansible-base 2.10 and ansible-core 2.11 or newer, and re-implements the filter for Ansible 2.9.
+
+.. code-block:: yaml+jinja
+
+ # ansible-base 2.10 or newer:
+ path: {{ ('/etc', path, 'subdir', file) | path_join }}
+
+ # Also works with Ansible 2.9:
+ path: {{ ('/etc', path, 'subdir', file) | community.general.path_join }}
+
+.. versionadded:: 3.0.0
diff --git a/ansible_collections/community/general/docs/docsite/rst/filter_guide_selecting_json_data.rst b/ansible_collections/community/general/docs/docsite/rst/filter_guide_selecting_json_data.rst
new file mode 100644
index 000000000..d8de07b92
--- /dev/null
+++ b/ansible_collections/community/general/docs/docsite/rst/filter_guide_selecting_json_data.rst
@@ -0,0 +1,149 @@
+..
+ Copyright (c) Ansible Project
+ GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+ SPDX-License-Identifier: GPL-3.0-or-later
+
+.. _ansible_collections.community.general.docsite.json_query_filter:
+
+Selecting JSON data: JSON queries
+---------------------------------
+
+To select a single element or a data subset from a complex data structure in JSON format (for example, Ansible facts), use the ``json_query`` filter. The ``json_query`` filter lets you query a complex JSON structure and iterate over it using a loop structure.
+
+.. note:: You must manually install the **jmespath** dependency on the Ansible controller before using this filter. This filter is built upon **jmespath**, and you can use the same syntax. For examples, see `jmespath examples <http://jmespath.org/examples.html>`_.
+
+Consider this data structure:
+
+.. code-block:: yaml+jinja
+
+ {
+ "domain_definition": {
+ "domain": {
+ "cluster": [
+ {
+ "name": "cluster1"
+ },
+ {
+ "name": "cluster2"
+ }
+ ],
+ "server": [
+ {
+ "name": "server11",
+ "cluster": "cluster1",
+ "port": "8080"
+ },
+ {
+ "name": "server12",
+ "cluster": "cluster1",
+ "port": "8090"
+ },
+ {
+ "name": "server21",
+ "cluster": "cluster2",
+ "port": "9080"
+ },
+ {
+ "name": "server22",
+ "cluster": "cluster2",
+ "port": "9090"
+ }
+ ],
+ "library": [
+ {
+ "name": "lib1",
+ "target": "cluster1"
+ },
+ {
+ "name": "lib2",
+ "target": "cluster2"
+ }
+ ]
+ }
+ }
+ }
+
+To extract all clusters from this structure, you can use the following query:
+
+.. code-block:: yaml+jinja
+
+ - name: Display all cluster names
+ ansible.builtin.debug:
+ var: item
+ loop: "{{ domain_definition | community.general.json_query('domain.cluster[*].name') }}"
+
+To extract all server names:
+
+.. code-block:: yaml+jinja
+
+ - name: Display all server names
+ ansible.builtin.debug:
+ var: item
+ loop: "{{ domain_definition | community.general.json_query('domain.server[*].name') }}"
+
+To extract ports from cluster1:
+
+.. code-block:: yaml+jinja
+
+ - name: Display all ports from cluster1
+ ansible.builtin.debug:
+ var: item
+ loop: "{{ domain_definition | community.general.json_query(server_name_cluster1_query) }}"
+ vars:
+ server_name_cluster1_query: "domain.server[?cluster=='cluster1'].port"
+
+.. note:: You can use a variable to make the query more readable.
+
+To print out the ports from cluster1 in a comma separated string:
+
+.. code-block:: yaml+jinja
+
+ - name: Display all ports from cluster1 as a string
+ ansible.builtin.debug:
+ msg: "{{ domain_definition | community.general.json_query('domain.server[?cluster==`cluster1`].port') | join(', ') }}"
+
+.. note:: In the example above, quoting literals using backticks avoids escaping quotes and maintains readability.
+
+You can use YAML `single quote escaping <https://yaml.org/spec/current.html#id2534365>`_:
+
+.. code-block:: yaml+jinja
+
+ - name: Display all ports from cluster1
+ ansible.builtin.debug:
+ var: item
+ loop: "{{ domain_definition | community.general.json_query('domain.server[?cluster==''cluster1''].port') }}"
+
+.. note:: Escaping single quotes within single quotes in YAML is done by doubling the single quote.
+
+To get a hash map with all ports and names of a cluster:
+
+.. code-block:: yaml+jinja
+
+ - name: Display all server ports and names from cluster1
+ ansible.builtin.debug:
+ var: item
+ loop: "{{ domain_definition | community.general.json_query(server_name_cluster1_query) }}"
+ vars:
+ server_name_cluster1_query: "domain.server[?cluster=='cluster2'].{name: name, port: port}"
+
+To extract ports from all clusters with name starting with 'server1':
+
+.. code-block:: yaml+jinja
+
+ - name: Display all ports from cluster1
+ ansible.builtin.debug:
+ msg: "{{ domain_definition | to_json | from_json | community.general.json_query(server_name_query) }}"
+ vars:
+ server_name_query: "domain.server[?starts_with(name,'server1')].port"
+
+To extract ports from all clusters with name containing 'server1':
+
+.. code-block:: yaml+jinja
+
+ - name: Display all ports from cluster1
+ ansible.builtin.debug:
+ msg: "{{ domain_definition | to_json | from_json | community.general.json_query(server_name_query) }}"
+ vars:
+ server_name_query: "domain.server[?contains(name,'server1')].port"
+
+.. note:: while using ``starts_with`` and ``contains``, you have to use `` to_json | from_json `` filter for correct parsing of data structure.
diff --git a/ansible_collections/community/general/docs/docsite/rst/filter_guide_working_with_times.rst b/ansible_collections/community/general/docs/docsite/rst/filter_guide_working_with_times.rst
new file mode 100644
index 000000000..dc68f2a2e
--- /dev/null
+++ b/ansible_collections/community/general/docs/docsite/rst/filter_guide_working_with_times.rst
@@ -0,0 +1,89 @@
+..
+ 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
+
+Working with times
+------------------
+
+The ``to_time_unit`` filter allows to convert times from a human-readable string to a unit. For example, ``'4h 30min 12second' | community.general.to_time_unit('hour')`` gives the number of hours that correspond to 4 hours, 30 minutes and 12 seconds.
+
+There are shorthands to directly convert to various units, like ``to_hours``, ``to_minutes``, ``to_seconds``, and so on. The following table lists all units that can be used:
+
+.. list-table:: Units
+ :widths: 25 25 25 25
+ :header-rows: 1
+
+ * - Unit name
+ - Unit value in seconds
+ - Unit strings for filter
+ - Shorthand filter
+ * - Millisecond
+ - 1/1000 second
+ - ``ms``, ``millisecond``, ``milliseconds``, ``msec``, ``msecs``, ``msecond``, ``mseconds``
+ - ``to_milliseconds``
+ * - Second
+ - 1 second
+ - ``s``, ``sec``, ``secs``, ``second``, ``seconds``
+ - ``to_seconds``
+ * - Minute
+ - 60 seconds
+ - ``m``, ``min``, ``mins``, ``minute``, ``minutes``
+ - ``to_minutes``
+ * - Hour
+ - 60*60 seconds
+ - ``h``, ``hour``, ``hours``
+ - ``to_hours``
+ * - Day
+ - 24*60*60 seconds
+ - ``d``, ``day``, ``days``
+ - ``to_days``
+ * - Week
+ - 7*24*60*60 seconds
+ - ``w``, ``week``, ``weeks``
+ - ``to_weeks``
+ * - Month
+ - 30*24*60*60 seconds
+ - ``mo``, ``month``, ``months``
+ - ``to_months``
+ * - Year
+ - 365*24*60*60 seconds
+ - ``y``, ``year``, ``years``
+ - ``to_years``
+
+Note that months and years are using a simplified representation: a month is 30 days, and a year is 365 days. If you need different definitions of months or years, you can pass them as keyword arguments. For example, if you want a year to be 365.25 days, and a month to be 30.5 days, you can write ``'11months 4' | community.general.to_years(year=365.25, month=30.5)``. These keyword arguments can be specified to ``to_time_unit`` and to all shorthand filters.
+
+.. code-block:: yaml+jinja
+
+ - name: Convert string to seconds
+ debug:
+ msg: "{{ '30h 20m 10s 123ms' | community.general.to_time_unit('seconds') }}"
+
+ - name: Convert string to hours
+ debug:
+ msg: "{{ '30h 20m 10s 123ms' | community.general.to_hours }}"
+
+ - name: Convert string to years (using 365.25 days == 1 year)
+ debug:
+ msg: "{{ '400d 15h' | community.general.to_years(year=365.25) }}"
+
+This produces:
+
+.. code-block:: ansible-output
+
+ TASK [Convert string to seconds] **********************************************************
+ ok: [localhost] => {
+ "msg": "109210.123"
+ }
+
+ TASK [Convert string to hours] ************************************************************
+ ok: [localhost] => {
+ "msg": "30.336145277778"
+ }
+
+ TASK [Convert string to years (using 365.25 days == 1 year)] ******************************
+ ok: [localhost] => {
+ "msg": "1.096851471595"
+ }
+
+.. versionadded: 0.2.0
diff --git a/ansible_collections/community/general/docs/docsite/rst/filter_guide_working_with_unicode.rst b/ansible_collections/community/general/docs/docsite/rst/filter_guide_working_with_unicode.rst
new file mode 100644
index 000000000..2e5a67f8f
--- /dev/null
+++ b/ansible_collections/community/general/docs/docsite/rst/filter_guide_working_with_unicode.rst
@@ -0,0 +1,35 @@
+..
+ 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
+
+Working with Unicode
+---------------------
+
+`Unicode <https://unicode.org/main.html>`_ makes it possible to produce two strings which may be visually equivalent, but are comprised of distinctly different characters/character sequences. To address this ``Unicode`` defines `normalization forms <https://unicode.org/reports/tr15/>`_ which avoid these distinctions by choosing a unique character sequence for a given visual representation.
+
+You can use the ``community.general.unicode_normalize`` filter to normalize ``Unicode`` strings within your playbooks.
+
+.. code-block:: yaml+jinja
+
+ - name: Compare Unicode representations
+ debug:
+ msg: "{{ with_combining_character | community.general.unicode_normalize == without_combining_character }}"
+ vars:
+ with_combining_character: "{{ 'Mayagu\u0308ez' }}"
+ without_combining_character: Mayagüez
+
+This produces:
+
+.. code-block:: ansible-output
+
+ TASK [Compare Unicode representations] ********************************************************
+ ok: [localhost] => {
+ "msg": true
+ }
+
+The ``community.general.unicode_normalize`` filter accepts a keyword argument to select the ``Unicode`` form used to normalize the input string.
+
+:form: One of ``'NFC'`` (default), ``'NFD'``, ``'NFKC'``, or ``'NFKD'``. See the `Unicode reference <https://unicode.org/reports/tr15/>`_ for more information.
+
+.. versionadded:: 3.7.0
diff --git a/ansible_collections/community/general/docs/docsite/rst/filter_guide_working_with_versions.rst b/ansible_collections/community/general/docs/docsite/rst/filter_guide_working_with_versions.rst
new file mode 100644
index 000000000..2488427b7
--- /dev/null
+++ b/ansible_collections/community/general/docs/docsite/rst/filter_guide_working_with_versions.rst
@@ -0,0 +1,39 @@
+..
+ 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
+
+Working with versions
+---------------------
+
+If you need to sort a list of version numbers, the Jinja ``sort`` filter is problematic. Since it sorts lexicographically, ``2.10`` will come before ``2.9``. To treat version numbers correctly, you can use the ``version_sort`` filter:
+
+.. code-block:: yaml+jinja
+
+ - name: Sort list by version number
+ debug:
+ var: ansible_versions | community.general.version_sort
+ vars:
+ ansible_versions:
+ - '2.8.0'
+ - '2.11.0'
+ - '2.7.0'
+ - '2.10.0'
+ - '2.9.0'
+
+This produces:
+
+.. code-block:: ansible-output
+
+ TASK [Sort list by version number] ********************************************************
+ ok: [localhost] => {
+ "ansible_versions | community.general.version_sort": [
+ "2.7.0",
+ "2.8.0",
+ "2.9.0",
+ "2.10.0",
+ "2.11.0"
+ ]
+ }
+
+.. versionadded: 2.2.0
diff --git a/ansible_collections/community/general/docs/docsite/rst/test_guide.rst b/ansible_collections/community/general/docs/docsite/rst/test_guide.rst
new file mode 100644
index 000000000..b0b7885f9
--- /dev/null
+++ b/ansible_collections/community/general/docs/docsite/rst/test_guide.rst
@@ -0,0 +1,33 @@
+..
+ Copyright (c) Ansible Project
+ GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+ SPDX-License-Identifier: GPL-3.0-or-later
+
+.. _ansible_collections.community.general.docsite.test_guide:
+
+community.general Test (Plugin) Guide
+=====================================
+
+The :ref:`community.general collection <plugins_in_community.general>` offers currently one test plugin.
+
+.. contents:: Topics
+
+Feature Tests
+-------------
+
+The ``a_module`` test allows to check whether a given string refers to an existing module or action plugin. This can be useful in roles, which can use this to ensure that required modules are present ahead of time.
+
+.. code-block:: yaml+jinja
+
+ - name: Make sure that community.aws.route53 is available
+ assert:
+ that:
+ - >
+ 'community.aws.route53' is community.general.a_module
+
+ - name: Make sure that community.general.does_not_exist is not a module or action plugin
+ assert:
+ that:
+ - "'community.general.does_not_exist' is not community.general.a_module"
+
+.. versionadded:: 4.0.0