diff --git a/changelogs/fragments/1264-dict_kv-new-filter.yaml b/changelogs/fragments/1264-dict_kv-new-filter.yaml new file mode 100644 index 0000000000..0981113124 --- /dev/null +++ b/changelogs/fragments/1264-dict_kv-new-filter.yaml @@ -0,0 +1,2 @@ +minor_changes: +- "Add new filter plugin ``dict_kv`` which returns a single key-value pair from two arguments. Useful for generating complex dictionaries without using loops. For example ``'value' | community.general.dict_kv('key'))`` evaluates to ``{'key': 'value'}`` (https://github.com/ansible-collections/community.general/pull/1264)." diff --git a/plugins/filter/dict_kv.py b/plugins/filter/dict_kv.py new file mode 100644 index 0000000000..b2124ed767 --- /dev/null +++ b/plugins/filter/dict_kv.py @@ -0,0 +1,70 @@ +# Copyright (C) 2020 Stanislav German-Evtushenko (@giner) +# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) + +from __future__ import (absolute_import, division, print_function) +__metaclass__ = type + + +def dict_kv(value, key): + '''Return a dictionary with a single key-value pair + + Example: + + - hosts: localhost + gather_facts: false + vars: + myvar: myvalue + tasks: + - debug: + msg: "{{ myvar | dict_kv('thatsmyvar') }}" + + produces: + + ok: [localhost] => { + "msg": { + "thatsmyvar": "myvalue" + } + } + + Example 2: + + - hosts: localhost + gather_facts: false + vars: + common_config: + type: host + database: all + myservers: + - server1 + - server2 + tasks: + - debug: + msg: "{{ myservers | map('dict_kv', 'server') | map('combine', common_config) }}" + + produces: + + ok: [localhost] => { + "msg": [ + { + "database": "all", + "server": "server1", + "type": "host" + }, + { + "database": "all", + "server": "server2", + "type": "host" + } + ] + } + ''' + return {key: value} + + +class FilterModule(object): + ''' Query filter ''' + + def filters(self): + return { + 'dict_kv': dict_kv + } diff --git a/tests/integration/targets/filter_dict_kv/aliases b/tests/integration/targets/filter_dict_kv/aliases new file mode 100644 index 0000000000..f04737b845 --- /dev/null +++ b/tests/integration/targets/filter_dict_kv/aliases @@ -0,0 +1,2 @@ +shippable/posix/group2 +skip/python2.6 # filters are controller only, and we no longer support Python 2.6 on the controller diff --git a/tests/integration/targets/filter_dict_kv/tasks/main.yml b/tests/integration/targets/filter_dict_kv/tasks/main.yml new file mode 100644 index 0000000000..871962e93d --- /dev/null +++ b/tests/integration/targets/filter_dict_kv/tasks/main.yml @@ -0,0 +1,10 @@ +--- +#################################################################### +# WARNING: These are designed specifically for Ansible tests # +# and should not be used as examples of how to write Ansible roles # +#################################################################### + +- name: test dict_kv filter + assert: + that: + - "('value' | community.general.dict_kv('key')) == {'key': 'value'}"