2021-08-07 15:59:29 +02:00
|
|
|
# -*- coding: utf-8 -*-
|
2020-03-09 10:11:07 +01:00
|
|
|
# (c) 2013, Serge van Ginderachter <serge@vanginderachter.be>
|
|
|
|
# (c) 2017 Ansible Project
|
|
|
|
# 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
|
|
|
|
|
|
|
|
DOCUMENTATION = '''
|
2021-01-12 07:12:03 +01:00
|
|
|
name: flattened
|
2020-09-28 21:21:51 +02:00
|
|
|
author: Serge van Ginderachter (!UNKNOWN) <serge@vanginderachter.be>
|
2020-03-09 10:11:07 +01:00
|
|
|
short_description: return single list completely flattened
|
|
|
|
description:
|
|
|
|
- given one or more lists, this lookup will flatten any list elements found recursively until only 1 list is left.
|
|
|
|
options:
|
|
|
|
_terms:
|
|
|
|
description: lists to flatten
|
|
|
|
required: True
|
|
|
|
notes:
|
|
|
|
- unlike 'items' which only flattens 1 level, this plugin will continue to flatten until it cannot find lists anymore.
|
|
|
|
- aka highlander plugin, there can only be one (list).
|
|
|
|
'''
|
|
|
|
|
|
|
|
EXAMPLES = """
|
|
|
|
- name: "'unnest' all elements into single list"
|
2020-08-08 22:04:34 +02:00
|
|
|
ansible.builtin.debug:
|
2022-01-09 12:29:19 +01:00
|
|
|
msg: "all in one list {{lookup('community.general.flattened', [1,2,3,[5,6]], ['a','b','c'], [[5,6,1,3], [34,'a','b','c']])}}"
|
2020-03-09 10:11:07 +01:00
|
|
|
"""
|
|
|
|
|
|
|
|
RETURN = """
|
|
|
|
_raw:
|
|
|
|
description:
|
|
|
|
- flattened list
|
|
|
|
type: list
|
|
|
|
"""
|
|
|
|
from ansible.errors import AnsibleError
|
|
|
|
from ansible.module_utils.six import string_types
|
|
|
|
from ansible.plugins.lookup import LookupBase
|
|
|
|
from ansible.utils.listify import listify_lookup_plugin_terms
|
|
|
|
|
|
|
|
|
|
|
|
class LookupModule(LookupBase):
|
|
|
|
|
|
|
|
def _check_list_of_one_list(self, term):
|
|
|
|
# make sure term is not a list of one (list of one..) item
|
|
|
|
# return the final non list item if so
|
|
|
|
|
|
|
|
if isinstance(term, list) and len(term) == 1:
|
|
|
|
term = term[0]
|
|
|
|
if isinstance(term, list):
|
|
|
|
term = self._check_list_of_one_list(term)
|
|
|
|
|
|
|
|
return term
|
|
|
|
|
|
|
|
def _do_flatten(self, terms, variables):
|
|
|
|
|
|
|
|
ret = []
|
|
|
|
for term in terms:
|
|
|
|
term = self._check_list_of_one_list(term)
|
|
|
|
|
|
|
|
if term == 'None' or term == 'null':
|
|
|
|
# ignore undefined items
|
|
|
|
break
|
|
|
|
|
|
|
|
if isinstance(term, string_types):
|
|
|
|
# convert a variable to a list
|
|
|
|
term2 = listify_lookup_plugin_terms(term, templar=self._templar, loader=self._loader)
|
|
|
|
# but avoid converting a plain string to a list of one string
|
|
|
|
if term2 != [term]:
|
|
|
|
term = term2
|
|
|
|
|
|
|
|
if isinstance(term, list):
|
|
|
|
# if it's a list, check recursively for items that are a list
|
|
|
|
term = self._do_flatten(term, variables)
|
|
|
|
ret.extend(term)
|
|
|
|
else:
|
|
|
|
ret.append(term)
|
|
|
|
|
|
|
|
return ret
|
|
|
|
|
|
|
|
def run(self, terms, variables, **kwargs):
|
|
|
|
|
|
|
|
if not isinstance(terms, list):
|
|
|
|
raise AnsibleError("with_flattened expects a list")
|
|
|
|
|
|
|
|
return self._do_flatten(terms, variables)
|