如何列出Jinja中唯一的对名单?

时间:2016-11-15 18:09:42

标签: ansible jinja2

我有一个字典,其数组值来自Ansible vars文件。

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服务器提供的Jinja模板:

#! /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中的元组列表成为唯一的?

2 个答案:

答案 0 :(得分: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 %}

答案 1 :(得分: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 %}