在知道其属性之一的值时如何检索字典键?

问题描述 投票:0回答:1

最近我正在使用 Ansible 开发 Netbox 自动化。我准备了任务,它收集有关网络接口的信息,如下所示:

    "interface_ips": {
        "br0": {
            "ipv4": [
                "10.0.0.10","10.0.0.11"
            ],
            "ipv6": [],
            "mac": "aa:bb:cc:dd:ee:ff",
            "mtu": "1500",
            "type": "bridge"
        },
        "lxcbr0": {
            "ipv4": [
                "10.100.0.10"
            ],
            "ipv6": [],
            "mac": "ff:ee:dd:cc:bb:aa",
            "mtu": "1500",
            "type": "bridge"
        }
    }

我想迭代收集的 IP(IPv4 + IPv6)并返回相应 IP 的接口名称。

我想要的输出如下:

  • 10.0.0.10 - br0 - 主机
  • 10.0.0.11 - br0 - 主机
  • 10.100.0.10 - lxcbr0 - 主机

某些接口可能分配了多个 IP,因此迭代每个 IP 非常重要。

我设法完成以下任务,但它不会迭代每个地址,仅迭代第一个 ipv4 地址。

    - name: Extract IPv4 addresses and interface names
      set_fact:
        ip_interface_map: "{{ ip_interface_map | default({}) | combine({item.value.ipv4[0]: item.key}) }}"
      loop: "{{ interface_ips | dict2items }}"

这可以以某种方式轻松完成吗?

python ansible jinja2 netbox
1个回答
0
投票

给定一个 IP 地址,您想要查找分配该地址的接口的名称。为此,我们需要构建一个将地址映射到接口名称的数据结构。我喜欢使用过滤器来处理这类事情,因为这允许我们在 Python 中实现逻辑。

如果我们将以下内容放入

filter_plugins/filters.py

def build_address_map(interface_ips):
    address_map = {}
    for iface, config in interface_ips.items():
        for addr in config["ipv4"]:
            address_map[addr] = iface
        for addr in config["ipv6"]:
            address_map[addr] = iface

    return address_map


class FilterModule:
    def filters(self):
        return {
            "build_address_map": build_address_map,
        }

然后我们可以这样写:

- hosts: localhost
  gather_facts: false
  vars:
    collected_ips:
    - 10.0.0.10
    - 192.168.10.100
    - 10.100.0.10

    interface_ips: {
        "br0": {
            "ipv4": [
                "10.0.0.10","10.0.0.11"
            ],
            "ipv6": [],
            "mac": "aa:bb:cc:dd:ee:ff",
            "mtu": "1500",
            "type": "bridge"
        },
        "lxcbr0": {
            "ipv4": [
                "10.100.0.10"
            ],
            "ipv6": [],
            "mac": "ff:ee:dd:cc:bb:aa",
            "mtu": "1500",
            "type": "bridge"
        }
      }
  tasks:
    - set_fact:
        address_map: "{{ interface_ips | build_address_map }}"

    - debug:
        msg: "address {{ item }} is assigned to {{ address_map[item]|default('unknown')}}"
      loop: "{{ collected_ips }}"

产生的输出:

TASK [debug] *********************************************************************************************************************************
ok: [localhost] => (item=10.0.0.10) => {
    "msg": "address 10.0.0.10 is assigned to br0"
}
ok: [localhost] => (item=192.168.10.100) => {
    "msg": "address 192.168.10.100 is assigned to unknown"
}
ok: [localhost] => (item=10.100.0.10) => {
    "msg": "address 10.100.0.10 is assigned to lxcbr0"
}
© www.soinside.com 2019 - 2024. All rights reserved.