2016-11-15 17 views
0

我有一個數組值來自Ansible變量文件的字典。如何製作Jinja中獨特的配對清單?

ipfilter: 
    zone1: 
    - { application: "app 1", local_ip: 1.1.1.1 } 
    - { application: "app 1", local_ip: 1.1.1.1 } 
    - { application: "app 2", local_ip: 2.2.2.2 } 
    zone2: 
    - { application: "app 3", local_ip: 3.3.3.3 } 
    - { application: "app 4", local_ip: 4.4.4.4 } 
    - { application: "app 4", local_ip: 4.4.4.4 } 

的問題是,中applicationlocal_ip元組不是唯一的,因爲對象包含額外的數據,這是我在本例中省略了,因爲它是不相關的下面的腳本。

該腳本是通過Ansible遞送到Solaris服務器金賈模板:

#! /bin/bash 
set -eu 
cat <<';' | 
{% for zone, rules in ipfilter.items() %} 
{% for rule in rules %} 
{{zone}} {{rule.application}} {{rule.local_ip}} 
{% endfor %} 
{% endfor %} 
; 
sort | uniq | while read zone application local_ip; do 
    ipfcfg delete "$zone" "$application" "$local_ip" 
done 

在字典外環迭代並在數組值內循環迭代。

我無法制作Jinja獨有的元組列表。因此,我不得不在Bash中使用sort | uniq | while read循環。這遠非完美,並有其自身的侷限性。

如何使Jinja中的元組列表變得獨一無二?

回答

1

你的榜樣得到獨特的表對,你可以簡單地使用:

ipfilter.values() | sum(start=[]) | unique 

但這不會工作你的情況,因爲你已經從你的原始數據省略了其它按鍵,所以unique過濾器不管用。

你會與你的任務之前有點Ansible變量的模板化魔法來解決此:

# construct list of tuples 
- set_fact: 
    tmp_app: '{"app":"{{item.application}}","ip":"{{item.local_ip}}"}' 
    with_items: "{{ ipfilter.values() | sum(start=[]) }}" 
    register: tmp_apps 
# pass uniq list to template 
- template: 
    src: script.j2 
    dest: script.sh 
    vars: 
    uniq_apps: "{{ tmp_apps.results | map(attribute='ansible_facts.tmp_app') | list | unique }}" 

和script.j2:

#! /bin/bash 
set -eu 
{% for app in uniq_apps %} 
ipfcfg delete "{{app.app}}" "{{app.ip}}" 
{% endfor %} 
+0

這個工程,但我仍然不明白'sum(start = [])'做了什麼。爲什麼我不得不使用'sum',儘管我不想總結任何東西? – ceving

+0

用'ipfilter.values()'得到列表清單(因爲你的區域是列表)。但是你只需要內部列表,所以我們總結它們來製作一個包含所有內部列表的長列表。 –

0

感謝Konstantin Suvorov'sSean Vieira's回答另一個問題我能夠在Jinja做我所有的東西。

#! /bin/bash 
set -eu 
{% set all_rules = [] %} 
{% for zone, rules in ipfilter.items() %} 
{% for rule in rules %} 
{%  set x = all_rules.extend([{'zone': zone, 'application': rule.application, 'local_ip': rule.local_ip}]) %} 
{% endfor %} 
{% endfor %} 
{% for item in all_rules|unique %} 
ipfcfg delete {{item.zone|quote}} {{item.application|quote}} {{item.local_ip|quote}} 
{% endfor %}