2016-11-15 1 views
0

私はAnabilitiesのvarsファイルからの配列値を持つ辞書を持っています。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のタプルは、一意ではないこと、です。

#! /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 

辞書上アウターループ反復と配列値を超える内側ループ反復:

スクリプトは、SolarisサーバにAnsibleによって送達神社テンプレートです。

私は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 = []) 'が何をしているのかまだ分かりません。私は何も要約したくないのに、なぜ「和」を使わなければならないのですか? – 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 %} 
関連する問題