Add recursive get key from dict
The docker_config (and other data) that we have in tripleo is a complex dict but we need a way to fetch a specific key from a larget structure. This change adds a filter called recursive_get_key_from_dict which will traverse all the dictionaries in a given dataset and return a list containing all the values of the requested key. Change-Id: I952df4d4a7700eccdb2d49a7fba271518058771a
This commit is contained in:
parent
97fd9db251
commit
c072a6bf9d
|
@ -29,7 +29,8 @@ class FilterModule(object):
|
|||
'haskey': self.haskey,
|
||||
'list_of_keys': self.list_of_keys,
|
||||
'container_exec_cmd': self.container_exec_cmd,
|
||||
'get_key_from_dict': self.get_key_from_dict
|
||||
'get_key_from_dict': self.get_key_from_dict,
|
||||
'recursive_get_key_from_dict': self.recursive_get_key_from_dict
|
||||
}
|
||||
|
||||
def subsort(self, dict_to_sort, attribute, null_value=0):
|
||||
|
@ -218,6 +219,22 @@ class FilterModule(object):
|
|||
returned_list.append(value)
|
||||
return sorted(returned_list)
|
||||
|
||||
def recursive_get_key_from_dict(self, data, key):
|
||||
"""Recursively return values for keys in a dict
|
||||
|
||||
This filter will traverse all the dictionaries in the provided
|
||||
dictionary and return any values for a specified key. This is useful
|
||||
if you have a complex dictionary containing dynamic keys but want to
|
||||
fetch a commonly named key.
|
||||
"""
|
||||
val = []
|
||||
if key in data:
|
||||
val.append(data.get(key))
|
||||
for k, v in data.items():
|
||||
if isinstance(v, dict):
|
||||
val.extend(self.recursive_get_key_from_dict(v, key))
|
||||
return val
|
||||
|
||||
def list_or_dict_arg(self, data, cmd, key, arg):
|
||||
"""Utility to build a command and its argument with list or dict data.
|
||||
|
||||
|
|
|
@ -367,6 +367,26 @@ class TestHelperFilters(tests_base.TestCase):
|
|||
default='service')
|
||||
self.assertEqual(result, expected_list)
|
||||
|
||||
def test_recursive_get_key_from_dict(self):
|
||||
data = {
|
||||
'step': {'container': {'name': 'foo', 'image': 'bar'},
|
||||
'other_container': {'name': 'meh', 'image': 'baz'}
|
||||
}
|
||||
}
|
||||
expected_list = ['bar', 'baz']
|
||||
result = self.filters.recursive_get_key_from_dict(data, 'image')
|
||||
self.assertEqual(result, expected_list)
|
||||
|
||||
def test_recursive_get_key_from_dict_multiple_levels(self):
|
||||
data = {
|
||||
'a': {'b': {'val': 1},
|
||||
'c': {'val': 2, 'd': {'val': 3}}
|
||||
}
|
||||
}
|
||||
expected_list = [1, 2, 3]
|
||||
result = self.filters.recursive_get_key_from_dict(data, 'val')
|
||||
self.assertEqual(result, expected_list)
|
||||
|
||||
def test_container_exec_cmd(self):
|
||||
data = {
|
||||
"action": "exec",
|
||||
|
|
Loading…
Reference in New Issue