2016-03-25 81 views
2

我有像這樣的列表: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 elemnents的唯一名稱,所以在這個例子中,我要循環

- item1 
- item2 
- item4 
- item6 

基本上什麼

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

,不過它只有獨特的元素。

我怎樣才能得到所有host_depends項目depends這樣我就可以在他們運行unique過濾器,並與with_items使用它們?

編輯:

我設法讓所有depends項目像這樣的列表:

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

但是從那裏,我不能減少這個列表中name項目。

回答

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

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 
+0

您如何使用它?你還會用'with_subelements:'一起使用它嗎? – MaxU

+1

@MaxU不,這是一個平面列表,所以使用'with_items'來迭代它的項目。 – Zulakis

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

返回一個列表的列表,如所依賴一個列表。要將列表列表整合成一個列表,請使用內置平坦查找:

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

有趣!我無法在任何地方找到這種查找。使用_....處理程序的所有 – Zulakis

+0

都是查找 –