最近我正在使用 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 的接口名称。
我想要的输出如下:
某些接口可能分配了多个 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 }}"
这可以以某种方式轻松完成吗?
给定一个 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"
}