如何在 Jinja 中制作独一无二的配对列表? [英] How to make a list of pairs unique in Jinja?

查看:29
本文介绍了如何在 Jinja 中制作独一无二的配对列表?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个字典,其中包含来自 Ansible vars 文件的数组值.

I have a dictionary with array values coming from an Ansible vars file.

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 的元组不是唯一的,因为对象包含额外的数据,我在例子中省略了,因为它是与以下脚本无关.

The problem is, that the tuple of application and local_ip is not unique, because the objects contain additional data, which I have omitted in the example, because it is not relevant for the following script.

该脚本是 Ansible 提供给 Solaris 服务器的 Jinja 模板:

The script is a Jinja template delivered by Ansible to a Solaris server:

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

外循环遍历字典,内循环遍历数组值.

The outer loop iterates over the dictionary and the inner loop iterates over the array values.

我无法使用 Jinja 使元组列表独一无二.因此我不得不使用 sort |唯一|Bash 中的 while read 循环.这远非完美,并且有其自身的局限性.

I am not able to make the list of tuples unique with Jinja. Therefor I had to use the sort | uniq | while read loop in Bash. This is far from perfect and has its own limitations.

如何在 Jinja 中使元组列表唯一?

How to make the list of tuples unique in Jinja instead?

推荐答案

要从您的示例中获取唯一的列表对,您可以简单地使用:

To get unique list pairs from your example, you can simply use:

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

但这在您的情况下不起作用,因为您从原始数据中省略了其他键,因此 unique 过滤器将不起作用.

But this will not work in your case, because you have omitted other keys from your original data, so unique filter will not work.

在执行任务之前,您必须使用一些 Ansible 变量模板魔术来解决此问题:

You will have to workaround this with a bit of Ansible variables templating magic prior to your task:

# 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:

and script.j2:

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

这篇关于如何在 Jinja 中制作独一无二的配对列表?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆