如何在 Ansible 中枚举网络接口

如何在 Ansible 中枚举网络接口

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

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

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

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

答案1

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

答案2

当我们了解一些信息时,获取接口的一些提示:

    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 }}'

一些简短的解释:

答案3

我理解 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'] }}"

ansible_interfaces这将循环遍历当前机器的所有条目并构建一个hostvars[inventory_hostname]['ansible_' + item]等于type“ether”的条目列表。

因此现在ansible_eth.0ansible_eth.1应该分别大致相当于旧的ansible_eth0ansible_eth1

我还没有彻底测试过这一点以确保订单总是按预期进行,但它似乎确实起了作用。

非常感谢这个 StackOverflow 答案向我展示如何使用 with_items 构建列表。

答案4

与 Daniel Widrick 的答案非常相似,但避免使用较旧的答案,而with_items使用loop。此外,我只想找到 wifi 接口,它仍然wlan0适用于树莓派。它还会找到许多其他适配器,因为大多数适配器都以 开头wl(但不是全部)

- name: Get wifi adapter
  set_fact: 
    wifi_adapter: '{{ item }}'
  loop: '{{ ansible_facts.interfaces }}'
  when: 'item.startswith("wl")'enter code here

相关内容