Repository: ansible/ansible

Issue:
New lookup plugin: merged_dicts
Input:  a list of dictionaries (order is important)
Output: a single dictionary with all the keys from the source
dictionaries and values from the last dictionary in the input list which
contained the given key



Discussion:
A rewrite of the previously closed #11137. This is my first pull request for ansible so please test thoroughly and comment.

@bcoca now that the feature_pull_request has been added does that mean that it will be merged or there's a process that it needs to go through ?

just need to review and test on our side, sorry for the delays but we are going through a very large backlog

No worries. I understand. Thank you for the update.

@bcoca any chance you've had a moment to look at merging this?

it is on my list, also to compare to another request that adds dict support to union/difference/intersection that might overlap with this

Hey @bcoca,

I was wondering if there's any development on this pull request. It has been more than a month. Any ETA?

Thank you,
Rumen Telbizov

sorry, have not had time to come back, its on my short list, but we do have a big backlog we are running through.

Thanks for the reply @bcoca. Since adding my own lookup plugin in ansible 1.9 is broken and doesn't work I can't use this functionality even if I wanted to add my own plugin bundled withing a role. I understand that the bug will be fixed in ansible 2.0 and then I wouldn't need this merged that urgently. 

Two questions are on my mind and I'd appreciate if you can comment:
- What would be a rough ETA on ansible 2.0 release?
- If you merge this pull request before 2.0 release would the plugin be available in ansible 1.9 as well?

Thank you in advance @bcoca.

Regards,
Rumen Telbizov

new features are only added to new releases, not backported, so the plugin is not planned for 1.9 because of this.

2.0 is expected at end of the month or possibly August, depends on critical bugs more than anything else.

Thank you for the update.

Note that this is related to, but not the same as, the functionality proposed in #7872. I'm not sure I like the idea of this being implemented as a lookup plugin, though. Seems more natural to have a filter that allows you to merge, and then lookup as normal.


Resolving patch:
diff --git a/lib/ansible/plugins/filter/core.py b/lib/ansible/plugins/filter/core.py
--- a/lib/ansible/plugins/filter/core.py
+++ b/lib/ansible/plugins/filter/core.py
@@ -19,6 +19,7 @@
 
 import sys
 import base64
+import itertools
 import json
 import os.path
 import ntpath
@@ -42,6 +43,7 @@
 from ansible.parsing.yaml.dumper import AnsibleDumper
 from ansible.utils.hashing import md5s, checksum_s
 from ansible.utils.unicode import unicode_wrap, to_unicode
+from ansible.utils.vars import merge_hash
 
 try:
     import passlib.hash
@@ -231,6 +233,20 @@ def mandatory(a):
         raise errors.AnsibleFilterError('Mandatory variable not defined.')
     return a
 
+def combine(*terms, **kwargs):
+    recursive = kwargs.get('recursive', False)
+    if len(kwargs) > 1 or (len(kwargs) == 1 and 'recursive' not in kwargs):
+        raise errors.AnsibleFilterError("'recursive' is the only valid keyword argument")
+
+    for t in terms:
+        if not isinstance(t, dict):
+            raise errors.AnsibleFilterError("|combine expects dictionaries, got " + repr(t))
+
+    if recursive:
+        return reduce(merge_hash, terms)
+    else:
+        return dict(itertools.chain(*map(dict.iteritems, terms)))
+
 class FilterModule(object):
     ''' Ansible core jinja2 filters '''
 
@@ -300,4 +316,7 @@ def filters(self):
             'shuffle': randomize_list,
             # undefined
             'mandatory': mandatory,
+
+            # merge dicts
+            'combine': combine,
         }


Test patch: