diff --git a/tripleo_ansible/ansible_plugins/filter/helpers.py b/tripleo_ansible/ansible_plugins/filter/helpers.py index f94349565..5e548ca76 100644 --- a/tripleo_ansible/ansible_plugins/filter/helpers.py +++ b/tripleo_ansible/ansible_plugins/filter/helpers.py @@ -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. diff --git a/tripleo_ansible/tests/plugins/filter/test_helpers.py b/tripleo_ansible/tests/plugins/filter/test_helpers.py index 769456a1e..abfcfabe7 100644 --- a/tripleo_ansible/tests/plugins/filter/test_helpers.py +++ b/tripleo_ansible/tests/plugins/filter/test_helpers.py @@ -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",