如何使用 jinja2 过滤器擦洗 ansible playbook 中的字典值

How to use jinja2 filters to scrub dict values in ansible playbook

我有一个 playbook 任务,其中 return 是一个像这样的命令列表:

mydict:
  - { "ip": "192.168.0.1", "mac": "00324a:ac6789" }
  - { "ip": "192.168.0.2", "mac": "00324a.ac6790" }
  - { "ip": "192.168.0.3", "mac": "00:32:4a:ac:67:91" }

我想清理 mac 地址,使它们都以相同的格式显示,例如:

- set_fact:
    myarp: "{{ mydict|map(attribute='mac')|ipaddr('eui48')  }}"

会 return:

myarp:
  - { "ip": "192.168.0.1", "mac": "00-32-4A-AC-67-89" }
  - { "ip": "192.168.0.2", "mac": "00-32-4A-AC-67-90" }
  - { "ip": "192.168.0.3", "mac": "00-32-4A-AC-67-91" }

它不适用于 map,因为此过滤器要么仅 returns 一个特定属性,要么将另一个过滤器应用于列表的每个元素。但是您不能将过滤器应用于每个列表元素的特定属性。我不认为有一种方法可以使用内置过滤器来做到这一点,如果有的话,它会变得太难读了。

你在这里能做的最好的事情是 write a custom filter plugin:

from ansible import errors
from jinja2.filters import environmentfilter
import re

class FilterModule(object):
    def filters(self):
        return {
            'scrubmac': self.scrubmac
        }
    def scrubmac(*args):
        data = args[1]
        for item in data:
            mac = re.sub('[^A-z0-9]', '', item['mac'])
            item['mac'] = re.sub('(.{2})(?=.)', '\1-', mac)
        return data

这是针对 Ansible 2 的。不确定,可能需要对 Ansible 1 进行一些小改动。

然后称它为

- set_fact:
    myarp: "{{ mydict | scrubmac }}"