From 659ef811a3e6396bfa92d07977a71f90e25b8c2c Mon Sep 17 00:00:00 2001 From: "patchback[bot]" <45432694+patchback[bot]@users.noreply.github.com> Date: Tue, 24 Nov 2020 06:23:37 +0100 Subject: [PATCH] Add filter dict_kv (#1264) (#1374) - Add filter `dict_kv` which returns a single key-value pair dictionary created from two arguments Example 1 ``` - hosts: localhost gather_facts: false vars: myvar: myvalue tasks: - debug: msg: "{{ myvar | dict_kv('thatsmyvar') }}" OUTPUT: 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) }}" OUTPUT: ok: [localhost] => { "msg": [ { "database": "all", "server": "server1", "type": "host" }, { "database": "all", "server": "server2", "type": "host" } ] } ``` (cherry picked from commit 44fd157a2b8a0dabbcac21c747550f6eefd7bb61) Co-authored-by: Stanislav German-Evtushenko --- .../fragments/1264-dict_kv-new-filter.yaml | 2 + plugins/filter/dict_kv.py | 70 +++++++++++++++++++ .../targets/filter_dict_kv/aliases | 2 + .../targets/filter_dict_kv/tasks/main.yml | 10 +++ 4 files changed, 84 insertions(+) create mode 100644 changelogs/fragments/1264-dict_kv-new-filter.yaml create mode 100644 plugins/filter/dict_kv.py create mode 100644 tests/integration/targets/filter_dict_kv/aliases create mode 100644 tests/integration/targets/filter_dict_kv/tasks/main.yml 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'}"