Назад | Перейти на главную страницу

Как перечислить сетевые интерфейсы в Ansible

Я хотел бы получить упорядоченный список сетевых интерфейсов на машине, использующей Ansible. Современные системы Linux не используют eth0, eth1 и т. Д. Так что названия непредсказуемы. В нашей сети мы подключаем интерфейс с наименьшим номером к локальной сети, а с самым высоким - к глобальной сети, поэтому я могу использовать положение интерфейса в упорядоченном списке для определения его функции.

Я ищу канонический способ сделать это в Ansible. Так что я могу использовать что-то вроде {{ansible_eth0.ipv4.address}}. (Где eth0 - какое-то другое имя).

Даже если я вручную установил переменную с именем интерфейса, похоже, нет способа получить IP этого интерфейса (используя содержимое переменной).

Я хотел бы обработать факты Ansible, чтобы получить то, что мне нужно, вместо того, чтобы запускать сценарий оболочки в удаленной системе.

В ansible_interfaces В факте перечислены все существующие сетевые интерфейсы.

Я понимаю, откуда приходит Нейк, поэтому после небольшого эксперимента я думаю, что нашел задачу, которая поможет.

Как упоминал Майкл Гамильтон выше, ansible_interfaces fact содержит список всех сетевых интерфейсов, и они кажутся упорядоченными (т.е. первый интерфейс Ethernet назывался бы 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 равно «эфиру».

Так что сейчас 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_var2: "{{ 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 }}"

несколько коротких объяснений:

Прошло некоторое время с тех пор, как я коснулся анзибля, но без дополнительной информации я ожидал бы чего-то вроде:

ip link show | grep mode | sed 's/://g' | awk '{print $1,$2}'

работать...

1 lo
2 eth0