Ansible:如何在ipaddr过滤器中使用selectattr

时间:2019-07-05 19:41:02

标签: ansible jinja2

在MacOS上,使用ansible 2.7.1(安装了netaddr),python 3.7.3。

由于某种原因,我似乎无法让selectattr和ipaddr在ansible中一起工作。

---
# simple test of ipaddr with selectattr
- hosts: localhost
  vars:
    x:
      - i: 'a'
        a: '1.2.3.4'
      - i: 'b'
        a: '192.168.3.23'
      - i: 'c'
        a: '0.0.0.0'
  tasks:
  - debug: var="x|selectattr('a', 'ipaddr','192.168.3.0/24')|list"

输出:

PLAY [localhost] ***************************************************************

TASK [Gathering Facts] *********************************************************
ok: [localhost]

TASK [debug] *******************************************************************
fatal: [localhost]: FAILED! => {"msg": "Unexpected failure during module execution."}
    to retry, use: --limit @/Users/chris.kiick/IIQ/services-performance-lab/scripts/ansible/tp2.retry

PLAY RECAP *********************************************************************
localhost                  : ok=1    changed=0    unreachable=0    failed=1

为什么这行不通?我可以直接使用ipaddr,它可以与map()一起使用。 Selectattr()可与其他过滤器一起正常工作。使用调试(-vvv)运行不会提供任何有用的信息。使用其他主机类型(centos,ubuntu)没有什么区别。

有什么想法吗?

1 个答案:

答案 0 :(得分:1)

x 是一个列表。列表中有项目,没有属性。可以测试一个项目,例如 x.1

"{{ x.1|selectattr('a', 'ipaddr','192.168.3.0/24')|list }}"

,但是 selectattr 无法将 ipaddr 识别为test。这是filter

The error was: TemplateRuntimeError: no test named 'ipaddr'

关于如何进行操作,有两种选择。可以循环列表。下面的任务

- debug:
    msg: "{{ item.a|ipaddr('192.168.3.0/24') }}"
  loop: "{{ x }}"

给予

"msg": ""
"msg": "192.168.3.23"
"msg": ""

,或添加三元过滤器。下面的任务

- debug:
    msg: "{{ item.a|ipaddr('192.168.3.0/24')|ternary( item.a, 'not in range') }}"
  loop: "{{ x }}"

给予

"msg": "not in range"
"msg": "192.168.3.23"
"msg": "not in range"

或以下任务

- set_fact:
    a_list: "{{ a_list|default([]) + [ item.a|ipaddr('192.168.3.0/24') ] }}"
  loop: "{{ x }}"
- debug:
    var: a_list

给出列表

"a_list": [
    null, 
    "192.168.3.23", 
    null
]