首页 > 解决方案 > 如何从列表中选择值最接近Ansible中另一个的项目

问题描述

我有一个返回以下输出的剧本:

ok: [Lab_Core_SW] => {
    "Test_List": [
        {
            "Firewall_IP": "10.120.193.100",
            "IP_Address": "10.120.0.0",
            "IP_and_Mask": "10.120.0.0/16",
            "Subnet_Mask": "16",
            "VRF_Name": "vrf1"
        },
        {
            "Firewall_IP": "10.120.160.36",
            "IP_Address": "10.120.46.0",
            "IP_and_Mask": "10.120.46.0/25",
            "Subnet_Mask": "25",
            "VRF_Name": "vrf2"
        },
        {
            "Firewall_IP": "10.120.187.68",
            "IP_Address": "10.120.0.0",
            "IP_and_Mask": "10.120.0.0/16",
            "Subnet_Mask": "16",
            "VRF_Name": "vrf3"
        },
        {
            "Firewall_IP": "10.109.1.66",
            "IP_Address": "10.0.0.0",
            "IP_and_Mask": "10.0.0.0/8",
            "Subnet_Mask": "8",
            "VRF_Name": "vrf4"
        },
        {
            "Firewall_IP": "10.120.184.68",
            "IP_Address": "10.120.0.0",
            "IP_and_Mask": "10.120.0.0/16",
            "Subnet_Mask": "16",
            "VRF_Name": "vrf5"
        }
    ]
}

有没有一种方法可以获取列表中每个项目的 Subnet_Mask 并找到最接近 32 的数字,然后只打印列表中的该项目,所以我剩下以下内容:

        {
            "Firewall_IP": "10.120.160.36",
            "IP_Address": "10.120.46.0",
            "IP_and_Mask": "10.120.46.0/25",
            "Subnet_Mask": "25",
            "VRF_Name": "vrf2"
        }

我不想使用when: item.Subnet_Mask >= x,因为根据核心交换机上的路由,这可能会返回多个结果或不返回任何结果。

我看过 ipaddr 过滤器,但它似乎没有我需要的东西。

我知道 python 中的 lambda 函数,但如果有可能以任何方式将其与 ansible 联系起来,我一直无法找出如何。

任何帮助表示赞赏

标签: ansiblejinja2

解决方案


我不确定您的确切用例,但您可以通过执行以下操作从列表中提取具有最接近其他属性的属性的项目。请注意,它正在从 JSON 文件加载您的输出——在您的情况下,它可能已经注册。

玩.yaml:

---
- hosts: 127.0.0.1
  connection: local
  gather_facts: no
  vars:
    obj: "{{ lookup('file', 'list.json') | from_json }}"

  tasks:
    - set_fact:
        diff: "{{ 32 - item['Subnet_Mask'] | int }}"
      loop: "{{ obj['Test_List'] }}"
      register: diff_result
    - set_fact:
        min_diff: "{{ diff_result.results | sort(attribute='ansible_facts.diff') | first }}"
    - debug:
        var: min_diff.item

该剧本循环遍历每个项目,从 32 中减去子网掩码,按差值对结果进行排序并输出差值最小的项目。

运行:

ANSIBLE_JINJA2_NATIVE=True ansible-playbook play.yaml -i 127.0.0.1,

ANSIBLE_JINJA2_NATIVE必要确保diff使用 . 将其记录为整数而不是字符串set_fact

输出:

TASK [debug]
ok: [127.0.0.1] => {
    "min_diff.item": {
        "Firewall_IP": "10.120.160.36", 
        "IP_Address": "10.120.46.0", 
        "IP_and_Mask": "10.120.46.0/25", 
        "Subnet_Mask": "25", 
        "VRF_Name": "vrf2"
    }
}

推荐阅读