如何在 Ansible 中枚举网络接口

Nei*_*eik 9 ansible

我想在使用 Ansible 的机器上获取网络接口的有序列表。现代 Linux 系统不使用 eth0、eth1 等。因此名称是不可预测的。在我们的网络中,我们将编号最低的接口连接到 LAN,将编号最高的接口连接到 WAN,因此我可以使用接口在有序列表中的位置来确定其功能。

我正在寻找在 Ansible 中执行此操作的规范方法。这样我就可以使用 {{ansible_eth0.ipv4.address}} 之类的东西。(其中 eth0 是其他名称)。

即使我手动设置了一个带有接口名称的变量,似乎也无法获得该接口的 IP(使用变量的内容)。

我想处理 Ansible 事实以获得我想要的东西,而不是在远程系统上运行 shell 脚本。

Mic*_*ton 9

ansible_interfaces事实列出了所有现有的网络接口。


小智 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.0ansible_eth.1应该分别大致相当于旧的ansible_eth0ansible_eth1

我还没有对此进行彻底的测试,以确保订单始终按预期运行,但它似乎可以解决问题。

非常感谢StackOverflow 的回答,向我展示了如何使用 with_items 构建列表。


sim*_*ohe 5

当我们知道一些信息时获取接口的一些提示:

    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)

一些简短的解释:


Dan*_*ick 2

自从我接触 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)