在 ansible 中使用 jinja2 selectattr 时出错

Getting error while using jinja2 selectattr in ansible

我有如下变量,(用户输入这些)

 vlanlist:
   - 3
   - 18 
   - 700
   - 57

以下是我从设备中收集到的内容,输出如下:

output5.msg:

[
    {
        "INTERFACE": "Ethernet1/1",
        "TRUNKING_VLANS": "2-18,20,24,48,52,54,56-66,68,70,72,76,80-82,84,86,88,90,92-94,96-104,108,112,116-127,700"
    },
    {
        "INTERFACE": "Ethernet1/2",
        "TRUNKING_VLANS": "2-18,20,24,48,52,54,56-66,68,70,72,76,80-82,84,86,88,90,92-94,96-104,108,112,116-127"
    }
]

场景:用户输入vlanlist,我必须检查用户输入的vlans(3,18,57,700)是否在界面Ethernet1/1 - TRUNKING_VLANS 和 Etherent1/2 - TRUNKING_VLANS 基于下面的 vlans 列表是预期的结果:

vlan 3 - allowed on Etherent1/1,Etherent1/2
vlan 18 - allowed on Etherent1/1,Etherent1/2
vlan 57 - allowed on Etherent1/1,Etherent1/2
vlan 700 - allowed on Etherent1/1
vlan 700 - NOT allowed on Etherent1/2

我正在尝试使用 selectattr 到 lookup/find vlanlist 在每个接口中 TRUNKING_VLANS :

- set_fact:
     vlan_info: "{{ vlan_info|d({})|combine({item : info}) }}"
   loop: "{{ vlanlist }}"
   vars:
     info: "{{ output5.msg|
              selectattr('TRUNKING_VLANS', 'contains', item)|list }}"

 - debug: msg="{{vlan_info}}"

获取错误:

{"msg": "An unhandled exception occurred while templating '{{ output5.msg| selectattr('TRUNKING_VLANS', 'contains', item)|list }}'. Error was a <class 'ansible.errors.AnsibleError'>, original message: Unexpected templating type error occurred on ({{ output5.msg| selectattr('TRUNKING_VLANS', 'contains', item)|list }}): 'in <string>' requires string as left operand, not int"}

扩展列表,例如创建文件

shell> cat expand_vlans.yml
- set_fact:
    _vlans: []
- set_fact:
    _vlans: "{{ _vlans + range(start|int, stop|int + 1)|list }}"
  loop: "{{ i.TRUNKING_VLANS.split(',') }}"
  vars:
    start: "{{ item.split('-')|first }}"
    stop: "{{ item.split('-')|last }}"
- set_fact:
    vlan_exp: "{{ vlan_exp|d([]) + [{'INTERFACE': i.INTERFACE,
                                     'TRUNKING_VLANS': _vlans}] }}"

并迭代数据

    - include_tasks: expand_vlans.yml
      loop: "{{ output5.msg }}"
      loop_control:
        loop_var: i

给予

  vlan_exp:
    - INTERFACE: Ethernet1/1
      TRUNKING_VLANS: [2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 20,
        24, 48, 52, 54, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 68, 70, 72, 76, 80,
        81, 82, 84, 86, 88, 90, 92, 93, 94, 96, 97, 98, 99, 100, 101, 102, 103, 104, 108,
        112, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 700]
    - INTERFACE: Ethernet1/2
      TRUNKING_VLANS: [2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 20,
        24, 48, 52, 54, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 68, 70, 72, 76, 80,
        81, 82, 84, 86, 88, 90, 92, 93, 94, 96, 97, 98, 99, 100, 101, 102, 103, 104, 108,
        112, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127]

然后创建信息

    - set_fact:
        vlan_info: "{{ vlan_info|d({})|combine({item: info}) }}"
      loop: "{{ vlanlist }}"
      vars:
        info: "{{ vlan_exp|
                  selectattr('TRUNKING_VLANS', 'contains', item)|
                  map(attribute='INTERFACE')|
                  list }}"

给予

  vlan_info:
    3: [Ethernet1/1, Ethernet1/2]
    18: [Ethernet1/1, Ethernet1/2]
    57: [Ethernet1/1, Ethernet1/2]
    700: [Ethernet1/1]