我想在使用 Ansible 的机器上获取网络接口的有序列表。现代 Linux 系统不使用 eth0、eth1 等。因此名称是不可预测的。在我们的网络中,我们将编号最低的接口连接到 LAN,将编号最高的接口连接到 WAN,因此我可以使用接口在有序列表中的位置来确定其功能。
我正在寻找在 Ansible 中执行此操作的规范方法。这样我就可以使用 {{ansible_eth0.ipv4.address}} 之类的东西。(其中 eth0 是其他名称)。
即使我手动设置了一个带有接口名称的变量,似乎也无法获得该接口的 IP(使用变量的内容)。
我想处理 Ansible 事实以获得我想要的东西,而不是在远程系统上运行 shell 脚本。
小智 5
我明白 Neik 的出发点,所以经过一些实验,我想我找到了一个可以解决问题的任务。
正如 Michael Hamilton 上面提到的,该ansible_interfaces事实包含所有网络接口的列表,并且它们似乎是按顺序排列的(即,第一个以太网接口称为 eth0,第二个以太网接口称为 eth1,等等)。所以一点点set_fact魔法和后来的大量实验:
- name: define traditional ethernet facts
set_fact:
ansible_eth: "{% set ansible_eth = ansible_eth|default([]) + [hostvars[inventory_hostname]['ansible_' + item]] %}{{ ansible_eth|list }}"
when: hostvars[inventory_hostname]['ansible_' + item]['type'] == 'ether'
with_items:
- "{{ hostvars[inventory_hostname]['ansible_interfaces'] }}"
Run Code Online (Sandbox Code Playgroud)
ansible_interfaces这会循环当前机器的所有条目,并构建一个等于“ether”hostvars[inventory_hostname]['ansible_' + item]的条目列表type。
因此,现在ansible_eth.0和ansible_eth.1应该分别大致相当于旧的ansible_eth0和ansible_eth1。
我还没有对此进行彻底的测试,以确保订单始终按预期运行,但它似乎可以解决问题。
非常感谢StackOverflow 的回答,向我展示了如何使用 with_items 构建列表。
当我们知道一些信息时获取接口的一些提示:
var:
allNetworkInterfaces: "{{ ansible_facts | dict2items | selectattr('value.ipv4', 'defined') | map(attribute='value') | list }}"
allNetworkInterfaces_variant2: "{{ ansible_facts.interfaces | map('extract', ansible_facts ) | list }}"
interfaceWithKnownIp: "{{ ansible_facts | dict2items | selectattr('value.ipv4', 'defined') | selectattr('value.ipv4.address', 'equalto', myKnowIpV4) | first }}"
interfaceWithKnownIp_fromVar: "{{ allNetworkInterfaces | selectattr('ipv4.address', 'equalto', myKnowIpV4) | first }}"
interfacesWithPartialKnowMac: "{{ allNetworkInterfaces | selectattr('macaddress', 'match', knownMacPrefix~'.*') | list }}"
interfacesWitKnowType: "{{ allNetworkInterfaces | selectattr('type', 'equalto', knownType) | sort(attribute='device') | list }}"
# extended on 2020-10-28
queryForKnownIpv6: "[*].{device: device, ipv4: ipv4, ipv6: ipv6[? address == 'fe80::a00:27ff:fe38:ad36']}[?ipv6])" # string must be in ' # sorry, only partial interface info, did not find out how to return all info directly
interfacesWithKnownIpv6: '{{ allNetworkInterfaces | json_query(queryForKnownIpv6) | first }}'
queryForKnownIpv4_linux: "[?ipv4.address == '{{ myKnownIpV4 }}']}[?ipv4])" # string must be in '
interfacesWithKnownIp_variantJsonQuery: '{{ allNetworkInterfaces | json_query(queryForKnownIpv4_linux) | first }}'
Run Code Online (Sandbox Code Playgroud)
一些简短的解释:
ansible_factsansible_facts.interfaces 是相同的 ansible_interfaces自从我接触 ansible 以来已经有一段时间了,但如果没有更多细节,我会期望类似的东西:
ip link show | grep mode | sed 's/://g' | awk '{print $1,$2}'
Run Code Online (Sandbox Code Playgroud)
上班...
1 lo
2 eth0
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
24789 次 |
| 最近记录: |