ansible / jinja2获得独特的子元素

时间:2016-03-25 22:07:03

标签: python ansible jinja2

我有一个这样的清单:

host_depends:
  - host: abc
    depends:
      - name: item1
      - name: item4
        type: asdf
      - name: item6
  - host: def
    depends:
      - name: item2
      - name: item4
      - name: item6

我需要遍历depends元素的唯一名称,因此在此示例中我想循环遍历

- item1 
- item2
- item4
- item6

基本上是什么

debug: var=item.1.name
with_subelements:
  - "{{ host_depends }}"
  - depends

确实如此,但仅限于独特的元素。

如何获取所有depends个商品的host_depends,以便我可以对其unique进行过滤,并将其与with_items一起使用?

编辑:

我设法获得所有depends项目的列表,如下所示:

host_depends|map(attribute='depends')|list

但是从那里开始,我无法将此列表缩减为name个项目。

3 个答案:

答案 0 :(得分:2)

如果使用Ansible使事情变得过于复杂而你无法用它来思考它,那么它就是一个不应该完成的指标。也许在循环中使用一些Jinja过滤器和一些set_fact任务是可能的。但不要,Ansible不是一种编程语言,不应该这样使用。 Ansible有两个主要优势:可读性和可扩展性。不要忽视后者而打破第一个。

with_subelements实际上是一个插件本身,只是它是一个核心插件。只需复制它并创建自己的with_unique_subelements插件即可。这是code of with_subelements。第100行是将元素添加到返回列表的位置。这就是你可以挂钩并实施检查是否已添加该项目的地方。

将您修改后的版本相对于您的剧本保存为lookup_plugins/unique_subelements.py,或者如果您使用Ansible 2,您也可以使用相同路径将其存储在任何角色中。

答案 1 :(得分:2)

host_depends|map(attribute='depends')|list

返回列表列表,依赖于列表。要将此列表列表展平/组合到一个列表中,请使用内置展平查找:

lookup('flattened', host_depends|map(attribute='depends')) |map(attribute='name')|unique|list

答案 2 :(得分:1)

host_depends|map(attribute='depends')|list返回列表列表,因为depends是一个列表。 将此列表列表展平/组合到一个列表中:

将其添加为roles/<rolename>/filter_plugins/filter.py

from ansible import errors

# This converts a list of lists into a single list
def flattenlist(l):
    try:
        return [item for sublist in l for item in sublist]
    except Exception, e:
        raise errors.AnsibleFilterError('split plugin error: %s' % str(e) )

class FilterModule(object):
    ''' A filter to split a string into a list. '''
    def filters(self):
        return {
            'flattenlist' : flattenlist
        }

并使用

host_depends|map(attribute='depends')|flattenlist|map(attribute='name')|unique|list