plugins (become, callback, filter): style adjustments (#9535)

* plugins (become, callback, filter, inventory): style adjustments

* remove inventory plugins from PR

* adjustments from review

* typo
pull/9547/head
Alexei Znamensky 2025-01-07 18:33:28 +13:00 committed by GitHub
parent 8cef0ee551
commit 3af793c2c1
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
22 changed files with 696 additions and 699 deletions

View File

@ -15,8 +15,8 @@ options:
become_user: become_user:
description: description:
- User you 'become' to execute the task. - User you 'become' to execute the task.
- This plugin ignores this setting as pfexec uses its own C(exec_attr) to figure this out, but it is supplied here - This plugin ignores this setting as pfexec uses its own C(exec_attr) to figure this out, but it is supplied here for
for Ansible to make decisions needed for the task execution, like file permissions. Ansible to make decisions needed for the task execution, like file permissions.
type: string type: string
default: root default: root
ini: ini:

View File

@ -29,7 +29,7 @@ ansible_config: |
stdout_callback = community.general.default_without_diff stdout_callback = community.general.default_without_diff
# Enable callback with environment variables: # Enable callback with environment variables:
environment_variable: | environment_variable: |-
ANSIBLE_STDOUT_CALLBACK=community.general.default_without_diff ANSIBLE_STDOUT_CALLBACK=community.general.default_without_diff
""" """

View File

@ -14,7 +14,8 @@ type: stdout
short_description: YAML-ized Ansible screen output short_description: YAML-ized Ansible screen output
deprecated: deprecated:
removed_in: 13.0.0 removed_in: 13.0.0
why: Starting in ansible-core 2.13, the P(ansible.builtin.default#callback) callback has support for printing output in YAML format. why: Starting in ansible-core 2.13, the P(ansible.builtin.default#callback) callback has support for printing output in
YAML format.
alternative: Use O(ansible.builtin.default#callback:result_format=yaml). alternative: Use O(ansible.builtin.default#callback:result_format=yaml).
description: description:
- Ansible output that can be quite a bit easier to read than the default JSON formatting. - Ansible output that can be quite a bit easier to read than the default JSON formatting.

View File

@ -2,7 +2,7 @@
# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt) # 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 # SPDX-License-Identifier: GPL-3.0-or-later
DOCUMENTATION = ''' DOCUMENTATION = r"""
name: accumulate name: accumulate
short_description: Produce a list of accumulated sums of the input list contents short_description: Produce a list of accumulated sums of the input list contents
version_added: 10.1.0 version_added: 10.1.0
@ -17,16 +17,16 @@ DOCUMENTATION = '''
type: list type: list
elements: any elements: any
required: true required: true
''' """
RETURN = ''' RETURN = r"""
_value: _value:
description: A list of cumulated sums of the elements of the input list. description: A list of cumulated sums of the elements of the input list.
type: list type: list
elements: any elements: any
''' """
EXAMPLES = ''' EXAMPLES = r"""
- name: Enumerate parent directories of some path - name: Enumerate parent directories of some path
ansible.builtin.debug: ansible.builtin.debug:
var: > var: >
@ -34,11 +34,12 @@ EXAMPLES = '''
| split('/') | map('split', '/') | split('/') | map('split', '/')
| community.general.accumulate | map('join', '/') | community.general.accumulate | map('join', '/')
# Produces: ['', '/some', '/some/path', '/some/path/to', '/some/path/to/my', '/some/path/to/my/file'] # Produces: ['', '/some', '/some/path', '/some/path/to', '/some/path/to/my', '/some/path/to/my/file']
- name: Growing string - name: Growing string
ansible.builtin.debug: ansible.builtin.debug:
var: "'abc' | community.general.accumulate" var: "'abc' | community.general.accumulate"
# Produces ['a', 'ab', 'abc'] # Produces ['a', 'ab', 'abc']
''' """
from itertools import accumulate from itertools import accumulate
from collections.abc import Sequence from collections.abc import Sequence

View File

@ -6,7 +6,7 @@
from __future__ import (absolute_import, division, print_function) from __future__ import (absolute_import, division, print_function)
__metaclass__ = type __metaclass__ = type
DOCUMENTATION = ''' DOCUMENTATION = r"""
name: counter name: counter
short_description: Counts hashable elements in a sequence short_description: Counts hashable elements in a sequence
version_added: 4.3.0 version_added: 4.3.0
@ -19,21 +19,22 @@ DOCUMENTATION = '''
type: list type: list
elements: any elements: any
required: true required: true
''' """
EXAMPLES = ''' EXAMPLES = r"""
- name: Count occurrences - name: Count occurrences
ansible.builtin.debug: ansible.builtin.debug:
msg: >- msg: >-
{{ [1, 'a', 2, 2, 'a', 'b', 'a'] | community.general.counter }} {{ [1, 'a', 2, 2, 'a', 'b', 'a'] | community.general.counter }}
# Produces: {1: 1, 'a': 3, 2: 2, 'b': 1} # Produces: {1: 1, 'a': 3, 2: 2, 'b': 1}
''' """
RETURN = ''' RETURN = r"""
_value: _value:
description: A dictionary with the elements of the sequence as keys, and their number of occurrences in the sequence as values. description: A dictionary with the elements of the sequence as keys, and their number of occurrences in the sequence as
values.
type: dictionary type: dictionary
''' """
from ansible.errors import AnsibleFilterError from ansible.errors import AnsibleFilterError
from ansible.module_utils.common._collections_compat import Sequence from ansible.module_utils.common._collections_compat import Sequence

View File

@ -16,7 +16,7 @@ except ImportError:
HAS_ZLIB = False HAS_ZLIB = False
DOCUMENTATION = ''' DOCUMENTATION = r"""
name: crc32 name: crc32
short_description: Generate a CRC32 checksum short_description: Generate a CRC32 checksum
version_added: 5.4.0 version_added: 5.4.0
@ -30,19 +30,19 @@ DOCUMENTATION = '''
required: true required: true
author: author:
- Julien Riou - Julien Riou
''' """
EXAMPLES = ''' EXAMPLES = r"""
- name: Checksum a test string - name: Checksum a test string
ansible.builtin.debug: ansible.builtin.debug:
msg: "{{ 'test' | community.general.crc32 }}" msg: "{{ 'test' | community.general.crc32 }}"
''' """
RETURN = ''' RETURN = r"""
_value: _value:
description: CRC32 checksum. description: CRC32 checksum.
type: string type: string
''' """
def crc32s(value): def crc32s(value):

View File

@ -7,7 +7,7 @@
from __future__ import absolute_import, division, print_function from __future__ import absolute_import, division, print_function
__metaclass__ = type __metaclass__ = type
DOCUMENTATION = ''' DOCUMENTATION = r"""
name: dict name: dict
short_description: Convert a list of tuples into a dictionary short_description: Convert a list of tuples into a dictionary
version_added: 3.0.0 version_added: 3.0.0
@ -20,9 +20,9 @@ DOCUMENTATION = '''
type: list type: list
elements: tuple elements: tuple
required: true required: true
''' """
EXAMPLES = ''' EXAMPLES = r"""
- name: Convert list of tuples into dictionary - name: Convert list of tuples into dictionary
ansible.builtin.set_fact: ansible.builtin.set_fact:
dictionary: "{{ [[1, 2], ['a', 'b']] | community.general.dict }}" dictionary: "{{ [[1, 2], ['a', 'b']] | community.general.dict }}"
@ -53,13 +53,13 @@ EXAMPLES = '''
# "k2": 42, # "k2": 42,
# "k3": "b" # "k3": "b"
# } # }
''' """
RETURN = ''' RETURN = r"""
_value: _value:
description: A dictionary with the provided key-value pairs. description: A dictionary with the provided key-value pairs.
type: dictionary type: dictionary
''' """
def dict_filter(sequence): def dict_filter(sequence):

View File

@ -6,7 +6,7 @@
from __future__ import (absolute_import, division, print_function) from __future__ import (absolute_import, division, print_function)
__metaclass__ = type __metaclass__ = type
DOCUMENTATION = ''' DOCUMENTATION = r"""
name: dict_kv name: dict_kv
short_description: Convert a value to a dictionary with a single key-value pair short_description: Convert a value to a dictionary with a single key-value pair
version_added: 1.3.0 version_added: 1.3.0
@ -23,20 +23,20 @@ DOCUMENTATION = '''
description: The key for the single key-value pair. description: The key for the single key-value pair.
type: any type: any
required: true required: true
''' """
EXAMPLES = ''' EXAMPLES = r"""
- name: Create a one-element dictionary from a value - name: Create a one-element dictionary from a value
ansible.builtin.debug: ansible.builtin.debug:
msg: "{{ 'myvalue' | dict_kv('mykey') }}" msg: "{{ 'myvalue' | dict_kv('mykey') }}"
# Produces the dictionary {'mykey': 'myvalue'} # Produces the dictionary {'mykey': 'myvalue'}
''' """
RETURN = ''' RETURN = r"""
_value: _value:
description: A dictionary with a single key-value pair. description: A dictionary with a single key-value pair.
type: dictionary type: dictionary
''' """
def dict_kv(value, key): def dict_kv(value, key):

View File

@ -8,7 +8,7 @@
from __future__ import absolute_import, division, print_function from __future__ import absolute_import, division, print_function
__metaclass__ = type __metaclass__ = type
DOCUMENTATION = ''' DOCUMENTATION = r"""
name: from_csv name: from_csv
short_description: Converts CSV text input into list of dicts short_description: Converts CSV text input into list of dicts
version_added: 2.3.0 version_added: 2.3.0
@ -50,9 +50,9 @@ DOCUMENTATION = '''
- When using this parameter, you change the default value used by O(dialect). - When using this parameter, you change the default value used by O(dialect).
- The default value depends on the dialect used. - The default value depends on the dialect used.
type: bool type: bool
''' """
EXAMPLES = ''' EXAMPLES = r"""
- name: Parse a CSV file's contents - name: Parse a CSV file's contents
ansible.builtin.debug: ansible.builtin.debug:
msg: >- msg: >-
@ -71,14 +71,14 @@ EXAMPLES = '''
# "Column 1": "bar", # "Column 1": "bar",
# "Value": "42", # "Value": "42",
# } # }
''' """
RETURN = ''' RETURN = r"""
_value: _value:
description: A list with one dictionary per row. description: A list with one dictionary per row.
type: list type: list
elements: dictionary elements: dictionary
''' """
from ansible.errors import AnsibleFilterError from ansible.errors import AnsibleFilterError

View File

@ -6,7 +6,7 @@
from __future__ import absolute_import, division, print_function from __future__ import absolute_import, division, print_function
DOCUMENTATION = r''' DOCUMENTATION = r"""
name: from_ini name: from_ini
short_description: Converts INI text input into a dictionary short_description: Converts INI text input into a dictionary
version_added: 8.2.0 version_added: 8.2.0
@ -18,9 +18,9 @@ DOCUMENTATION = r'''
description: A string containing an INI document. description: A string containing an INI document.
type: string type: string
required: true required: true
''' """
EXAMPLES = r''' EXAMPLES = r"""
- name: Slurp an INI file - name: Slurp an INI file
ansible.builtin.slurp: ansible.builtin.slurp:
src: /etc/rhsm/rhsm.conf src: /etc/rhsm/rhsm.conf
@ -36,13 +36,13 @@ EXAMPLES = r'''
{{ {{
rhsm_conf.content | b64decode | community.general.from_ini rhsm_conf.content | b64decode | community.general.from_ini
}} }}
''' """
RETURN = ''' RETURN = r"""
_value: _value:
description: A dictionary representing the INI file. description: A dictionary representing the INI file.
type: dictionary type: dictionary
''' """
__metaclass__ = type __metaclass__ = type

View File

@ -6,19 +6,19 @@
from __future__ import (absolute_import, division, print_function) from __future__ import (absolute_import, division, print_function)
__metaclass__ = type __metaclass__ = type
DOCUMENTATION = ''' DOCUMENTATION = r"""
name: groupby_as_dict name: groupby_as_dict
short_description: Transform a sequence of dictionaries to a dictionary where the dictionaries are indexed by an attribute short_description: Transform a sequence of dictionaries to a dictionary where the dictionaries are indexed by an attribute
version_added: 3.1.0 version_added: 3.1.0
author: Felix Fontein (@felixfontein) author: Felix Fontein (@felixfontein)
description: description:
- Transform a sequence of dictionaries to a dictionary where the dictionaries are indexed by an attribute. - Transform a sequence of dictionaries to a dictionary where the dictionaries are indexed by an attribute.
- This filter is similar to the Jinja2 C(groupby) filter. Use the Jinja2 C(groupby) filter if you have multiple entries with the same value, - This filter is similar to the Jinja2 C(groupby) filter. Use the Jinja2 C(groupby) filter if you have multiple entries
or when you need a dictionary with list values, or when you need to use deeply nested attributes. with the same value, or when you need a dictionary with list values, or when you need to use deeply nested attributes.
positional: attribute positional: attribute
options: options:
_input: _input:
description: A list of dictionaries description: A list of dictionaries.
type: list type: list
elements: dictionary elements: dictionary
required: true required: true
@ -26,9 +26,9 @@ DOCUMENTATION = '''
description: The attribute to use as the key. description: The attribute to use as the key.
type: str type: str
required: true required: true
''' """
EXAMPLES = ''' EXAMPLES = r"""
- name: Arrange a list of dictionaries as a dictionary of dictionaries - name: Arrange a list of dictionaries as a dictionary of dictionaries
ansible.builtin.debug: ansible.builtin.debug:
msg: "{{ sequence | community.general.groupby_as_dict('key') }}" msg: "{{ sequence | community.general.groupby_as_dict('key') }}"
@ -46,13 +46,13 @@ EXAMPLES = '''
# other_value: # other_value:
# key: other_value # key: other_value
# baz: bar # baz: bar
''' """
RETURN = ''' RETURN = r"""
_value: _value:
description: A dictionary containing the dictionaries from the list as values. description: A dictionary containing the dictionaries from the list as values.
type: dictionary type: dictionary
''' """
from ansible.errors import AnsibleFilterError from ansible.errors import AnsibleFilterError
from ansible.module_utils.common._collections_compat import Mapping, Sequence from ansible.module_utils.common._collections_compat import Mapping, Sequence

View File

@ -8,7 +8,7 @@
from __future__ import (absolute_import, division, print_function) from __future__ import (absolute_import, division, print_function)
__metaclass__ = type __metaclass__ = type
DOCUMENTATION = ''' DOCUMENTATION = r"""
name: jc name: jc
short_description: Convert output of many shell commands and file-types to JSON short_description: Convert output of many shell commands and file-types to JSON
version_added: 1.1.0 version_added: 1.1.0
@ -26,7 +26,7 @@ DOCUMENTATION = '''
description: description:
- The correct parser for the input data. - The correct parser for the input data.
- For example V(ifconfig). - For example V(ifconfig).
- "Note: use underscores instead of dashes (if any) in the parser module name." - 'Note: use underscores instead of dashes (if any) in the parser module name.'
- See U(https://github.com/kellyjonbrazil/jc#parsers) for the latest list of parsers. - See U(https://github.com/kellyjonbrazil/jc#parsers) for the latest list of parsers.
type: string type: string
required: true required: true
@ -40,9 +40,9 @@ DOCUMENTATION = '''
default: false default: false
requirements: requirements:
- jc installed as a Python library (U(https://pypi.org/project/jc/)) - jc installed as a Python library (U(https://pypi.org/project/jc/))
''' """
EXAMPLES = ''' EXAMPLES = r"""
- name: Install the prereqs of the jc filter (jc Python package) on the Ansible controller - name: Install the prereqs of the jc filter (jc Python package) on the Ansible controller
delegate_to: localhost delegate_to: localhost
ansible.builtin.pip: ansible.builtin.pip:
@ -68,13 +68,13 @@ EXAMPLES = '''
# "operating_system": "GNU/Linux", # "operating_system": "GNU/Linux",
# "processor": "x86_64" # "processor": "x86_64"
# } # }
''' """
RETURN = ''' RETURN = r"""
_value: _value:
description: The processed output. description: The processed output.
type: any type: any
''' """
from ansible.errors import AnsibleError, AnsibleFilterError from ansible.errors import AnsibleError, AnsibleFilterError
import importlib import importlib

View File

@ -6,7 +6,7 @@
from __future__ import (absolute_import, division, print_function) from __future__ import (absolute_import, division, print_function)
__metaclass__ = type __metaclass__ = type
DOCUMENTATION = ''' DOCUMENTATION = r"""
name: json_query name: json_query
short_description: Select a single element or a data subset from a complex data structure short_description: Select a single element or a data subset from a complex data structure
description: description:
@ -26,9 +26,9 @@ DOCUMENTATION = '''
required: true required: true
requirements: requirements:
- jmespath - jmespath
''' """
EXAMPLES = ''' EXAMPLES = r"""
- name: Define data to work on in the examples below - name: Define data to work on in the examples below
ansible.builtin.set_fact: ansible.builtin.set_fact:
domain_definition: domain_definition:
@ -99,13 +99,13 @@ EXAMPLES = '''
msg: "{{ domain_definition | to_json | from_json | community.general.json_query(server_name_query) }}" msg: "{{ domain_definition | to_json | from_json | community.general.json_query(server_name_query) }}"
vars: vars:
server_name_query: "domain.server[?contains(name,'server1')].port" server_name_query: "domain.server[?contains(name,'server1')].port"
''' """
RETURN = ''' RETURN = r"""
_value: _value:
description: The result of the query. description: The result of the query.
type: any type: any
''' """
from ansible.errors import AnsibleError, AnsibleFilterError from ansible.errors import AnsibleError, AnsibleFilterError

View File

@ -7,7 +7,7 @@
from __future__ import (absolute_import, division, print_function) from __future__ import (absolute_import, division, print_function)
__metaclass__ = type __metaclass__ = type
DOCUMENTATION = ''' DOCUMENTATION = r"""
name: keep_keys name: keep_keys
short_description: Keep specific keys from dictionaries in a list short_description: Keep specific keys from dictionaries in a list
version_added: "9.1.0" version_added: "9.1.0"
@ -40,66 +40,66 @@ DOCUMENTATION = '''
regex: regex:
- Matches keys that match the regular expresion provided in O(target). - Matches keys that match the regular expresion provided in O(target).
- In this case, O(target) must be a regex string or a list with single regex string. - In this case, O(target) must be a regex string or a list with single regex string.
''' """
EXAMPLES = ''' EXAMPLES = r"""
l: - l:
- {k0_x0: A0, k1_x1: B0, k2_x2: [C0], k3_x3: foo} - {k0_x0: A0, k1_x1: B0, k2_x2: [C0], k3_x3: foo}
- {k0_x0: A1, k1_x1: B1, k2_x2: [C1], k3_x3: bar} - {k0_x0: A1, k1_x1: B1, k2_x2: [C1], k3_x3: bar}
# 1) By default match keys that equal any of the items in the target. # 1) By default match keys that equal any of the items in the target.
t: [k0_x0, k1_x1] - t: [k0_x0, k1_x1]
r: "{{ l | community.general.keep_keys(target=t) }}" r: "{{ l | community.general.keep_keys(target=t) }}"
# 2) Match keys that start with any of the items in the target. # 2) Match keys that start with any of the items in the target.
t: [k0, k1] - t: [k0, k1]
r: "{{ l | community.general.keep_keys(target=t, matching_parameter='starts_with') }}" r: "{{ l | community.general.keep_keys(target=t, matching_parameter='starts_with') }}"
# 3) Match keys that end with any of the items in target. # 3) Match keys that end with any of the items in target.
t: [x0, x1] - t: [x0, x1]
r: "{{ l | community.general.keep_keys(target=t, matching_parameter='ends_with') }}" r: "{{ l | community.general.keep_keys(target=t, matching_parameter='ends_with') }}"
# 4) Match keys by the regex. # 4) Match keys by the regex.
t: ['^.*[01]_x.*$'] - t: ['^.*[01]_x.*$']
r: "{{ l | community.general.keep_keys(target=t, matching_parameter='regex') }}" r: "{{ l | community.general.keep_keys(target=t, matching_parameter='regex') }}"
# 5) Match keys by the regex. # 5) Match keys by the regex.
t: '^.*[01]_x.*$' - t: '^.*[01]_x.*$'
r: "{{ l | community.general.keep_keys(target=t, matching_parameter='regex') }}" r: "{{ l | community.general.keep_keys(target=t, matching_parameter='regex') }}"
# The results of above examples 1-5 are all the same. # The results of above examples 1-5 are all the same.
r: - r:
- {k0_x0: A0, k1_x1: B0} - {k0_x0: A0, k1_x1: B0}
- {k0_x0: A1, k1_x1: B1} - {k0_x0: A1, k1_x1: B1}
# 6) By default match keys that equal the target. # 6) By default match keys that equal the target.
t: k0_x0 - t: k0_x0
r: "{{ l | community.general.keep_keys(target=t) }}" r: "{{ l | community.general.keep_keys(target=t) }}"
# 7) Match keys that start with the target. # 7) Match keys that start with the target.
t: k0 - t: k0
r: "{{ l | community.general.keep_keys(target=t, matching_parameter='starts_with') }}" r: "{{ l | community.general.keep_keys(target=t, matching_parameter='starts_with') }}"
# 8) Match keys that end with the target. # 8) Match keys that end with the target.
t: x0 - t: x0
r: "{{ l | community.general.keep_keys(target=t, matching_parameter='ends_with') }}" r: "{{ l | community.general.keep_keys(target=t, matching_parameter='ends_with') }}"
# 9) Match keys by the regex. # 9) Match keys by the regex.
t: '^.*0_x.*$' - t: '^.*0_x.*$'
r: "{{ l | community.general.keep_keys(target=t, matching_parameter='regex') }}" r: "{{ l | community.general.keep_keys(target=t, matching_parameter='regex') }}"
# The results of above examples 6-9 are all the same. # The results of above examples 6-9 are all the same.
r: - r:
- {k0_x0: A0} - {k0_x0: A0}
- {k0_x0: A1} - {k0_x0: A1}
''' """
RETURN = ''' RETURN = r"""
_value: _value:
description: The list of dictionaries with selected keys. description: The list of dictionaries with selected keys.
type: list type: list
elements: dictionary elements: dictionary
''' """
from ansible_collections.community.general.plugins.plugin_utils.keys_filter import ( from ansible_collections.community.general.plugins.plugin_utils.keys_filter import (
_keys_filter_params, _keys_filter_params,

View File

@ -6,28 +6,23 @@
from __future__ import (absolute_import, division, print_function) from __future__ import (absolute_import, division, print_function)
__metaclass__ = type __metaclass__ = type
DOCUMENTATION = ''' DOCUMENTATION = r"""
name: lists_mergeby name: lists_mergeby
short_description: Merge two or more lists of dictionaries by a given attribute short_description: Merge two or more lists of dictionaries by a given attribute
version_added: 2.0.0 version_added: 2.0.0
author: Vladimir Botka (@vbotka) author: Vladimir Botka (@vbotka)
description: description:
- Merge two or more lists by attribute O(index). Optional - Merge two or more lists by attribute O(index). Optional parameters O(recursive) and O(list_merge) control the merging
parameters O(recursive) and O(list_merge) control the merging of of the nested dictionaries and lists.
the nested dictionaries and lists.
- The function C(merge_hash) from C(ansible.utils.vars) is used. - The function C(merge_hash) from C(ansible.utils.vars) is used.
- To learn details on how to use the parameters O(recursive) and - To learn details on how to use the parameters O(recursive) and O(list_merge) see Ansible User's Guide chapter "Using filters
O(list_merge) see Ansible User's Guide chapter "Using filters to to manipulate data" section R(Combining hashes/dictionaries, combine_filter) or the filter P(ansible.builtin.combine#filter).
manipulate data" section R(Combining hashes/dictionaries, combine_filter) or the
filter P(ansible.builtin.combine#filter).
positional: another_list, index positional: another_list, index
options: options:
_input: _input:
description: description:
- A list of dictionaries, or a list of lists of dictionaries. - A list of dictionaries, or a list of lists of dictionaries.
- The required type of the C(elements) is set to C(raw) - The required type of the C(elements) is set to C(raw) because all elements of O(_input) can be either dictionaries
because all elements of O(_input) can be either dictionaries
or lists. or lists.
type: list type: list
elements: raw elements: raw
@ -40,14 +35,13 @@ DOCUMENTATION = '''
elements: raw elements: raw
index: index:
description: description:
- The dictionary key that must be present in every dictionary in every list that is used to - The dictionary key that must be present in every dictionary in every list that is used to merge the lists.
merge the lists.
type: string type: string
required: true required: true
recursive: recursive:
description: description:
- Should the combine recursively merge nested dictionaries (hashes). - Should the combine recursively merge nested dictionaries (hashes).
- "B(Note:) It does not depend on the value of the C(hash_behaviour) setting in C(ansible.cfg)." - B(Note:) It does not depend on the value of the C(hash_behaviour) setting in C(ansible.cfg).
type: boolean type: boolean
default: false default: false
list_merge: list_merge:
@ -62,9 +56,9 @@ DOCUMENTATION = '''
- prepend - prepend
- append_rp - append_rp
- prepend_rp - prepend_rp
''' """
EXAMPLES = ''' EXAMPLES = r"""
# Some results below are manually formatted for better readability. The # Some results below are manually formatted for better readability. The
# dictionaries' keys will be sorted alphabetically in real output. # dictionaries' keys will be sorted alphabetically in real output.
@ -193,14 +187,14 @@ EXAMPLES = '''
# r: # r:
# - {index: a, foo: {x:1, y: 3, z: 4}} # - {index: a, foo: {x:1, y: 3, z: 4}}
# - {index: b, foo: [Y1, Y2]} # - {index: b, foo: [Y1, Y2]}
''' """
RETURN = ''' RETURN = r"""
_value: _value:
description: The merged list. description: The merged list.
type: list type: list
elements: dictionary elements: dictionary
''' """
from ansible.errors import AnsibleFilterError from ansible.errors import AnsibleFilterError
from ansible.module_utils.six import string_types from ansible.module_utils.six import string_types

View File

@ -7,7 +7,7 @@
from __future__ import (absolute_import, division, print_function) from __future__ import (absolute_import, division, print_function)
__metaclass__ = type __metaclass__ = type
DOCUMENTATION = ''' DOCUMENTATION = r"""
name: random_mac name: random_mac
short_description: Generate a random MAC address short_description: Generate a random MAC address
description: description:
@ -23,9 +23,9 @@ DOCUMENTATION = '''
- If no seed is provided, a system random source such as C(/dev/urandom) is used. - If no seed is provided, a system random source such as C(/dev/urandom) is used.
required: false required: false
type: string type: string
''' """
EXAMPLES = ''' EXAMPLES = r"""
- name: Random MAC given a prefix - name: Random MAC given a prefix
ansible.builtin.debug: ansible.builtin.debug:
msg: "{{ '52:54:00' | community.general.random_mac }}" msg: "{{ '52:54:00' | community.general.random_mac }}"
@ -34,13 +34,13 @@ EXAMPLES = '''
- name: With a seed - name: With a seed
ansible.builtin.debug: ansible.builtin.debug:
msg: "{{ '52:54:00' | community.general.random_mac(seed=inventory_hostname) }}" msg: "{{ '52:54:00' | community.general.random_mac(seed=inventory_hostname) }}"
''' """
RETURN = ''' RETURN = r"""
_value: _value:
description: The generated MAC. description: The generated MAC.
type: string type: string
''' """
import re import re
from random import Random, SystemRandom from random import Random, SystemRandom

View File

@ -7,7 +7,7 @@
from __future__ import (absolute_import, division, print_function) from __future__ import (absolute_import, division, print_function)
__metaclass__ = type __metaclass__ = type
DOCUMENTATION = ''' DOCUMENTATION = r"""
name: remove_keys name: remove_keys
short_description: Remove specific keys from dictionaries in a list short_description: Remove specific keys from dictionaries in a list
version_added: "9.1.0" version_added: "9.1.0"
@ -40,66 +40,66 @@ DOCUMENTATION = '''
regex: regex:
- Matches keys that match the regular expresion provided in O(target). - Matches keys that match the regular expresion provided in O(target).
- In this case, O(target) must be a regex string or a list with single regex string. - In this case, O(target) must be a regex string or a list with single regex string.
''' """
EXAMPLES = ''' EXAMPLES = r"""
l: - l:
- {k0_x0: A0, k1_x1: B0, k2_x2: [C0], k3_x3: foo} - {k0_x0: A0, k1_x1: B0, k2_x2: [C0], k3_x3: foo}
- {k0_x0: A1, k1_x1: B1, k2_x2: [C1], k3_x3: bar} - {k0_x0: A1, k1_x1: B1, k2_x2: [C1], k3_x3: bar}
# 1) By default match keys that equal any of the items in the target. # 1) By default match keys that equal any of the items in the target.
t: [k0_x0, k1_x1] - t: [k0_x0, k1_x1]
r: "{{ l | community.general.remove_keys(target=t) }}" r: "{{ l | community.general.remove_keys(target=t) }}"
# 2) Match keys that start with any of the items in the target. # 2) Match keys that start with any of the items in the target.
t: [k0, k1] - t: [k0, k1]
r: "{{ l | community.general.remove_keys(target=t, matching_parameter='starts_with') }}" r: "{{ l | community.general.remove_keys(target=t, matching_parameter='starts_with') }}"
# 3) Match keys that end with any of the items in target. # 3) Match keys that end with any of the items in target.
t: [x0, x1] - t: [x0, x1]
r: "{{ l | community.general.remove_keys(target=t, matching_parameter='ends_with') }}" r: "{{ l | community.general.remove_keys(target=t, matching_parameter='ends_with') }}"
# 4) Match keys by the regex. # 4) Match keys by the regex.
t: ['^.*[01]_x.*$'] - t: ['^.*[01]_x.*$']
r: "{{ l | community.general.remove_keys(target=t, matching_parameter='regex') }}" r: "{{ l | community.general.remove_keys(target=t, matching_parameter='regex') }}"
# 5) Match keys by the regex. # 5) Match keys by the regex.
t: '^.*[01]_x.*$' - t: '^.*[01]_x.*$'
r: "{{ l | community.general.remove_keys(target=t, matching_parameter='regex') }}" r: "{{ l | community.general.remove_keys(target=t, matching_parameter='regex') }}"
# The results of above examples 1-5 are all the same. # The results of above examples 1-5 are all the same.
r: - r:
- {k2_x2: [C0], k3_x3: foo} - {k2_x2: [C0], k3_x3: foo}
- {k2_x2: [C1], k3_x3: bar} - {k2_x2: [C1], k3_x3: bar}
# 6) By default match keys that equal the target. # 6) By default match keys that equal the target.
t: k0_x0 - t: k0_x0
r: "{{ l | community.general.remove_keys(target=t) }}" r: "{{ l | community.general.remove_keys(target=t) }}"
# 7) Match keys that start with the target. # 7) Match keys that start with the target.
t: k0 - t: k0
r: "{{ l | community.general.remove_keys(target=t, matching_parameter='starts_with') }}" r: "{{ l | community.general.remove_keys(target=t, matching_parameter='starts_with') }}"
# 8) Match keys that end with the target. # 8) Match keys that end with the target.
t: x0 - t: x0
r: "{{ l | community.general.remove_keys(target=t, matching_parameter='ends_with') }}" r: "{{ l | community.general.remove_keys(target=t, matching_parameter='ends_with') }}"
# 9) Match keys by the regex. # 9) Match keys by the regex.
t: '^.*0_x.*$' - t: '^.*0_x.*$'
r: "{{ l | community.general.remove_keys(target=t, matching_parameter='regex') }}" r: "{{ l | community.general.remove_keys(target=t, matching_parameter='regex') }}"
# The results of above examples 6-9 are all the same. # The results of above examples 6-9 are all the same.
r: - r:
- {k1_x1: B0, k2_x2: [C0], k3_x3: foo} - {k1_x1: B0, k2_x2: [C0], k3_x3: foo}
- {k1_x1: B1, k2_x2: [C1], k3_x3: bar} - {k1_x1: B1, k2_x2: [C1], k3_x3: bar}
''' """
RETURN = ''' RETURN = r"""
_value: _value:
description: The list of dictionaries with selected keys removed. description: The list of dictionaries with selected keys removed.
type: list type: list
elements: dictionary elements: dictionary
''' """
from ansible_collections.community.general.plugins.plugin_utils.keys_filter import ( from ansible_collections.community.general.plugins.plugin_utils.keys_filter import (
_keys_filter_params, _keys_filter_params,

View File

@ -7,7 +7,7 @@
from __future__ import (absolute_import, division, print_function) from __future__ import (absolute_import, division, print_function)
__metaclass__ = type __metaclass__ = type
DOCUMENTATION = ''' DOCUMENTATION = r"""
name: replace_keys name: replace_keys
short_description: Replace specific keys in a list of dictionaries short_description: Replace specific keys in a list of dictionaries
version_added: "9.1.0" version_added: "9.1.0"
@ -49,87 +49,87 @@ DOCUMENTATION = '''
starts_with: Matches keys that start with one of the O(target[].before) items. starts_with: Matches keys that start with one of the O(target[].before) items.
ends_with: Matches keys that end with one of the O(target[].before) items. ends_with: Matches keys that end with one of the O(target[].before) items.
regex: Matches keys that match one of the regular expressions provided in O(target[].before). regex: Matches keys that match one of the regular expressions provided in O(target[].before).
''' """
EXAMPLES = ''' EXAMPLES = r"""
l: - l:
- {k0_x0: A0, k1_x1: B0, k2_x2: [C0], k3_x3: foo} - {k0_x0: A0, k1_x1: B0, k2_x2: [C0], k3_x3: foo}
- {k0_x0: A1, k1_x1: B1, k2_x2: [C1], k3_x3: bar} - {k0_x0: A1, k1_x1: B1, k2_x2: [C1], k3_x3: bar}
# 1) By default, replace keys that are equal any of the attributes before. # 1) By default, replace keys that are equal any of the attributes before.
t: - t:
- {before: k0_x0, after: a0} - {before: k0_x0, after: a0}
- {before: k1_x1, after: a1} - {before: k1_x1, after: a1}
r: "{{ l | community.general.replace_keys(target=t) }}" r: "{{ l | community.general.replace_keys(target=t) }}"
# 2) Replace keys that starts with any of the attributes before. # 2) Replace keys that starts with any of the attributes before.
t: - t:
- {before: k0, after: a0} - {before: k0, after: a0}
- {before: k1, after: a1} - {before: k1, after: a1}
r: "{{ l | community.general.replace_keys(target=t, matching_parameter='starts_with') }}" r: "{{ l | community.general.replace_keys(target=t, matching_parameter='starts_with') }}"
# 3) Replace keys that ends with any of the attributes before. # 3) Replace keys that ends with any of the attributes before.
t: - t:
- {before: x0, after: a0} - {before: x0, after: a0}
- {before: x1, after: a1} - {before: x1, after: a1}
r: "{{ l | community.general.replace_keys(target=t, matching_parameter='ends_with') }}" r: "{{ l | community.general.replace_keys(target=t, matching_parameter='ends_with') }}"
# 4) Replace keys that match any regex of the attributes before. # 4) Replace keys that match any regex of the attributes before.
t: - t:
- {before: "^.*0_x.*$", after: a0} - {before: "^.*0_x.*$", after: a0}
- {before: "^.*1_x.*$", after: a1} - {before: "^.*1_x.*$", after: a1}
r: "{{ l | community.general.replace_keys(target=t, matching_parameter='regex') }}" r: "{{ l | community.general.replace_keys(target=t, matching_parameter='regex') }}"
# The results of above examples 1-4 are all the same. # The results of above examples 1-4 are all the same.
r: - r:
- {a0: A0, a1: B0, k2_x2: [C0], k3_x3: foo} - {a0: A0, a1: B0, k2_x2: [C0], k3_x3: foo}
- {a0: A1, a1: B1, k2_x2: [C1], k3_x3: bar} - {a0: A1, a1: B1, k2_x2: [C1], k3_x3: bar}
# 5) If more keys match the same attribute before the last one will be used. # 5) If more keys match the same attribute before the last one will be used.
t: - t:
- {before: "^.*_x.*$", after: X} - {before: "^.*_x.*$", after: X}
r: "{{ l | community.general.replace_keys(target=t, matching_parameter='regex') }}" r: "{{ l | community.general.replace_keys(target=t, matching_parameter='regex') }}"
# gives # gives
r: - r:
- X: foo - X: foo
- X: bar - X: bar
# 6) If there are items with equal attribute before the first one will be used. # 6) If there are items with equal attribute before the first one will be used.
t: - t:
- {before: "^.*_x.*$", after: X} - {before: "^.*_x.*$", after: X}
- {before: "^.*_x.*$", after: Y} - {before: "^.*_x.*$", after: Y}
r: "{{ l | community.general.replace_keys(target=t, matching_parameter='regex') }}" r: "{{ l | community.general.replace_keys(target=t, matching_parameter='regex') }}"
# gives # gives
r: - r:
- X: foo - X: foo
- X: bar - X: bar
# 7) If there are more matches for a key the first one will be used. # 7) If there are more matches for a key the first one will be used.
l: - l:
- {aaa1: A, bbb1: B, ccc1: C} - {aaa1: A, bbb1: B, ccc1: C}
- {aaa2: D, bbb2: E, ccc2: F} - {aaa2: D, bbb2: E, ccc2: F}
t: - t:
- {before: a, after: X} - {before: a, after: X}
- {before: aa, after: Y} - {before: aa, after: Y}
r: "{{ l | community.general.replace_keys(target=t, matching_parameter='starts_with') }}" r: "{{ l | community.general.replace_keys(target=t, matching_parameter='starts_with') }}"
# gives # gives
r: - r:
- {X: A, bbb1: B, ccc1: C} - {X: A, bbb1: B, ccc1: C}
- {X: D, bbb2: E, ccc2: F} - {X: D, bbb2: E, ccc2: F}
''' """
RETURN = ''' RETURN = r"""
_value: _value:
description: The list of dictionaries with replaced keys. description: The list of dictionaries with replaced keys.
type: list type: list
elements: dictionary elements: dictionary
''' """
from ansible_collections.community.general.plugins.plugin_utils.keys_filter import ( from ansible_collections.community.general.plugins.plugin_utils.keys_filter import (
_keys_filter_params, _keys_filter_params,

View File

@ -6,7 +6,7 @@
from __future__ import (absolute_import, division, print_function) from __future__ import (absolute_import, division, print_function)
__metaclass__ = type __metaclass__ = type
DOCUMENTATION = ''' DOCUMENTATION = r"""
name: reveal_ansible_type name: reveal_ansible_type
short_description: Return input type short_description: Return input type
version_added: "9.2.0" version_added: "9.2.0"
@ -21,30 +21,30 @@ DOCUMENTATION = '''
description: Data type aliases. description: Data type aliases.
default: {} default: {}
type: dictionary type: dictionary
''' """
EXAMPLES = ''' EXAMPLES = r"""
# Substitution converts str to AnsibleUnicode # Substitution converts str to AnsibleUnicode
# ------------------------------------------- # -------------------------------------------
# String. AnsibleUnicode. # String. AnsibleUnicode.
data: "abc" - data: "abc"
result: '{{ data | community.general.reveal_ansible_type }}' result: '{{ data | community.general.reveal_ansible_type }}'
# result => AnsibleUnicode # result => AnsibleUnicode
# String. AnsibleUnicode alias str. # String. AnsibleUnicode alias str.
alias: {"AnsibleUnicode": "str"} - alias: {"AnsibleUnicode": "str"}
data: "abc" data: "abc"
result: '{{ data | community.general.reveal_ansible_type(alias) }}' result: '{{ data | community.general.reveal_ansible_type(alias) }}'
# result => str # result => str
# List. All items are AnsibleUnicode. # List. All items are AnsibleUnicode.
data: ["a", "b", "c"] - data: ["a", "b", "c"]
result: '{{ data | community.general.reveal_ansible_type }}' result: '{{ data | community.general.reveal_ansible_type }}'
# result => list[AnsibleUnicode] # result => list[AnsibleUnicode]
# Dictionary. All keys are AnsibleUnicode. All values are AnsibleUnicode. # Dictionary. All keys are AnsibleUnicode. All values are AnsibleUnicode.
data: {"a": "foo", "b": "bar", "c": "baz"} - data: {"a": "foo", "b": "bar", "c": "baz"}
result: '{{ data | community.general.reveal_ansible_type }}' result: '{{ data | community.general.reveal_ansible_type }}'
# result => dict[AnsibleUnicode, AnsibleUnicode] # result => dict[AnsibleUnicode, AnsibleUnicode]
@ -52,70 +52,70 @@ result: '{{ data | community.general.reveal_ansible_type }}'
# ---------------------------------------------------- # ----------------------------------------------------
# String # String
result: '{{ "abc" | community.general.reveal_ansible_type }}' - result: '{{ "abc" | community.general.reveal_ansible_type }}'
# result => str # result => str
# Integer # Integer
result: '{{ 123 | community.general.reveal_ansible_type }}' - result: '{{ 123 | community.general.reveal_ansible_type }}'
# result => int # result => int
# Float # Float
result: '{{ 123.45 | community.general.reveal_ansible_type }}' - result: '{{ 123.45 | community.general.reveal_ansible_type }}'
# result => float # result => float
# Boolean # Boolean
result: '{{ true | community.general.reveal_ansible_type }}' - result: '{{ true | community.general.reveal_ansible_type }}'
# result => bool # result => bool
# List. All items are strings. # List. All items are strings.
result: '{{ ["a", "b", "c"] | community.general.reveal_ansible_type }}' - result: '{{ ["a", "b", "c"] | community.general.reveal_ansible_type }}'
# result => list[str] # result => list[str]
# List of dictionaries. # List of dictionaries.
result: '{{ [{"a": 1}, {"b": 2}] | community.general.reveal_ansible_type }}' - result: '{{ [{"a": 1}, {"b": 2}] | community.general.reveal_ansible_type }}'
# result => list[dict] # result => list[dict]
# Dictionary. All keys are strings. All values are integers. # Dictionary. All keys are strings. All values are integers.
result: '{{ {"a": 1} | community.general.reveal_ansible_type }}' - result: '{{ {"a": 1} | community.general.reveal_ansible_type }}'
# result => dict[str, int] # result => dict[str, int]
# Dictionary. All keys are strings. All values are integers. # Dictionary. All keys are strings. All values are integers.
result: '{{ {"a": 1, "b": 2} | community.general.reveal_ansible_type }}' - result: '{{ {"a": 1, "b": 2} | community.general.reveal_ansible_type }}'
# result => dict[str, int] # result => dict[str, int]
# Type of strings is AnsibleUnicode or str # Type of strings is AnsibleUnicode or str
# ---------------------------------------- # ----------------------------------------
# Dictionary. The keys are integers or strings. All values are strings. # Dictionary. The keys are integers or strings. All values are strings.
alias: {"AnsibleUnicode": "str"} - alias: {"AnsibleUnicode": "str"}
data: {1: 'a', 'b': 'b'} data: {1: 'a', 'b': 'b'}
result: '{{ data | community.general.reveal_ansible_type(alias) }}' result: '{{ data | community.general.reveal_ansible_type(alias) }}'
# result => dict[int|str, str] # result => dict[int|str, str]
# Dictionary. All keys are integers. All values are keys. # Dictionary. All keys are integers. All values are keys.
alias: {"AnsibleUnicode": "str"} - alias: {"AnsibleUnicode": "str"}
data: {1: 'a', 2: 'b'} data: {1: 'a', 2: 'b'}
result: '{{ data | community.general.reveal_ansible_type(alias) }}' result: '{{ data | community.general.reveal_ansible_type(alias) }}'
# result => dict[int, str] # result => dict[int, str]
# Dictionary. All keys are strings. Multiple types values. # Dictionary. All keys are strings. Multiple types values.
alias: {"AnsibleUnicode": "str"} - alias: {"AnsibleUnicode": "str"}
data: {'a': 1, 'b': 1.1, 'c': 'abc', 'd': True, 'e': ['x', 'y', 'z'], 'f': {'x': 1, 'y': 2}} data: {'a': 1, 'b': 1.1, 'c': 'abc', 'd': true, 'e': ['x', 'y', 'z'], 'f': {'x': 1, 'y': 2}}
result: '{{ data | community.general.reveal_ansible_type(alias) }}' result: '{{ data | community.general.reveal_ansible_type(alias) }}'
# result => dict[str, bool|dict|float|int|list|str] # result => dict[str, bool|dict|float|int|list|str]
# List. Multiple types items. # List. Multiple types items.
alias: {"AnsibleUnicode": "str"} - alias: {"AnsibleUnicode": "str"}
data: [1, 2, 1.1, 'abc', True, ['x', 'y', 'z'], {'x': 1, 'y': 2}] data: [1, 2, 1.1, 'abc', true, ['x', 'y', 'z'], {'x': 1, 'y': 2}]
result: '{{ data | community.general.reveal_ansible_type(alias) }}' result: '{{ data | community.general.reveal_ansible_type(alias) }}'
# result => list[bool|dict|float|int|list|str] # result => list[bool|dict|float|int|list|str]
''' """
RETURN = ''' RETURN = r"""
_value: _value:
description: Type of the data. description: Type of the data.
type: str type: str
''' """
from ansible_collections.community.general.plugins.plugin_utils.ansible_type import _ansible_type from ansible_collections.community.general.plugins.plugin_utils.ansible_type import _ansible_type

View File

@ -6,7 +6,7 @@
from __future__ import absolute_import, division, print_function from __future__ import absolute_import, division, print_function
DOCUMENTATION = r''' DOCUMENTATION = r"""
name: to_ini name: to_ini
short_description: Converts a dictionary to the INI file format short_description: Converts a dictionary to the INI file format
version_added: 8.2.0 version_added: 8.2.0
@ -18,9 +18,9 @@ DOCUMENTATION = r'''
description: The dictionary that should be converted to the INI format. description: The dictionary that should be converted to the INI format.
type: dictionary type: dictionary
required: true required: true
''' """
EXAMPLES = r''' EXAMPLES = r"""
- name: Define a dictionary - name: Define a dictionary
ansible.builtin.set_fact: ansible.builtin.set_fact:
my_dict: my_dict:
@ -41,13 +41,13 @@ EXAMPLES = r'''
# #
# [another_section] # [another_section]
# connection = ssh # connection = ssh
''' """
RETURN = r''' RETURN = r"""
_value: _value:
description: A string formatted as INI file. description: A string formatted as INI file.
type: string type: string
''' """
__metaclass__ = type __metaclass__ = type

View File

@ -7,7 +7,7 @@
from __future__ import absolute_import, division, print_function from __future__ import absolute_import, division, print_function
__metaclass__ = type __metaclass__ = type
DOCUMENTATION = ''' DOCUMENTATION = r"""
name: unicode_normalize name: unicode_normalize
short_description: Normalizes unicode strings to facilitate comparison of characters with normalized forms short_description: Normalizes unicode strings to facilitate comparison of characters with normalized forms
version_added: 3.7.0 version_added: 3.7.0
@ -31,21 +31,21 @@ DOCUMENTATION = '''
- NFD - NFD
- NFKC - NFKC
- NFKD - NFKD
''' """
EXAMPLES = ''' EXAMPLES = r"""
- name: Normalize unicode string - name: Normalize unicode string
ansible.builtin.set_fact: ansible.builtin.set_fact:
dictionary: "{{ 'ä' | community.general.unicode_normalize('NFKD') }}" dictionary: "{{ 'ä' | community.general.unicode_normalize('NFKD') }}"
# The resulting string has length 2: one letter is 'a', the other # The resulting string has length 2: one letter is 'a', the other
# the diacritic combiner. # the diacritic combiner.
''' """
RETURN = ''' RETURN = r"""
_value: _value:
description: The normalized unicode string of the specified normal form. description: The normalized unicode string of the specified normal form.
type: string type: string
''' """
from unicodedata import normalize from unicodedata import normalize

View File

@ -6,7 +6,7 @@
from __future__ import (absolute_import, division, print_function) from __future__ import (absolute_import, division, print_function)
__metaclass__ = type __metaclass__ = type
DOCUMENTATION = ''' DOCUMENTATION = r"""
name: version_sort name: version_sort
short_description: Sort a list according to version order instead of pure alphabetical one short_description: Sort a list according to version order instead of pure alphabetical one
version_added: 2.2.0 version_added: 2.2.0
@ -19,21 +19,21 @@ DOCUMENTATION = '''
type: list type: list
elements: string elements: string
required: true required: true
''' """
EXAMPLES = ''' EXAMPLES = r"""
- name: Convert list of tuples into dictionary - name: Convert list of tuples into dictionary
ansible.builtin.set_fact: ansible.builtin.set_fact:
dictionary: "{{ ['2.1', '2.10', '2.9'] | community.general.version_sort }}" dictionary: "{{ ['2.1', '2.10', '2.9'] | community.general.version_sort }}"
# Result is ['2.1', '2.9', '2.10'] # Result is ['2.1', '2.9', '2.10']
''' """
RETURN = ''' RETURN = r"""
_value: _value:
description: The list of strings sorted by version. description: The list of strings sorted by version.
type: list type: list
elements: string elements: string
''' """
from ansible_collections.community.general.plugins.module_utils.version import LooseVersion from ansible_collections.community.general.plugins.module_utils.version import LooseVersion