diff --git a/.github/BOTMETA.yml b/.github/BOTMETA.yml index c801ba6494..ade8a1cdbf 100644 --- a/.github/BOTMETA.yml +++ b/.github/BOTMETA.yml @@ -126,9 +126,13 @@ files: maintainers: giner $filters/from_csv.py: maintainers: Ajpantuso - $filters/groupby: + $filters/groupby.py: maintainers: felixfontein - $filters/hashids: + $filters/hashids.py: + maintainers: Ajpantuso + $filters/hashids_decode.yml: + maintainers: Ajpantuso + $filters/hashids_encode.yml: maintainers: Ajpantuso $filters/jc.py: maintainers: kellyjonbrazil @@ -142,8 +146,24 @@ files: maintainers: resmo $filters/unicode_normalize.py: maintainers: Ajpantuso + $filters/to_days.yml: + maintainers: resmo + $filters/to_hours.yml: + maintainers: resmo + $filters/to_milliseconds.yml: + maintainers: resmo + $filters/to_minutes.yml: + maintainers: resmo + $filters/to_months.yml: + maintainers: resmo $filters/to_seconds.yml: maintainers: resmo + $filters/to_time_unit.yml: + maintainers: resmo + $filters/to_weeks.yml: + maintainers: resmo + $filters/to_years.yml: + maintainers: resmo $filters/version_sort.py: maintainers: ericzolf $inventories/: diff --git a/plugins/filter/counter.py b/plugins/filter/counter.py index ad957fce21..5d7f365f94 100644 --- a/plugins/filter/counter.py +++ b/plugins/filter/counter.py @@ -5,6 +5,35 @@ from __future__ import (absolute_import, division, print_function) __metaclass__ = type +DOCUMENTATION = ''' + name: counter + short_description: Counts hashable elements in a sequence + version_added: 4.3.0 + author: Rémy Keil (@keilr) + description: + - Counts hashable elements in a sequence. + options: + _input: + description: A sequence. + type: list + elements: any + required: true +''' + +EXAMPLES = ''' +- name: Count occurences + ansible.builtin.debug: + msg: >- + {{ [1, 'a', 2, 2, 'a', 'b', 'a'] | community.general.counter }} + # Produces: {1: 1, 'a': 3, 2: 2, 'b': 1} +''' + +RETURN = ''' + _value: + description: A dictionary with the elements of the sequence as keys, and their number of occurance in the sequence as values. + type: dictionary +''' + from ansible.errors import AnsibleFilterError from ansible.module_utils.common._collections_compat import Sequence from collections import Counter diff --git a/plugins/filter/dict.py b/plugins/filter/dict.py index 3d20e752b1..f18ec1bc24 100644 --- a/plugins/filter/dict.py +++ b/plugins/filter/dict.py @@ -6,6 +6,60 @@ from __future__ import absolute_import, division, print_function __metaclass__ = type +DOCUMENTATION = ''' + name: dict + short_description: Convert a list of tuples into a dictionary + version_added: 3.0.0 + author: Felix Fontein (@felixfontein) + description: + - Convert a list of tuples into a dictionary. This is a filter version of the C(dict) function. + options: + _input: + description: A list of tuples (with exactly two elements). + type: list + elements: tuple + required: true +''' + +EXAMPLES = ''' +- name: Convert list of tuples into dictionary + ansible.builtin.set_fact: + dictionary: "{{ [[1, 2], ['a', 'b']] | community.general.dict }}" + # Result is {1: 2, 'a': 'b'} + +- name: Create a list of dictionaries with map and the community.general.dict filter + ansible.builtin.debug: + msg: >- + {{ values | map('zip', ['k1', 'k2', 'k3']) + | map('map', 'reverse') + | map('community.general.dict') }} + vars: + values: + - - foo + - 23 + - a + - - bar + - 42 + - b + # Produces the following list of dictionaries: + # { + # "k1": "foo", + # "k2": 23, + # "k3": "a" + # }, + # { + # "k1": "bar", + # "k2": 42, + # "k3": "b" + # } +''' + +RETURN = ''' + _value: + description: Whether the module or action plugin denoted by the input exists. + type: boolean +''' + def dict_filter(sequence): '''Convert a list of tuples to a dictionary. diff --git a/plugins/filter/dict_kv.py b/plugins/filter/dict_kv.py index 7ce6c3e44a..1a0957819e 100644 --- a/plugins/filter/dict_kv.py +++ b/plugins/filter/dict_kv.py @@ -5,6 +5,38 @@ from __future__ import (absolute_import, division, print_function) __metaclass__ = type +DOCUMENTATION = ''' + name: dict_kv + short_description: Convert a value to a dictionary with a single key-value pair + version_added: 1.3.0 + author: Stanislav German-Evtushenko (@giner) + description: + - Convert a value to a dictionary with a single key-value pair. + positional: key + options: + _input: + description: The value for the single key-value pair. + type: any + required: true + key: + description: The key for the single key-value pair. + type: any + required: true +''' + +EXAMPLES = ''' +- name: Create a one-element dictionary from a value + ansible.builtin.debug: + msg: "{{ 'myvalue' | dict_kv('mykey') }}" + # Produces the dictionary {'mykey': 'myvalue'} +''' + +RETURN = ''' + _value: + description: A dictionary with a single key-value pair. + type: dictionary +''' + def dict_kv(value, key): '''Return a dictionary with a single key-value pair diff --git a/plugins/filter/from_csv.py b/plugins/filter/from_csv.py index b66d47699b..8043e36385 100644 --- a/plugins/filter/from_csv.py +++ b/plugins/filter/from_csv.py @@ -7,6 +7,78 @@ from __future__ import absolute_import, division, print_function __metaclass__ = type +DOCUMENTATION = ''' + name: from_csv + short_description: Converts CSV text input into list of dicts + version_added: 2.3.0 + author: Andrew Pantuso (@Ajpantuso) + description: + - Converts CSV text input into list of dictionaries. + options: + _input: + description: A string containing a CSV document. + type: string + required: true + dialect: + description: + - The CSV dialect to use when parsing the CSV file. + - Possible values include C(excel), C(excel-tab) or C(unix). + type: str + default: excel + fieldnames: + description: + - A list of field names for every column. + - This is needed if the CSV does not have a header. + type: list + elements: str + delimiter: + description: + - A one-character string used to separate fields. + - When using this parameter, you change the default value used by I(dialect). + - The default value depends on the dialect used. + type: str + skipinitialspace: + description: + - Whether to ignore any whitespaces immediately following the delimiter. + - When using this parameter, you change the default value used by I(dialect). + - The default value depends on the dialect used. + type: bool + strict: + description: + - Whether to raise an exception on bad CSV input. + - When using this parameter, you change the default value used by I(dialect). + - The default value depends on the dialect used. + type: bool +''' + +EXAMPLES = ''' +- name: Create a list of dictionaries with map and the community.general.dict filter + ansible.builtin.debug: + msg: >- + {{ csv_data | community.genera.from_csv(dialect='unix') }} + vars: + csv_data: | + Column 1,Value + foo,23 + bar,42 + # Produces the following list of dictionaries: + # { + # "Column 1": "foo", + # "Value": "23", + # }, + # { + # "Column 1": "bar", + # "Value": "42", + # } +''' + +RETURN = ''' + _value: + description: A list with one dictionary per row. + type: list + elements: dictionary +''' + from ansible.errors import AnsibleFilterError from ansible.module_utils.common.text.converters import to_native diff --git a/plugins/filter/groupby.py b/plugins/filter/groupby.py index a2a85aa905..386a8b44cf 100644 --- a/plugins/filter/groupby.py +++ b/plugins/filter/groupby.py @@ -5,6 +5,52 @@ from __future__ import (absolute_import, division, print_function) __metaclass__ = type +DOCUMENTATION = ''' + name: groupby_as_dict + short_description: Transform a sequence of dictionaries to a dictionary where the dictionaries are indexed by an attribute + version_added: 3.1.0 + author: Felix Fontein (@felixfontein) + description: + - Transform a sequence of dictionaries to a dictionary where the dictionaries are indexed by an attribute. + positional: attribute + options: + _input: + description: A list of dictionaries + type: list + elements: dictionary + required: true + attribute: + description: The attribute to use as the key. + type: str + required: true +''' + +EXAMPLES = ''' +- name: Arrange a list of dictionaries as a dictionary of dictionaries + ansible.builtin.debug: + msg: "{{ sequence | community.general.groupby_as_dict('key') }}" + vars: + sequence: + - key: value + foo: bar + - key: other_value + baz: bar + # Produces the following nested structure: + # + # value: + # key: value + # foo: bar + # other_value: + # key: other_value + # baz: bar +''' + +RETURN = ''' + _value: + description: A dictionary containing the dictionaries from the list as values. + type: dictionary +''' + from ansible.errors import AnsibleFilterError from ansible.module_utils.common._collections_compat import Mapping, Sequence diff --git a/plugins/filter/hashids_decode.yml b/plugins/filter/hashids_decode.yml new file mode 100644 index 0000000000..50e07abc8c --- /dev/null +++ b/plugins/filter/hashids_decode.yml @@ -0,0 +1,38 @@ +DOCUMENTATION: + name: hashids_decode + short_description: Decodes a sequence of numbers from a YouTube-like hash + version_added: 3.0.0 + author: Andrew Pantuso (@Ajpantuso) + description: + - Decodes a sequence of numbers from a YouTube-like hash. + options: + _input: + description: A YouTube-like hash. + type: string + required: true + salt: + description: + - String to use as salt when hashing. + type: str + default: excel + alphabet: + description: + - String of 16 or more unique characters to produce a hash. + type: list + elements: str + min_length: + description: + - Minimum length of hash produced. + type: integer + +EXAMPLES: | + - name: Convert hash to list of integers + ansible.builtin.debug: + msg: "{{ 'o2fXhV' | community.general.hashids_decode }}" + # Produces: [1, 2, 3] + +RETURN: + _value: + description: A list of integers. + type: list + elements: integer diff --git a/plugins/filter/hashids_encode.yml b/plugins/filter/hashids_encode.yml new file mode 100644 index 0000000000..69816aac30 --- /dev/null +++ b/plugins/filter/hashids_encode.yml @@ -0,0 +1,38 @@ +DOCUMENTATION: + name: hashids_encode + short_description: Encodes YouTube-like hashes from a sequence of integers + version_added: 3.0.0 + author: Andrew Pantuso (@Ajpantuso) + description: + - Encodes YouTube-like hashes from a sequence of integers. + options: + _input: + description: A list of integers. + type: list + elements: integer + required: true + salt: + description: + - String to use as salt when hashing. + type: str + default: excel + alphabet: + description: + - String of 16 or more unique characters to produce a hash. + type: list + elements: str + min_length: + description: + - Minimum length of hash produced. + type: integer + +EXAMPLES: | + - name: Convert list of integers to hash + ansible.builtin.debug: + msg: "{{ [1, 2, 3] | community.general.hashids_encode }}" + # Produces: 'o2fXhV' + +RETURN: + _value: + description: A YouTube-like hash. + type: string diff --git a/plugins/filter/jc.py b/plugins/filter/jc.py index f8fc4ac5bd..094da26632 100644 --- a/plugins/filter/jc.py +++ b/plugins/filter/jc.py @@ -21,6 +21,67 @@ from __future__ import (absolute_import, division, print_function) __metaclass__ = type +DOCUMENTATION = ''' + name: jc + short_description: Convert output of many shell commands and file-types to JSON + version_added: 1.1.0 + author: Kelly Brazil (@kellyjonbrazil) + description: + - Convert output of many shell commands and file-types to JSON. + - Uses the L(jc library,https://github.com/kellyjonbrazil/jc). + positional: parser + options: + _input: + description: The data to convert. + type: string + required: true + parser: + description: + - The correct parser for the input data. + - For exmaple C(ifconfig). + - See U(https://github.com/kellyjonbrazil/jc#parsers) for the latest list of parsers. + type: string + required: true + quiet: + description: Set to C(false) to not suppress warnings. + type: boolean + default: true + raw: + description: Set to C(true) to return pre-processed JSON. + type: boolean + default: false + requirements: + - jc (https://github.com/kellyjonbrazil/jc) +''' + +EXAMPLES = ''' +- name: Run command + ansible.builtin.command: uname -a + register: result + +- name: Convert command's result to JSON + ansible.builtin.debug: + msg: "{{ result.stdout | community.general.jc('uname') }}" + # Possible output: + # + # "msg": { + # "hardware_platform": "x86_64", + # "kernel_name": "Linux", + # "kernel_release": "4.15.0-112-generic", + # "kernel_version": "#113-Ubuntu SMP Thu Jul 9 23:41:39 UTC 2020", + # "machine": "x86_64", + # "node_name": "kbrazil-ubuntu", + # "operating_system": "GNU/Linux", + # "processor": "x86_64" + # } +''' + +RETURN = ''' + _value: + description: The processed output. + type: any +''' + from ansible.errors import AnsibleError, AnsibleFilterError import importlib diff --git a/plugins/filter/json_query.py b/plugins/filter/json_query.py index 9c835e8c71..e7fb891c6c 100644 --- a/plugins/filter/json_query.py +++ b/plugins/filter/json_query.py @@ -19,6 +19,107 @@ from __future__ import (absolute_import, division, print_function) __metaclass__ = type +DOCUMENTATION = ''' + name: json_query + short_description: Select a single element or a data subset from a complex data structure + description: + - This filter lets you query a complex JSON structure and iterate over it using a loop structure. + positional: expr + options: + _input: + description: + - The JSON data to query. + type: any + required: true + expr: + description: + - The query expression. + - See U(http://jmespath.org/examples.html) for examples. + type: string + required: true + requirements: + - jmespath +''' + +EXAMPLES = ''' +- name: Define data to work on in the examples below + ansible.builtin.set_fact: + 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 + +- name: Display all cluster names + ansible.builtin.debug: + var: item + loop: "{{ domain_definition | community.general.json_query('domain.cluster[*].name') }}" + +- name: Display all server names + ansible.builtin.debug: + var: item + loop: "{{ domain_definition | community.general.json_query('domain.server[*].name') }}" + +- 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" + +- 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(', ') }}" + +- name: Display all ports from cluster1 + ansible.builtin.debug: + var: item + loop: "{{ domain_definition | community.general.json_query('domain.server[?cluster==''cluster1''].port') }}" + +- 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}" + +- 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" + +- 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" +''' + +RETURN = ''' + _value: + description: Whether the module or action plugin denoted by the input exists. + type: any +''' + from ansible.errors import AnsibleError, AnsibleFilterError try: diff --git a/plugins/filter/list.py b/plugins/filter/list.py index 005e4b7c70..74ad9fb9de 100644 --- a/plugins/filter/list.py +++ b/plugins/filter/list.py @@ -5,6 +5,97 @@ from __future__ import (absolute_import, division, print_function) __metaclass__ = type +DOCUMENTATION = ''' + name: lists_mergeby + short_description: Merge two or more lists of dictionaries by a given attribute + version_added: 2.0.0 + author: Vladimir Botka (@vbotka) + description: + - Merge two or more lists by attribute I(index). Optional parameters 'recursive' and 'list_merge' + control the merging of the lists in values. The function merge_hash from ansible.utils.vars + is used. To learn details on how to use the parameters 'recursive' and 'list_merge' see + Ansible User's Guide chapter "Using filters to manipulate data" section "Combining + hashes/dictionaries". + positional: another_list, index + options: + _input: + description: A list of dictionaries. + type: list + elements: dictionary + required: true + another_list: + description: Another list of dictionaries. This parameter can be specified multiple times. + type: list + elements: dictionary + index: + description: + - The dictionary key that must be present in every dictionary in every list that is used to + merge the lists. + type: string + required: true + recursive: + description: + - 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)." + type: boolean + default: false + list_merge: + description: + - Modifies the behaviour when the dictionaries (hashes) to merge contain arrays/lists. + type: string + default: replace + choices: + - replace + - keep + - append + - prepend + - append_rp + - prepend_rp +''' + +EXAMPLES = ''' +- name: Create a list of dictionaries with map and the community.general.dict filter + ansible.builtin.debug: + msg: >- + {{ list1 | community.general.lists_mergeby( + list2, + 'index', + recursive=True, + list_merge='append' + ) }}" + vars: + list1: + - index: a + value: 123 + - index: b + value: 42 + list2: + - index: a + foo: bar + - index: c + foo: baz + # Produces the following list of dictionaries: + # { + # "index": "a", + # "foo": "bar", + # "value": 123 + # }, + # { + # "index": "b", + # "value": 42 + # }, + # { + # "index": "c", + # "foo": "baz" + # } +''' + +RETURN = ''' + _value: + description: Whether the module or action plugin denoted by the input exists. + type: boolean +''' + from ansible.errors import AnsibleFilterError from ansible.module_utils.six import string_types from ansible.module_utils.common._collections_compat import Mapping, Sequence diff --git a/plugins/filter/random_mac.py b/plugins/filter/random_mac.py index fdcff4d9da..544cd0aa0b 100644 --- a/plugins/filter/random_mac.py +++ b/plugins/filter/random_mac.py @@ -40,15 +40,21 @@ DOCUMENTATION = ''' EXAMPLES = ''' - name: Random MAC given a prefix - debug: + ansible.builtin.debug: msg: "{{ '52:54:00' | community.general.random_mac }}" # => '52:54:00:ef:1c:03' - name: With a seed - debug: + ansible.builtin.debug: msg: "{{ '52:54:00' | community.general.random_mac(seed=inventory_hostname) }}" ''' +RETURN = ''' + _value: + description: The generated MAC. + type: string +''' + import re from random import Random, SystemRandom diff --git a/plugins/filter/to_days.yml b/plugins/filter/to_days.yml new file mode 100644 index 0000000000..e06c9463dc --- /dev/null +++ b/plugins/filter/to_days.yml @@ -0,0 +1,40 @@ +DOCUMENTATION: + name: to_days + short_description: Converte a duration string to days + version_added: 0.2.0 + description: + - Parse a human readable time duration string and convert to days. + options: + _input: + description: + - The time string to convert. + - Can use the units C(y) and C(year) for a year, C(mo) and C(month) for a month, C(w) and C(week) for a week, + C(d) and C(day) for a day, C(h) and C(hour) for a hour, C(m), C(min) and C(minute) for minutes, C(s), C(sec) + and C(second) for seconds, C(ms), C(msec), C(msecond) and C(millisecond) for milliseconds. The suffix C(s) + can be added to a unit as well, so C(seconds) is the same as C(second). + - Valid strings are space separated combinations of an integer with an optional minus sign and a unit. + - Examples are C(1h), C(-5m), and C(3h -5m 6s). + type: string + required: true + year: + description: + - Number of days per year. + default: 365 + type: float + month: + description: + - Number of days per month. + default: 30 + type: float + author: + - René Moser (@resmo) + +EXAMPLES: | + - name: Convert a duration into days + ansible.builtin.debug: + msg: "{{ '1y 7m 5d 30h' | community.general.to_days }}" + +RETURN: + _value: + description: Number of days. + type: float diff --git a/plugins/filter/to_hours.yml b/plugins/filter/to_hours.yml new file mode 100644 index 0000000000..976c3a6adf --- /dev/null +++ b/plugins/filter/to_hours.yml @@ -0,0 +1,40 @@ +DOCUMENTATION: + name: to_hours + short_description: Converte a duration string to hours + version_added: 0.2.0 + description: + - Parse a human readable time duration string and convert to hours. + options: + _input: + description: + - The time string to convert. + - Can use the units C(y) and C(year) for a year, C(mo) and C(month) for a month, C(w) and C(week) for a week, + C(d) and C(day) for a day, C(h) and C(hour) for a hour, C(m), C(min) and C(minute) for minutes, C(s), C(sec) + and C(second) for seconds, C(ms), C(msec), C(msecond) and C(millisecond) for milliseconds. The suffix C(s) + can be added to a unit as well, so C(seconds) is the same as C(second). + - Valid strings are space separated combinations of an integer with an optional minus sign and a unit. + - Examples are C(1h), C(-5m), and C(3h -5m 6s). + type: string + required: true + year: + description: + - Number of days per year. + default: 365 + type: float + month: + description: + - Number of days per month. + default: 30 + type: float + author: + - René Moser (@resmo) + +EXAMPLES: | + - name: Convert a duration into hours + ansible.builtin.debug: + msg: "{{ '7d 30h 20m 10s 123ms' | community.general.to_hours }}" + +RETURN: + _value: + description: Number of hours. + type: float diff --git a/plugins/filter/to_milliseconds.yml b/plugins/filter/to_milliseconds.yml new file mode 100644 index 0000000000..a4c59ce958 --- /dev/null +++ b/plugins/filter/to_milliseconds.yml @@ -0,0 +1,40 @@ +DOCUMENTATION: + name: to_milliseconds + short_description: Converte a duration string to milliseconds + version_added: 0.2.0 + description: + - Parse a human readable time duration string and convert to milliseconds. + options: + _input: + description: + - The time string to convert. + - Can use the units C(y) and C(year) for a year, C(mo) and C(month) for a month, C(w) and C(week) for a week, + C(d) and C(day) for a day, C(h) and C(hour) for a hour, C(m), C(min) and C(minute) for minutes, C(s), C(sec) + and C(second) for seconds, C(ms), C(msec), C(msecond) and C(millisecond) for milliseconds. The suffix C(s) + can be added to a unit as well, so C(seconds) is the same as C(second). + - Valid strings are space separated combinations of an integer with an optional minus sign and a unit. + - Examples are C(1h), C(-5m), and C(3h -5m 6s). + type: string + required: true + year: + description: + - Number of days per year. + default: 365 + type: float + month: + description: + - Number of days per month. + default: 30 + type: float + author: + - René Moser (@resmo) + +EXAMPLES: | + - name: Convert a duration into milliseconds + ansible.builtin.debug: + msg: "{{ '30h 20m 10s 123ms' | community.general.to_milliseconds }}" + +RETURN: + _value: + description: Number of milliseconds. + type: float diff --git a/plugins/filter/to_minutes.yml b/plugins/filter/to_minutes.yml new file mode 100644 index 0000000000..7dfeada29f --- /dev/null +++ b/plugins/filter/to_minutes.yml @@ -0,0 +1,40 @@ +DOCUMENTATION: + name: to_minutes + short_description: Converte a duration string to minutes + version_added: 0.2.0 + description: + - Parse a human readable time duration string and convert to minutes. + options: + _input: + description: + - The time string to convert. + - Can use the units C(y) and C(year) for a year, C(mo) and C(month) for a month, C(w) and C(week) for a week, + C(d) and C(day) for a day, C(h) and C(hour) for a hour, C(m), C(min) and C(minute) for minutes, C(s), C(sec) + and C(second) for seconds, C(ms), C(msec), C(msecond) and C(millisecond) for milliseconds. The suffix C(s) + can be added to a unit as well, so C(seconds) is the same as C(second). + - Valid strings are space separated combinations of an integer with an optional minus sign and a unit. + - Examples are C(1h), C(-5m), and C(3h -5m 6s). + type: string + required: true + year: + description: + - Number of days per year. + default: 365 + type: float + month: + description: + - Number of days per month. + default: 30 + type: float + author: + - René Moser (@resmo) + +EXAMPLES: | + - name: Convert a duration into minutes + ansible.builtin.debug: + msg: "{{ '30h 20m 10s 123ms' | community.general.to_minutes }}" + +RETURN: + _value: + description: Number of minutes. + type: float diff --git a/plugins/filter/to_months.yml b/plugins/filter/to_months.yml new file mode 100644 index 0000000000..84a94d2526 --- /dev/null +++ b/plugins/filter/to_months.yml @@ -0,0 +1,40 @@ +DOCUMENTATION: + name: to_months + short_description: Converte a duration string to months + version_added: 0.2.0 + description: + - Parse a human readable time duration string and convert to months. + options: + _input: + description: + - The time string to convert. + - Can use the units C(y) and C(year) for a year, C(mo) and C(month) for a month, C(w) and C(week) for a week, + C(d) and C(day) for a day, C(h) and C(hour) for a hour, C(m), C(min) and C(minute) for minutes, C(s), C(sec) + and C(second) for seconds, C(ms), C(msec), C(msecond) and C(millisecond) for milliseconds. The suffix C(s) + can be added to a unit as well, so C(seconds) is the same as C(second). + - Valid strings are space separated combinations of an integer with an optional minus sign and a unit. + - Examples are C(1h), C(-5m), and C(3h -5m 6s). + type: string + required: true + year: + description: + - Number of days per year. + default: 365 + type: float + month: + description: + - Number of days per month. + default: 30 + type: float + author: + - René Moser (@resmo) + +EXAMPLES: | + - name: Convert a duration into months + ansible.builtin.debug: + msg: "{{ '1y 7m 5d 30h' | community.general.to_months }}" + +RETURN: + _value: + description: Number of months. + type: float diff --git a/plugins/filter/to_seconds.yml b/plugins/filter/to_seconds.yml index af6ae82b09..0b09e98456 100644 --- a/plugins/filter/to_seconds.yml +++ b/plugins/filter/to_seconds.yml @@ -1,9 +1,9 @@ DOCUMENTATION: - name: community.general.to_seconds - short_description: Converte a date/time string to seconds + name: to_seconds + short_description: Converte a duration string to seconds version_added: 0.2.0 description: - - Parse a human readable time string and convert to seconds. + - Parse a human readable time duration string and convert to seconds. options: _input: description: @@ -26,12 +26,12 @@ DOCUMENTATION: - Number of days per month. default: 30 type: float - authors: + author: - René Moser (@resmo) EXAMPLES: | - name: Convert a duration into seconds - debug: + ansible.builtin.debug: msg: "{{ '30h 20m 10s 123ms' | community.general.to_seconds }}" RETURN: diff --git a/plugins/filter/to_time_unit.yml b/plugins/filter/to_time_unit.yml new file mode 100644 index 0000000000..43debef917 --- /dev/null +++ b/plugins/filter/to_time_unit.yml @@ -0,0 +1,85 @@ +DOCUMENTATION: + name: to_time_unit + short_description: Converte a duration string to the given time unit + version_added: 0.2.0 + description: + - Parse a human readable time duration string and convert to the given time unit. + positional: unit + options: + _input: + description: + - The time string to convert. + - Can use the units C(y) and C(year) for a year, C(mo) and C(month) for a month, C(w) and C(week) for a week, + C(d) and C(day) for a day, C(h) and C(hour) for a hour, C(m), C(min) and C(minute) for minutes, C(s), C(sec) + and C(second) for seconds, C(ms), C(msec), C(msecond) and C(millisecond) for milliseconds. The suffix C(s) + can be added to a unit as well, so C(seconds) is the same as C(second). + - Valid strings are space separated combinations of an integer with an optional minus sign and a unit. + - Examples are C(1h), C(-5m), and C(3h -5m 6s). + type: string + required: true + unit: + description: + - Time unit to convert the duration to. + default: ms + choices: + - millisecond + - milliseconds + - ms + - msec + - msecs + - msecond + - mseconds + - s + - sec + - secs + - second + - seconds + - h + - hour + - hours + - hs + - m + - min + - mins + - minute + - minutes + - ms + - d + - ds + - day + - days + - w + - ws + - week + - weeks + - mo + - mos + - month + - months + - y + - ys + - year + - years + type: string + year: + description: + - Number of days per year. + default: 365 + type: float + month: + description: + - Number of days per month. + default: 30 + type: float + author: + - René Moser (@resmo) + +EXAMPLES: | + - name: Convert a duration into seconds + ansible.builtin.debug: + msg: "{{ '1053d 17h 53m -10s 391ms' | community.general.to_time_unit('s') }}" + +RETURN: + _value: + description: Number of time units. + type: float diff --git a/plugins/filter/to_weeks.yml b/plugins/filter/to_weeks.yml new file mode 100644 index 0000000000..4626e35662 --- /dev/null +++ b/plugins/filter/to_weeks.yml @@ -0,0 +1,40 @@ +DOCUMENTATION: + name: to_weeks + short_description: Converte a duration string to weeks + version_added: 0.2.0 + description: + - Parse a human readable time duration string and convert to weeks. + options: + _input: + description: + - The time string to convert. + - Can use the units C(y) and C(year) for a year, C(mo) and C(month) for a month, C(w) and C(week) for a week, + C(d) and C(day) for a day, C(h) and C(hour) for a hour, C(m), C(min) and C(minute) for minutes, C(s), C(sec) + and C(second) for seconds, C(ms), C(msec), C(msecond) and C(millisecond) for milliseconds. The suffix C(s) + can be added to a unit as well, so C(seconds) is the same as C(second). + - Valid strings are space separated combinations of an integer with an optional minus sign and a unit. + - Examples are C(1h), C(-5m), and C(3h -5m 6s). + type: string + required: true + year: + description: + - Number of days per year. + default: 365 + type: float + month: + description: + - Number of days per month. + default: 30 + type: float + author: + - René Moser (@resmo) + +EXAMPLES: | + - name: Convert a duration into weeks + ansible.builtin.debug: + msg: "{{ '1y 7m 5d 30h' | community.general.to_weeks }}" + +RETURN: + _value: + description: Number of weeks. + type: float diff --git a/plugins/filter/to_years.yml b/plugins/filter/to_years.yml new file mode 100644 index 0000000000..4fb54b8753 --- /dev/null +++ b/plugins/filter/to_years.yml @@ -0,0 +1,40 @@ +DOCUMENTATION: + name: to_years + short_description: Converte a duration string to years + version_added: 0.2.0 + description: + - Parse a human readable time duration string and convert to years. + options: + _input: + description: + - The time string to convert. + - Can use the units C(y) and C(year) for a year, C(mo) and C(month) for a month, C(w) and C(week) for a week, + C(d) and C(day) for a day, C(h) and C(hour) for a hour, C(m), C(min) and C(minute) for minutes, C(s), C(sec) + and C(second) for seconds, C(ms), C(msec), C(msecond) and C(millisecond) for milliseconds. The suffix C(s) + can be added to a unit as well, so C(seconds) is the same as C(second). + - Valid strings are space separated combinations of an integer with an optional minus sign and a unit. + - Examples are C(1h), C(-5m), and C(3h -5m 6s). + type: string + required: true + year: + description: + - Number of days per year. + default: 365 + type: float + month: + description: + - Number of days per month. + default: 30 + type: float + author: + - René Moser (@resmo) + +EXAMPLES: | + - name: Convert a duration into years + ansible.builtin.debug: + msg: "{{ '1053d 30h' | community.general.to_years }}" + +RETURN: + _value: + description: Number of years. + type: float diff --git a/plugins/filter/unicode_normalize.py b/plugins/filter/unicode_normalize.py index 9afbf29e3f..30aed2005a 100644 --- a/plugins/filter/unicode_normalize.py +++ b/plugins/filter/unicode_normalize.py @@ -6,6 +6,46 @@ from __future__ import absolute_import, division, print_function __metaclass__ = type +DOCUMENTATION = ''' + name: unicode_normalize + short_description: Normalizes unicode strings to facilitate comparison of characters with normalized forms + version_added: 3.7.0 + author: Andrew Pantuso (@Ajpantuso) + description: + - Normalizes unicode strings to facilitate comparison of characters with normalized forms. + positional: form + options: + _input: + description: A unicode string. + type: string + required: true + form: + description: + - The normal form to use. + - See U(https://docs.python.org/3/library/unicodedata.html#unicodedata.normalize) for details. + type: string + default: NFC + choices: + - NFC + - NFD + - NFKC + - NFKD +''' + +EXAMPLES = ''' +- name: Normalize unicode string + ansible.builtin.set_fact: + dictionary: "{{ 'ä' | community.general.unicode_normalize('NFKD') }}" + # The resulting string has length 2: one letter is 'a', the other + # the diacritic combiner. +''' + +RETURN = ''' + _value: + description: The normalized unicode string of the specified normal form. + type: string +''' + from unicodedata import normalize from ansible.errors import AnsibleFilterError, AnsibleFilterTypeError diff --git a/plugins/filter/version_sort.py b/plugins/filter/version_sort.py index ac62ef8c8f..9d21691085 100644 --- a/plugins/filter/version_sort.py +++ b/plugins/filter/version_sort.py @@ -5,6 +5,35 @@ from __future__ import (absolute_import, division, print_function) __metaclass__ = type +DOCUMENTATION = ''' + name: version_sort + short_description: Sort a list according to version order instead of pure alphabetical one + version_added: 2.2.0 + author: Eric L. (@ericzolf) + description: + - Sort a list according to version order instead of pure alphabetical one. + options: + _input: + description: A list of strings to sort. + type: list + elements: string + required: true +''' + +EXAMPLES = ''' +- name: Convert list of tuples into dictionary + ansible.builtin.set_fact: + dictionary: "{{ ['2.1', '2.10', '2.9'] | community.general.version_sort }}" + # Result is ['2.1', '2.9', '2.10'] +''' + +RETURN = ''' + _value: + description: The list of strings sorted by version. + type: list + elements: string +''' + from ansible_collections.community.general.plugins.module_utils.version import LooseVersion diff --git a/plugins/lookup/cyberarkpassword.py b/plugins/lookup/cyberarkpassword.py index 80323c10fd..663ec38808 100644 --- a/plugins/lookup/cyberarkpassword.py +++ b/plugins/lookup/cyberarkpassword.py @@ -57,14 +57,19 @@ EXAMPLES = """ """ RETURN = """ - password: - description: - - The actual value stored - passprops: - description: properties assigned to the entry - type: dictionary - passwordchangeinprocess: - description: did the password change? +_result: + description: A list containing one dictionary. + type: list + elements: dictionary + contains: + password: + description: + - The actual value stored + passprops: + description: properties assigned to the entry + type: dictionary + passwordchangeinprocess: + description: did the password change? """ import os diff --git a/plugins/modules/files/read_csv.py b/plugins/modules/files/read_csv.py index 2d5644db2e..484a365e4c 100644 --- a/plugins/modules/files/read_csv.py +++ b/plugins/modules/files/read_csv.py @@ -48,19 +48,19 @@ options: delimiter: description: - A one-character string used to separate fields. - - When using this parameter, you change the default value used by C(dialect). + - When using this parameter, you change the default value used by I(dialect). - The default value depends on the dialect used. type: str skipinitialspace: description: - Whether to ignore any whitespaces immediately following the delimiter. - - When using this parameter, you change the default value used by C(dialect). + - When using this parameter, you change the default value used by I(dialect). - The default value depends on the dialect used. type: bool strict: description: - Whether to raise an exception on bad CSV input. - - When using this parameter, you change the default value used by C(dialect). + - When using this parameter, you change the default value used by I(dialect). - The default value depends on the dialect used. type: bool notes: diff --git a/plugins/test/a_module.py b/plugins/test/a_module.py index 36c13ffabd..c6ed2fffcd 100644 --- a/plugins/test/a_module.py +++ b/plugins/test/a_module.py @@ -4,6 +4,39 @@ from __future__ import (absolute_import, division, print_function) __metaclass__ = type +DOCUMENTATION = ''' + name: a_module + short_description: Test whether a given string refers to an existing module or action plugin + version_added: 4.0.0 + author: Felix Fontein (@felixfontein) + description: + - Test 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. + options: + _input: + description: A string denoting a fully qualified collection name (FQCN) of a module or action plugin. + type: string + required: true +''' + +EXAMPLES = ''' +- name: Make sure that community.aws.route53 is available + ansible.builtin.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 + ansible.builtin.assert: + that: + - "'community.general.does_not_exist' is not community.general.a_module" +''' + +RETURN = ''' + _value: + description: Whether the module or action plugin denoted by the input exists. + type: boolean +''' from ansible.plugins.loader import action_loader, module_loader