review pt 1
parent
792aa2731c
commit
595c9ee38f
|
@ -10,8 +10,8 @@ The Ansible ``ansible.utils`` collection includes a variety of plugins that aid
|
||||||
|
|
||||||
This collection has been tested against following Ansible versions: **>=2.9.10**.
|
This collection has been tested against following Ansible versions: **>=2.9.10**.
|
||||||
|
|
||||||
For collections that support Ansible 2.9, please ensure you update your `network_os` to use the
|
For collections that support Ansible 2.9, please ensure you update your `network_os` to use the
|
||||||
fully qualified collection name (for example, `cisco.ios.ios`).
|
fully qualified collection name (for example, `cisco.ios.ios`).
|
||||||
Plugins and modules within a collection may be tested with only specific Ansible versions.
|
Plugins and modules within a collection may be tested with only specific Ansible versions.
|
||||||
A collection may contain metadata that identifies these versions.
|
A collection may contain metadata that identifies these versions.
|
||||||
PEP440 is the schema used to describe the versions of Ansible.
|
PEP440 is the schema used to describe the versions of Ansible.
|
||||||
|
|
|
@ -1,5 +1,3 @@
|
||||||
---
|
---
|
||||||
minor_changes:
|
minor_changes:
|
||||||
- "'consolidate' filter plugin added."
|
- "'consolidate' filter plugin added."
|
||||||
trivial:
|
|
||||||
- Fix sanity issues and update black version.
|
|
||||||
|
|
|
@ -19,7 +19,7 @@ Synopsis
|
||||||
--------
|
--------
|
||||||
- This plugin presents collective structured data including all supplied facts grouping on common attributes mentioned.
|
- This plugin presents collective structured data including all supplied facts grouping on common attributes mentioned.
|
||||||
- All other boolean parameter defaults to False unless parameters is explicitly mentioned.
|
- All other boolean parameter defaults to False unless parameters is explicitly mentioned.
|
||||||
- Using the parameters below- ``data_source|ansible.utils.consolidate(fail_missing_match_key=False``))
|
- Using the parameters below- ``data_sources|ansible.utils.consolidate(fail_missing_match_key=False``))
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@ -39,7 +39,7 @@ Parameters
|
||||||
<tr>
|
<tr>
|
||||||
<td colspan="2">
|
<td colspan="2">
|
||||||
<div class="ansibleOptionAnchor" id="parameter-"></div>
|
<div class="ansibleOptionAnchor" id="parameter-"></div>
|
||||||
<b>data_source</b>
|
<b>data_sources</b>
|
||||||
<a class="ansibleOptionLink" href="#parameter-" title="Permalink to this option"></a>
|
<a class="ansibleOptionLink" href="#parameter-" title="Permalink to this option"></a>
|
||||||
<div style="font-size: small">
|
<div style="font-size: small">
|
||||||
<span style="color: purple">list</span>
|
<span style="color: purple">list</span>
|
||||||
|
@ -98,7 +98,7 @@ Parameters
|
||||||
<td class="elbow-placeholder"></td>
|
<td class="elbow-placeholder"></td>
|
||||||
<td colspan="1">
|
<td colspan="1">
|
||||||
<div class="ansibleOptionAnchor" id="parameter-"></div>
|
<div class="ansibleOptionAnchor" id="parameter-"></div>
|
||||||
<b>prefix</b>
|
<b>name</b>
|
||||||
<a class="ansibleOptionLink" href="#parameter-" title="Permalink to this option"></a>
|
<a class="ansibleOptionLink" href="#parameter-" title="Permalink to this option"></a>
|
||||||
<div style="font-size: small">
|
<div style="font-size: small">
|
||||||
<span style="color: purple">string</span>
|
<span style="color: purple">string</span>
|
||||||
|
@ -110,7 +110,7 @@ Parameters
|
||||||
<td>
|
<td>
|
||||||
</td>
|
</td>
|
||||||
<td>
|
<td>
|
||||||
<div>Specify the prefix with which the result set be created.</div>
|
<div>Specify the name with which the result set be created.</div>
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
|
|
||||||
|
@ -126,13 +126,13 @@ Parameters
|
||||||
<td>
|
<td>
|
||||||
<ul style="margin: 0; padding: 0"><b>Choices:</b>
|
<ul style="margin: 0; padding: 0"><b>Choices:</b>
|
||||||
<li>no</li>
|
<li>no</li>
|
||||||
<li>yes</li>
|
<li><div style="color: blue"><b>yes</b> ←</div></li>
|
||||||
</ul>
|
</ul>
|
||||||
</td>
|
</td>
|
||||||
<td>
|
<td>
|
||||||
</td>
|
</td>
|
||||||
<td>
|
<td>
|
||||||
<div>Fail if duplicate values for any key is found.</div>
|
<div>Fail if the match key's value exists more than once in a given data set.</div>
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
|
@ -147,7 +147,7 @@ Parameters
|
||||||
<td>
|
<td>
|
||||||
<ul style="margin: 0; padding: 0"><b>Choices:</b>
|
<ul style="margin: 0; padding: 0"><b>Choices:</b>
|
||||||
<li>no</li>
|
<li>no</li>
|
||||||
<li>yes</li>
|
<li><div style="color: blue"><b>yes</b> ←</div></li>
|
||||||
</ul>
|
</ul>
|
||||||
</td>
|
</td>
|
||||||
<td>
|
<td>
|
||||||
|
@ -168,13 +168,13 @@ Parameters
|
||||||
<td>
|
<td>
|
||||||
<ul style="margin: 0; padding: 0"><b>Choices:</b>
|
<ul style="margin: 0; padding: 0"><b>Choices:</b>
|
||||||
<li>no</li>
|
<li>no</li>
|
||||||
<li>yes</li>
|
<li><div style="color: blue"><b>yes</b> ←</div></li>
|
||||||
</ul>
|
</ul>
|
||||||
</td>
|
</td>
|
||||||
<td>
|
<td>
|
||||||
</td>
|
</td>
|
||||||
<td>
|
<td>
|
||||||
<div>Fail if a keys to match in not same accross all data sets.</div>
|
<div>Fail if the match key's value is not found in every data source.</div>
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
</table>
|
</table>
|
||||||
|
@ -280,25 +280,25 @@ Examples
|
||||||
tasks:
|
tasks:
|
||||||
- name: Build the facts collection
|
- name: Build the facts collection
|
||||||
set_fact:
|
set_fact:
|
||||||
data_source:
|
data_sources:
|
||||||
- data: "{{ interfaces }}"
|
- data: "{{ interfaces }}"
|
||||||
match_key: name
|
match_key: name
|
||||||
prefix: interfaces
|
name: interfaces
|
||||||
- data: "{{ l2_interfaces }}"
|
- data: "{{ l2_interfaces }}"
|
||||||
match_key: name
|
match_key: name
|
||||||
prefix: l2_interfaces
|
name: l2_interfaces
|
||||||
- data: "{{ l3_interfaces }}"
|
- data: "{{ l3_interfaces }}"
|
||||||
match_key: name
|
match_key: name
|
||||||
prefix: l3_interfaces
|
name: l3_interfaces
|
||||||
|
|
||||||
- name: Combine all the facts based on match_keys
|
- name: Combine all the facts based on match_keys
|
||||||
set_fact:
|
set_fact:
|
||||||
combined: "{{ data_source|ansible.utils.consolidate(fail_missing_match_value=False) }}"
|
combined: "{{ data_sources|ansible.utils.consolidate(fail_missing_match_value=False) }}"
|
||||||
|
|
||||||
##Output
|
##Output
|
||||||
# ok: [localhost] => {
|
# ok: [localhost] => {
|
||||||
# "ansible_facts": {
|
# "ansible_facts": {
|
||||||
# "data_source": [
|
# "data_sources": [
|
||||||
# {
|
# {
|
||||||
# "data": [
|
# "data": [
|
||||||
# {
|
# {
|
||||||
|
@ -344,7 +344,7 @@ Examples
|
||||||
# }
|
# }
|
||||||
# ],
|
# ],
|
||||||
# "match_key": "name",
|
# "match_key": "name",
|
||||||
# "prefix": "interfaces"
|
# "name": "interfaces"
|
||||||
# },
|
# },
|
||||||
# {
|
# {
|
||||||
# "data": [
|
# "data": [
|
||||||
|
@ -402,7 +402,7 @@ Examples
|
||||||
# }
|
# }
|
||||||
# ],
|
# ],
|
||||||
# "match_key": "name",
|
# "match_key": "name",
|
||||||
# "prefix": "l2_interfaces"
|
# "name": "l2_interfaces"
|
||||||
# },
|
# },
|
||||||
# {
|
# {
|
||||||
# "data": [
|
# "data": [
|
||||||
|
@ -428,7 +428,7 @@ Examples
|
||||||
# }
|
# }
|
||||||
# ],
|
# ],
|
||||||
# "match_key": "name",
|
# "match_key": "name",
|
||||||
# "prefix": "l3_interfaces"
|
# "name": "l3_interfaces"
|
||||||
# }
|
# }
|
||||||
# ]
|
# ]
|
||||||
# },
|
# },
|
||||||
|
@ -663,25 +663,25 @@ Examples
|
||||||
tasks:
|
tasks:
|
||||||
- name: Build the facts collection
|
- name: Build the facts collection
|
||||||
set_fact:
|
set_fact:
|
||||||
data_source:
|
data_sources:
|
||||||
- data: "{{ interfaces }}"
|
- data: "{{ interfaces }}"
|
||||||
match_key: name
|
match_key: name
|
||||||
prefix: interfaces
|
name: interfaces
|
||||||
- data: "{{ l2_interfaces }}"
|
- data: "{{ l2_interfaces }}"
|
||||||
match_key: name
|
match_key: name
|
||||||
prefix: l2_interfaces
|
name: l2_interfaces
|
||||||
- data: "{{ l3_interfaces }}"
|
- data: "{{ l3_interfaces }}"
|
||||||
match_key: name
|
match_key: name
|
||||||
prefix: l3_interfaces
|
name: l3_interfaces
|
||||||
|
|
||||||
- name: Combine all the facts based on match_keys
|
- name: Combine all the facts based on match_keys
|
||||||
set_fact:
|
set_fact:
|
||||||
combined: "{{ data_source|ansible.utils.consolidate(fail_missing_match_value=True) }}"
|
combined: "{{ data_sources|ansible.utils.consolidate(fail_missing_match_value=True) }}"
|
||||||
|
|
||||||
##Output
|
##Output
|
||||||
# ok: [localhost] => {
|
# ok: [localhost] => {
|
||||||
# "ansible_facts": {
|
# "ansible_facts": {
|
||||||
# "data_source": [
|
# "data_sources": [
|
||||||
# {
|
# {
|
||||||
# "data": [
|
# "data": [
|
||||||
# {
|
# {
|
||||||
|
@ -727,7 +727,7 @@ Examples
|
||||||
# }
|
# }
|
||||||
# ],
|
# ],
|
||||||
# "match_key": "name",
|
# "match_key": "name",
|
||||||
# "prefix": "interfaces"
|
# "name": "interfaces"
|
||||||
# },
|
# },
|
||||||
# {
|
# {
|
||||||
# "data": [
|
# "data": [
|
||||||
|
@ -785,7 +785,7 @@ Examples
|
||||||
# }
|
# }
|
||||||
# ],
|
# ],
|
||||||
# "match_key": "name",
|
# "match_key": "name",
|
||||||
# "prefix": "l2_interfaces"
|
# "name": "l2_interfaces"
|
||||||
# },
|
# },
|
||||||
# {
|
# {
|
||||||
# "data": [
|
# "data": [
|
||||||
|
@ -811,7 +811,7 @@ Examples
|
||||||
# }
|
# }
|
||||||
# ],
|
# ],
|
||||||
# "match_key": "name",
|
# "match_key": "name",
|
||||||
# "prefix": "l3_interfaces"
|
# "name": "l3_interfaces"
|
||||||
# }
|
# }
|
||||||
# ]
|
# ]
|
||||||
# },
|
# },
|
||||||
|
@ -916,25 +916,25 @@ Examples
|
||||||
tasks:
|
tasks:
|
||||||
- name: Build the facts collection
|
- name: Build the facts collection
|
||||||
set_fact:
|
set_fact:
|
||||||
data_source:
|
data_sources:
|
||||||
- data: "{{ interfaces }}"
|
- data: "{{ interfaces }}"
|
||||||
match_key: name
|
match_key: name
|
||||||
prefix: interfaces
|
name: interfaces
|
||||||
- data: "{{ l2_interfaces }}"
|
- data: "{{ l2_interfaces }}"
|
||||||
match_key: name
|
match_key: name
|
||||||
prefix: l2_interfaces
|
name: l2_interfaces
|
||||||
- data: "{{ l3_interfaces }}"
|
- data: "{{ l3_interfaces }}"
|
||||||
match_key: name
|
match_key: name
|
||||||
prefix: l3_interfaces
|
name: l3_interfaces
|
||||||
|
|
||||||
- name: Combine all the facts based on match_keys
|
- name: Combine all the facts based on match_keys
|
||||||
set_fact:
|
set_fact:
|
||||||
combined: "{{ data_source|ansible.utils.consolidate(fail_missing_match_key=True) }}"
|
combined: "{{ data_sources|ansible.utils.consolidate(fail_missing_match_key=True) }}"
|
||||||
|
|
||||||
##Output
|
##Output
|
||||||
# ok: [localhost] => {
|
# ok: [localhost] => {
|
||||||
# "ansible_facts": {
|
# "ansible_facts": {
|
||||||
# "data_source": [
|
# "data_sources": [
|
||||||
# {
|
# {
|
||||||
# "data": [
|
# "data": [
|
||||||
# {
|
# {
|
||||||
|
@ -980,7 +980,7 @@ Examples
|
||||||
# }
|
# }
|
||||||
# ],
|
# ],
|
||||||
# "match_key": "name",
|
# "match_key": "name",
|
||||||
# "prefix": "interfaces"
|
# "name": "interfaces"
|
||||||
# },
|
# },
|
||||||
# {
|
# {
|
||||||
# "data": [
|
# "data": [
|
||||||
|
@ -1038,7 +1038,7 @@ Examples
|
||||||
# }
|
# }
|
||||||
# ],
|
# ],
|
||||||
# "match_key": "name",
|
# "match_key": "name",
|
||||||
# "prefix": "l2_interfaces"
|
# "name": "l2_interfaces"
|
||||||
# },
|
# },
|
||||||
# {
|
# {
|
||||||
# "data": [
|
# "data": [
|
||||||
|
@ -1064,7 +1064,7 @@ Examples
|
||||||
# }
|
# }
|
||||||
# ],
|
# ],
|
||||||
# "match_key": "name",
|
# "match_key": "name",
|
||||||
# "prefix": "l3_interfaces"
|
# "name": "l3_interfaces"
|
||||||
# }
|
# }
|
||||||
# ]
|
# ]
|
||||||
# },
|
# },
|
||||||
|
@ -1173,25 +1173,25 @@ Examples
|
||||||
tasks:
|
tasks:
|
||||||
- name: Build the facts collection
|
- name: Build the facts collection
|
||||||
set_fact:
|
set_fact:
|
||||||
data_source:
|
data_sources:
|
||||||
- data: "{{ interfaces }}"
|
- data: "{{ interfaces }}"
|
||||||
match_key: name
|
match_key: name
|
||||||
prefix: interfaces
|
name: interfaces
|
||||||
- data: "{{ l2_interfaces }}"
|
- data: "{{ l2_interfaces }}"
|
||||||
match_key: name
|
match_key: name
|
||||||
prefix: l2_interfaces
|
name: l2_interfaces
|
||||||
- data: "{{ l3_interfaces }}"
|
- data: "{{ l3_interfaces }}"
|
||||||
match_key: name
|
match_key: name
|
||||||
prefix: l3_interfaces
|
name: l3_interfaces
|
||||||
|
|
||||||
- name: Combine all the facts based on match_keys
|
- name: Combine all the facts based on match_keys
|
||||||
set_fact:
|
set_fact:
|
||||||
combined: "{{ data_source|ansible.utils.consolidate(fail_duplicate=True) }}"
|
combined: "{{ data_sources|ansible.utils.consolidate(fail_duplicate=True) }}"
|
||||||
|
|
||||||
##Output
|
##Output
|
||||||
# ok: [localhost] => {
|
# ok: [localhost] => {
|
||||||
# "ansible_facts": {
|
# "ansible_facts": {
|
||||||
# "data_source": [
|
# "data_sources": [
|
||||||
# {
|
# {
|
||||||
# "data": [
|
# "data": [
|
||||||
# {
|
# {
|
||||||
|
@ -1237,7 +1237,7 @@ Examples
|
||||||
# }
|
# }
|
||||||
# ],
|
# ],
|
||||||
# "match_key": "name",
|
# "match_key": "name",
|
||||||
# "prefix": "interfaces"
|
# "name": "interfaces"
|
||||||
# },
|
# },
|
||||||
# {
|
# {
|
||||||
# "data": [
|
# "data": [
|
||||||
|
@ -1298,7 +1298,7 @@ Examples
|
||||||
# }
|
# }
|
||||||
# ],
|
# ],
|
||||||
# "match_key": "name",
|
# "match_key": "name",
|
||||||
# "prefix": "l2_interfaces"
|
# "name": "l2_interfaces"
|
||||||
# },
|
# },
|
||||||
# {
|
# {
|
||||||
# "data": [
|
# "data": [
|
||||||
|
@ -1324,7 +1324,7 @@ Examples
|
||||||
# }
|
# }
|
||||||
# ],
|
# ],
|
||||||
# "match_key": "name",
|
# "match_key": "name",
|
||||||
# "prefix": "l3_interfaces"
|
# "name": "l3_interfaces"
|
||||||
# }
|
# }
|
||||||
# ]
|
# ]
|
||||||
# },
|
# },
|
||||||
|
|
|
@ -20,9 +20,9 @@ DOCUMENTATION = """
|
||||||
description:
|
description:
|
||||||
- This plugin presents collective structured data including all supplied facts grouping on common attributes mentioned.
|
- This plugin presents collective structured data including all supplied facts grouping on common attributes mentioned.
|
||||||
- All other boolean parameter defaults to False unless parameters is explicitly mentioned.
|
- All other boolean parameter defaults to False unless parameters is explicitly mentioned.
|
||||||
- Using the parameters below- C(data_source|ansible.utils.consolidate(fail_missing_match_key=False)))
|
- Using the parameters below- C(data_sources|ansible.utils.consolidate(fail_missing_match_key=False)))
|
||||||
options:
|
options:
|
||||||
data_source:
|
data_sources:
|
||||||
description:
|
description:
|
||||||
- This option represents a list of dictionaries to perform the operation on.
|
- This option represents a list of dictionaries to perform the operation on.
|
||||||
- For example C(facts_source|ansible.utils.consolidate(fail_missing_match_key=False))), in this case C(facts_source) represents this option.
|
- For example C(facts_source|ansible.utils.consolidate(fail_missing_match_key=False))), in this case C(facts_source) represents this option.
|
||||||
|
@ -38,19 +38,22 @@ DOCUMENTATION = """
|
||||||
description: Specify key to match on.
|
description: Specify key to match on.
|
||||||
type: str
|
type: str
|
||||||
required: True
|
required: True
|
||||||
prefix:
|
name:
|
||||||
description: Specify the prefix with which the result set be created.
|
description: Specify the name with which the result set be created.
|
||||||
type: str
|
type: str
|
||||||
required: True
|
required: True
|
||||||
fail_missing_match_key:
|
fail_missing_match_key:
|
||||||
description: Fail if match_key is not found in a specific data set.
|
description: Fail if match_key is not found in a specific data set.
|
||||||
type: bool
|
type: bool
|
||||||
|
default: True
|
||||||
fail_missing_match_value:
|
fail_missing_match_value:
|
||||||
description: Fail if a keys to match in not same accross all data sets.
|
description: Fail if the match key's value is not found in every data source.
|
||||||
type: bool
|
type: bool
|
||||||
|
default: True
|
||||||
fail_duplicate:
|
fail_duplicate:
|
||||||
description: Fail if duplicate values for any key is found.
|
description: Fail if the match key's value exists more than once in a given data set.
|
||||||
type: bool
|
type: bool
|
||||||
|
default: True
|
||||||
"""
|
"""
|
||||||
|
|
||||||
EXAMPLES = r"""
|
EXAMPLES = r"""
|
||||||
|
@ -147,25 +150,25 @@ vars_files:
|
||||||
tasks:
|
tasks:
|
||||||
- name: Build the facts collection
|
- name: Build the facts collection
|
||||||
set_fact:
|
set_fact:
|
||||||
data_source:
|
data_sources:
|
||||||
- data: "{{ interfaces }}"
|
- data: "{{ interfaces }}"
|
||||||
match_key: name
|
match_key: name
|
||||||
prefix: interfaces
|
name: interfaces
|
||||||
- data: "{{ l2_interfaces }}"
|
- data: "{{ l2_interfaces }}"
|
||||||
match_key: name
|
match_key: name
|
||||||
prefix: l2_interfaces
|
name: l2_interfaces
|
||||||
- data: "{{ l3_interfaces }}"
|
- data: "{{ l3_interfaces }}"
|
||||||
match_key: name
|
match_key: name
|
||||||
prefix: l3_interfaces
|
name: l3_interfaces
|
||||||
|
|
||||||
- name: Combine all the facts based on match_keys
|
- name: Combine all the facts based on match_keys
|
||||||
set_fact:
|
set_fact:
|
||||||
combined: "{{ data_source|ansible.utils.consolidate(fail_missing_match_value=False) }}"
|
combined: "{{ data_sources|ansible.utils.consolidate(fail_missing_match_value=False) }}"
|
||||||
|
|
||||||
##Output
|
##Output
|
||||||
# ok: [localhost] => {
|
# ok: [localhost] => {
|
||||||
# "ansible_facts": {
|
# "ansible_facts": {
|
||||||
# "data_source": [
|
# "data_sources": [
|
||||||
# {
|
# {
|
||||||
# "data": [
|
# "data": [
|
||||||
# {
|
# {
|
||||||
|
@ -211,7 +214,7 @@ tasks:
|
||||||
# }
|
# }
|
||||||
# ],
|
# ],
|
||||||
# "match_key": "name",
|
# "match_key": "name",
|
||||||
# "prefix": "interfaces"
|
# "name": "interfaces"
|
||||||
# },
|
# },
|
||||||
# {
|
# {
|
||||||
# "data": [
|
# "data": [
|
||||||
|
@ -269,7 +272,7 @@ tasks:
|
||||||
# }
|
# }
|
||||||
# ],
|
# ],
|
||||||
# "match_key": "name",
|
# "match_key": "name",
|
||||||
# "prefix": "l2_interfaces"
|
# "name": "l2_interfaces"
|
||||||
# },
|
# },
|
||||||
# {
|
# {
|
||||||
# "data": [
|
# "data": [
|
||||||
|
@ -295,7 +298,7 @@ tasks:
|
||||||
# }
|
# }
|
||||||
# ],
|
# ],
|
||||||
# "match_key": "name",
|
# "match_key": "name",
|
||||||
# "prefix": "l3_interfaces"
|
# "name": "l3_interfaces"
|
||||||
# }
|
# }
|
||||||
# ]
|
# ]
|
||||||
# },
|
# },
|
||||||
|
@ -530,25 +533,25 @@ vars_files:
|
||||||
tasks:
|
tasks:
|
||||||
- name: Build the facts collection
|
- name: Build the facts collection
|
||||||
set_fact:
|
set_fact:
|
||||||
data_source:
|
data_sources:
|
||||||
- data: "{{ interfaces }}"
|
- data: "{{ interfaces }}"
|
||||||
match_key: name
|
match_key: name
|
||||||
prefix: interfaces
|
name: interfaces
|
||||||
- data: "{{ l2_interfaces }}"
|
- data: "{{ l2_interfaces }}"
|
||||||
match_key: name
|
match_key: name
|
||||||
prefix: l2_interfaces
|
name: l2_interfaces
|
||||||
- data: "{{ l3_interfaces }}"
|
- data: "{{ l3_interfaces }}"
|
||||||
match_key: name
|
match_key: name
|
||||||
prefix: l3_interfaces
|
name: l3_interfaces
|
||||||
|
|
||||||
- name: Combine all the facts based on match_keys
|
- name: Combine all the facts based on match_keys
|
||||||
set_fact:
|
set_fact:
|
||||||
combined: "{{ data_source|ansible.utils.consolidate(fail_missing_match_value=True) }}"
|
combined: "{{ data_sources|ansible.utils.consolidate(fail_missing_match_value=True) }}"
|
||||||
|
|
||||||
##Output
|
##Output
|
||||||
# ok: [localhost] => {
|
# ok: [localhost] => {
|
||||||
# "ansible_facts": {
|
# "ansible_facts": {
|
||||||
# "data_source": [
|
# "data_sources": [
|
||||||
# {
|
# {
|
||||||
# "data": [
|
# "data": [
|
||||||
# {
|
# {
|
||||||
|
@ -594,7 +597,7 @@ tasks:
|
||||||
# }
|
# }
|
||||||
# ],
|
# ],
|
||||||
# "match_key": "name",
|
# "match_key": "name",
|
||||||
# "prefix": "interfaces"
|
# "name": "interfaces"
|
||||||
# },
|
# },
|
||||||
# {
|
# {
|
||||||
# "data": [
|
# "data": [
|
||||||
|
@ -652,7 +655,7 @@ tasks:
|
||||||
# }
|
# }
|
||||||
# ],
|
# ],
|
||||||
# "match_key": "name",
|
# "match_key": "name",
|
||||||
# "prefix": "l2_interfaces"
|
# "name": "l2_interfaces"
|
||||||
# },
|
# },
|
||||||
# {
|
# {
|
||||||
# "data": [
|
# "data": [
|
||||||
|
@ -678,7 +681,7 @@ tasks:
|
||||||
# }
|
# }
|
||||||
# ],
|
# ],
|
||||||
# "match_key": "name",
|
# "match_key": "name",
|
||||||
# "prefix": "l3_interfaces"
|
# "name": "l3_interfaces"
|
||||||
# }
|
# }
|
||||||
# ]
|
# ]
|
||||||
# },
|
# },
|
||||||
|
@ -783,25 +786,25 @@ vars_files:
|
||||||
tasks:
|
tasks:
|
||||||
- name: Build the facts collection
|
- name: Build the facts collection
|
||||||
set_fact:
|
set_fact:
|
||||||
data_source:
|
data_sources:
|
||||||
- data: "{{ interfaces }}"
|
- data: "{{ interfaces }}"
|
||||||
match_key: name
|
match_key: name
|
||||||
prefix: interfaces
|
name: interfaces
|
||||||
- data: "{{ l2_interfaces }}"
|
- data: "{{ l2_interfaces }}"
|
||||||
match_key: name
|
match_key: name
|
||||||
prefix: l2_interfaces
|
name: l2_interfaces
|
||||||
- data: "{{ l3_interfaces }}"
|
- data: "{{ l3_interfaces }}"
|
||||||
match_key: name
|
match_key: name
|
||||||
prefix: l3_interfaces
|
name: l3_interfaces
|
||||||
|
|
||||||
- name: Combine all the facts based on match_keys
|
- name: Combine all the facts based on match_keys
|
||||||
set_fact:
|
set_fact:
|
||||||
combined: "{{ data_source|ansible.utils.consolidate(fail_missing_match_key=True) }}"
|
combined: "{{ data_sources|ansible.utils.consolidate(fail_missing_match_key=True) }}"
|
||||||
|
|
||||||
##Output
|
##Output
|
||||||
# ok: [localhost] => {
|
# ok: [localhost] => {
|
||||||
# "ansible_facts": {
|
# "ansible_facts": {
|
||||||
# "data_source": [
|
# "data_sources": [
|
||||||
# {
|
# {
|
||||||
# "data": [
|
# "data": [
|
||||||
# {
|
# {
|
||||||
|
@ -847,7 +850,7 @@ tasks:
|
||||||
# }
|
# }
|
||||||
# ],
|
# ],
|
||||||
# "match_key": "name",
|
# "match_key": "name",
|
||||||
# "prefix": "interfaces"
|
# "name": "interfaces"
|
||||||
# },
|
# },
|
||||||
# {
|
# {
|
||||||
# "data": [
|
# "data": [
|
||||||
|
@ -905,7 +908,7 @@ tasks:
|
||||||
# }
|
# }
|
||||||
# ],
|
# ],
|
||||||
# "match_key": "name",
|
# "match_key": "name",
|
||||||
# "prefix": "l2_interfaces"
|
# "name": "l2_interfaces"
|
||||||
# },
|
# },
|
||||||
# {
|
# {
|
||||||
# "data": [
|
# "data": [
|
||||||
|
@ -931,7 +934,7 @@ tasks:
|
||||||
# }
|
# }
|
||||||
# ],
|
# ],
|
||||||
# "match_key": "name",
|
# "match_key": "name",
|
||||||
# "prefix": "l3_interfaces"
|
# "name": "l3_interfaces"
|
||||||
# }
|
# }
|
||||||
# ]
|
# ]
|
||||||
# },
|
# },
|
||||||
|
@ -1040,25 +1043,25 @@ vars_files:
|
||||||
tasks:
|
tasks:
|
||||||
- name: Build the facts collection
|
- name: Build the facts collection
|
||||||
set_fact:
|
set_fact:
|
||||||
data_source:
|
data_sources:
|
||||||
- data: "{{ interfaces }}"
|
- data: "{{ interfaces }}"
|
||||||
match_key: name
|
match_key: name
|
||||||
prefix: interfaces
|
name: interfaces
|
||||||
- data: "{{ l2_interfaces }}"
|
- data: "{{ l2_interfaces }}"
|
||||||
match_key: name
|
match_key: name
|
||||||
prefix: l2_interfaces
|
name: l2_interfaces
|
||||||
- data: "{{ l3_interfaces }}"
|
- data: "{{ l3_interfaces }}"
|
||||||
match_key: name
|
match_key: name
|
||||||
prefix: l3_interfaces
|
name: l3_interfaces
|
||||||
|
|
||||||
- name: Combine all the facts based on match_keys
|
- name: Combine all the facts based on match_keys
|
||||||
set_fact:
|
set_fact:
|
||||||
combined: "{{ data_source|ansible.utils.consolidate(fail_duplicate=True) }}"
|
combined: "{{ data_sources|ansible.utils.consolidate(fail_duplicate=True) }}"
|
||||||
|
|
||||||
##Output
|
##Output
|
||||||
# ok: [localhost] => {
|
# ok: [localhost] => {
|
||||||
# "ansible_facts": {
|
# "ansible_facts": {
|
||||||
# "data_source": [
|
# "data_sources": [
|
||||||
# {
|
# {
|
||||||
# "data": [
|
# "data": [
|
||||||
# {
|
# {
|
||||||
|
@ -1104,7 +1107,7 @@ tasks:
|
||||||
# }
|
# }
|
||||||
# ],
|
# ],
|
||||||
# "match_key": "name",
|
# "match_key": "name",
|
||||||
# "prefix": "interfaces"
|
# "name": "interfaces"
|
||||||
# },
|
# },
|
||||||
# {
|
# {
|
||||||
# "data": [
|
# "data": [
|
||||||
|
@ -1165,7 +1168,7 @@ tasks:
|
||||||
# }
|
# }
|
||||||
# ],
|
# ],
|
||||||
# "match_key": "name",
|
# "match_key": "name",
|
||||||
# "prefix": "l2_interfaces"
|
# "name": "l2_interfaces"
|
||||||
# },
|
# },
|
||||||
# {
|
# {
|
||||||
# "data": [
|
# "data": [
|
||||||
|
@ -1191,7 +1194,7 @@ tasks:
|
||||||
# }
|
# }
|
||||||
# ],
|
# ],
|
||||||
# "match_key": "name",
|
# "match_key": "name",
|
||||||
# "prefix": "l3_interfaces"
|
# "name": "l3_interfaces"
|
||||||
# }
|
# }
|
||||||
# ]
|
# ]
|
||||||
# },
|
# },
|
||||||
|
@ -1224,7 +1227,7 @@ def _consolidate(*args, **kwargs):
|
||||||
"""Consolidate facts together on common attributes"""
|
"""Consolidate facts together on common attributes"""
|
||||||
|
|
||||||
keys = [
|
keys = [
|
||||||
"data_source",
|
"data_sources",
|
||||||
"fail_missing_match_key",
|
"fail_missing_match_key",
|
||||||
"fail_missing_match_value",
|
"fail_missing_match_value",
|
||||||
"fail_duplicate",
|
"fail_duplicate",
|
||||||
|
|
|
@ -33,7 +33,7 @@ def _raise_error(filter, msg):
|
||||||
|
|
||||||
|
|
||||||
def fail_on_filter(validator_func):
|
def fail_on_filter(validator_func):
|
||||||
"""decorator to fail on supplied filters
|
"""Decorator to fail on supplied filters
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
validator_func (func): Function that generates failure messages
|
validator_func (func): Function that generates failure messages
|
||||||
|
@ -43,7 +43,11 @@ def fail_on_filter(validator_func):
|
||||||
"""
|
"""
|
||||||
|
|
||||||
def update_err(*args, **kwargs):
|
def update_err(*args, **kwargs):
|
||||||
|
"""Filters return value or raises error as per supplied parameters
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
any: Return value to the function call
|
||||||
|
"""
|
||||||
res, err = validator_func(*args, **kwargs)
|
res, err = validator_func(*args, **kwargs)
|
||||||
if err.get("match_key_err"):
|
if err.get("match_key_err"):
|
||||||
_raise_error(
|
_raise_error(
|
||||||
|
@ -64,8 +68,8 @@ def fail_on_filter(validator_func):
|
||||||
def check_missing_match_key_duplicate(
|
def check_missing_match_key_duplicate(
|
||||||
data_sources, fail_missing_match_key, fail_duplicate
|
data_sources, fail_missing_match_key, fail_duplicate
|
||||||
):
|
):
|
||||||
"""Checks if the match_key specified is present in all the supplied data,
|
"""Check if the match_key specified is present in all the supplied data,
|
||||||
also checks for duplicate data accross all the data sources
|
also check for duplicate data accross all the data sources
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
data_sources (list): list of dicts as data sources
|
data_sources (list): list of dicts as data sources
|
||||||
|
@ -75,11 +79,11 @@ def check_missing_match_key_duplicate(
|
||||||
list: list of unique keys based on specified match_keys
|
list: list of unique keys based on specified match_keys
|
||||||
"""
|
"""
|
||||||
results, errors_match_key, errors_duplicate = [], [], []
|
results, errors_match_key, errors_duplicate = [], [], []
|
||||||
for ds_idx, data_source in enumerate(data_sources):
|
for ds_idx, data_source in enumerate(data_sources, start=1):
|
||||||
match_key = data_source["match_key"]
|
match_key = data_source["match_key"]
|
||||||
ds_values = []
|
ds_values = []
|
||||||
|
|
||||||
for dd_idx, data_dict in enumerate(data_source["data"]):
|
for dd_idx, data_dict in enumerate(data_source["data"], start=1):
|
||||||
try:
|
try:
|
||||||
ds_values.append(data_dict[match_key])
|
ds_values.append(data_dict[match_key])
|
||||||
except KeyError:
|
except KeyError:
|
||||||
|
@ -117,7 +121,7 @@ def check_missing_match_values(matched_keys, fail_missing_match_value):
|
||||||
errors_match_values = []
|
errors_match_values = []
|
||||||
all_values = set(itertools.chain.from_iterable(matched_keys))
|
all_values = set(itertools.chain.from_iterable(matched_keys))
|
||||||
if fail_missing_match_value:
|
if fail_missing_match_value:
|
||||||
for ds_idx, ds_values in enumerate(matched_keys):
|
for ds_idx, ds_values in enumerate(matched_keys, start=1):
|
||||||
missing_match = all_values - ds_values
|
missing_match = all_values - ds_values
|
||||||
if missing_match:
|
if missing_match:
|
||||||
m_matches = ", ".join(missing_match)
|
m_matches = ", ".join(missing_match)
|
||||||
|
@ -143,7 +147,7 @@ def consolidate_facts(data_sources, all_values):
|
||||||
consolidated_facts = {}
|
consolidated_facts = {}
|
||||||
for data_source in data_sources:
|
for data_source in data_sources:
|
||||||
match_key = data_source["match_key"]
|
match_key = data_source["match_key"]
|
||||||
source = data_source["prefix"]
|
source = data_source["name"]
|
||||||
data_dict = {
|
data_dict = {
|
||||||
d[match_key]: d for d in data_source["data"] if match_key in d
|
d[match_key]: d for d in data_source["data"] if match_key in d
|
||||||
}
|
}
|
||||||
|
@ -155,7 +159,7 @@ def consolidate_facts(data_sources, all_values):
|
||||||
|
|
||||||
|
|
||||||
def consolidate(
|
def consolidate(
|
||||||
data_source,
|
data_sources,
|
||||||
fail_missing_match_key=False,
|
fail_missing_match_key=False,
|
||||||
fail_missing_match_value=False,
|
fail_missing_match_value=False,
|
||||||
fail_duplicate=False,
|
fail_duplicate=False,
|
||||||
|
@ -173,8 +177,8 @@ def consolidate(
|
||||||
"""
|
"""
|
||||||
|
|
||||||
key_sets = check_missing_match_key_duplicate(
|
key_sets = check_missing_match_key_duplicate(
|
||||||
data_source, fail_missing_match_key, fail_duplicate
|
data_sources, fail_missing_match_key, fail_duplicate
|
||||||
)
|
)
|
||||||
key_vals = check_missing_match_values(key_sets, fail_missing_match_value)
|
key_vals = check_missing_match_values(key_sets, fail_missing_match_value)
|
||||||
consolidated_facts = consolidate_facts(data_source, key_vals)
|
consolidated_facts = consolidate_facts(data_sources, key_vals)
|
||||||
return consolidated_facts
|
return consolidated_facts
|
||||||
|
|
|
@ -1,14 +1,14 @@
|
||||||
---
|
---
|
||||||
- name: Build the data structure
|
- name: Build the data structure
|
||||||
ansible.builtin.set_fact:
|
ansible.builtin.set_fact:
|
||||||
data_source:
|
data_sources:
|
||||||
- data:
|
- data:
|
||||||
[
|
[
|
||||||
{ "name": "GigabitEthernet0/1" },
|
{ "name": "GigabitEthernet0/1" },
|
||||||
{ "name": "GigabitEthernet0/2" },
|
{ "name": "GigabitEthernet0/2" },
|
||||||
]
|
]
|
||||||
match_key: name
|
match_key: name
|
||||||
prefix: acl_interfaces
|
name: acl_interfaces
|
||||||
- data:
|
- data:
|
||||||
[
|
[
|
||||||
{
|
{
|
||||||
|
@ -23,11 +23,11 @@
|
||||||
},
|
},
|
||||||
]
|
]
|
||||||
match_key: name
|
match_key: name
|
||||||
prefix: interfaces
|
name: interfaces
|
||||||
|
|
||||||
- name: Combine all the dictionaries based on match_keys
|
- name: Combine all the dictionaries based on match_keys
|
||||||
ansible.builtin.set_fact:
|
ansible.builtin.set_fact:
|
||||||
combined: "{{ data_source|ansible.utils.consolidate(fail_missing_match_value=False) }}"
|
combined: "{{ data_sources|ansible.utils.consolidate(fail_missing_match_value=False) }}"
|
||||||
|
|
||||||
- name: Assert result dicts
|
- name: Assert result dicts
|
||||||
assert:
|
assert:
|
||||||
|
|
|
@ -19,7 +19,7 @@ class TestConsolidate(unittest.TestCase):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
def test_consolidate_plugin(self):
|
def test_consolidate_plugin(self):
|
||||||
data_source = [
|
data_sources = [
|
||||||
{
|
{
|
||||||
"data": [
|
"data": [
|
||||||
{
|
{
|
||||||
|
@ -60,7 +60,7 @@ class TestConsolidate(unittest.TestCase):
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
"match_key": "name",
|
"match_key": "name",
|
||||||
"prefix": "interfaces",
|
"name": "interfaces",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"data": [
|
"data": [
|
||||||
|
@ -116,7 +116,7 @@ class TestConsolidate(unittest.TestCase):
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
"match_key": "name",
|
"match_key": "name",
|
||||||
"prefix": "l2_interfaces",
|
"name": "l2_interfaces",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"data": [
|
"data": [
|
||||||
|
@ -130,7 +130,7 @@ class TestConsolidate(unittest.TestCase):
|
||||||
{"name": "Loopback999"},
|
{"name": "Loopback999"},
|
||||||
],
|
],
|
||||||
"match_key": "name",
|
"match_key": "name",
|
||||||
"prefix": "l3_interfaces",
|
"name": "l3_interfaces",
|
||||||
},
|
},
|
||||||
]
|
]
|
||||||
|
|
||||||
|
@ -244,13 +244,13 @@ class TestConsolidate(unittest.TestCase):
|
||||||
"l3_interfaces": {"name": "Loopback999"},
|
"l3_interfaces": {"name": "Loopback999"},
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
args = ["", data_source]
|
args = ["", data_sources]
|
||||||
|
|
||||||
result = _consolidate(*args)
|
result = _consolidate(*args)
|
||||||
self.assertEqual(result, output)
|
self.assertEqual(result, output)
|
||||||
|
|
||||||
def test_fail_missing_match_key(self):
|
def test_fail_missing_match_key(self):
|
||||||
data_source = [
|
data_sources = [
|
||||||
{
|
{
|
||||||
"data": [
|
"data": [
|
||||||
{
|
{
|
||||||
|
@ -291,7 +291,7 @@ class TestConsolidate(unittest.TestCase):
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
"match_key": "name",
|
"match_key": "name",
|
||||||
"prefix": "interfaces",
|
"name": "interfaces",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"data": [
|
"data": [
|
||||||
|
@ -347,7 +347,7 @@ class TestConsolidate(unittest.TestCase):
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
"match_key": "name",
|
"match_key": "name",
|
||||||
"prefix": "l2_interfaces",
|
"name": "l2_interfaces",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"data": [
|
"data": [
|
||||||
|
@ -361,21 +361,21 @@ class TestConsolidate(unittest.TestCase):
|
||||||
{"name": "Loopback999"},
|
{"name": "Loopback999"},
|
||||||
],
|
],
|
||||||
"match_key": "name",
|
"match_key": "name",
|
||||||
"prefix": "l3_interfaces",
|
"name": "l3_interfaces",
|
||||||
},
|
},
|
||||||
]
|
]
|
||||||
|
|
||||||
fail_missing_match_key = True
|
fail_missing_match_key = True
|
||||||
args = ["", data_source, fail_missing_match_key]
|
args = ["", data_sources, fail_missing_match_key]
|
||||||
with self.assertRaises(AnsibleFilterError) as error:
|
with self.assertRaises(AnsibleFilterError) as error:
|
||||||
_consolidate(*args)
|
_consolidate(*args)
|
||||||
self.assertIn(
|
self.assertIn(
|
||||||
"Error when using plugin 'consolidate': 'fail_missing_match_key' reported Missing match key 'name' in data source 2 in list entry 0",
|
"Error when using plugin 'consolidate': 'fail_missing_match_key' reported Missing match key 'name' in data source 3 in list entry 1",
|
||||||
str(error.exception),
|
str(error.exception),
|
||||||
)
|
)
|
||||||
|
|
||||||
def test_fail_missing_match_value(self):
|
def test_fail_missing_match_value(self):
|
||||||
data_source = [
|
data_sources = [
|
||||||
{
|
{
|
||||||
"data": [
|
"data": [
|
||||||
{
|
{
|
||||||
|
@ -416,7 +416,7 @@ class TestConsolidate(unittest.TestCase):
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
"match_key": "name",
|
"match_key": "name",
|
||||||
"prefix": "interfaces",
|
"name": "interfaces",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"data": [
|
"data": [
|
||||||
|
@ -472,7 +472,7 @@ class TestConsolidate(unittest.TestCase):
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
"match_key": "name",
|
"match_key": "name",
|
||||||
"prefix": "l2_interfaces",
|
"name": "l2_interfaces",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"data": [
|
"data": [
|
||||||
|
@ -490,7 +490,7 @@ class TestConsolidate(unittest.TestCase):
|
||||||
{"name": "Loopback999"},
|
{"name": "Loopback999"},
|
||||||
],
|
],
|
||||||
"match_key": "name",
|
"match_key": "name",
|
||||||
"prefix": "l3_interfaces",
|
"name": "l3_interfaces",
|
||||||
},
|
},
|
||||||
]
|
]
|
||||||
|
|
||||||
|
@ -499,7 +499,7 @@ class TestConsolidate(unittest.TestCase):
|
||||||
fail_duplicate = True
|
fail_duplicate = True
|
||||||
args = [
|
args = [
|
||||||
"",
|
"",
|
||||||
data_source,
|
data_sources,
|
||||||
fail_missing_match_key,
|
fail_missing_match_key,
|
||||||
fail_missing_match_value,
|
fail_missing_match_value,
|
||||||
fail_duplicate,
|
fail_duplicate,
|
||||||
|
@ -507,6 +507,6 @@ class TestConsolidate(unittest.TestCase):
|
||||||
with self.assertRaises(AnsibleFilterError) as error:
|
with self.assertRaises(AnsibleFilterError) as error:
|
||||||
_consolidate(*args)
|
_consolidate(*args)
|
||||||
self.assertIn(
|
self.assertIn(
|
||||||
"Error when using plugin 'consolidate': 'fail_duplicate' reported Duplicate values in data source 2",
|
"Error when using plugin 'consolidate': 'fail_duplicate' reported Duplicate values in data source 3",
|
||||||
str(error.exception),
|
str(error.exception),
|
||||||
)
|
)
|
||||||
|
|
Loading…
Reference in New Issue