Como percorrer os fatos da interface

1

O módulo de configuração do ansible fornece o fato de ansible_interfaces

"ansible_interfaces": [
    "lo", 
    "eth0",
    "eth1"
], 

E por interface alguns fatos:

"ansible_eth0": {
    "active": true, 
    "device": "eth0", 
    "ipv4": {
        "address": "192.168.10.2", 
        "broadcast": "192.168.10.255", 
        "netmask": "255.255.255.0", 
        "network": "192.168.10.0"
    },
    "macaddress": "52:54:00:5c:c1:36", 
    "module": "virtio_net", 
    "mtu": 1500, 
    "pciid": "virtio0", 
    "promisc": false, 
    "type": "ether"
}

Como eu uso o fato de ansible_interfaces para percorrer as interfaces disponíveis?

  tasks:
    - name: find interface facts
      debug: msg=ansible_{{ item }}
      with_items: "{{ ansible_interfaces }}"

Isso claramente não está funcionando, porque imprime as cadeias ansible_lo, ansible_eth0 e ansible_eth1, mas eu quero imprimir os fatos dessas interfaces. Alguns servidores têm outras interfaces, como pontes, então não sei de antemão quais interfaces usar.

p.s. este exemplo não é muito útil, mas eventualmente eu quero usá-lo para armazenar fatos como macaddresses em elasticsearch para facilitar a busca de qual servidor possui o macaddress.

    
por Vincent 07.03.2016 / 14:23

2 respostas

7

Você se deparou com uma das limitações do modelo Jinja / Ansible, ou seja, não há como avaliar expressões, o que seria necessário para obter o valor de algo como ansible_{{ item }} . Você está preso com uma corda.

Felizmente, existe o objeto global hostvars , onde você pode acessar todos os fatos por chave, que é ... uma string.

Algo nesse sentido deve levar você até lá:

tasks:
  - name: find interface facts
    debug:
      msg: "{{ hostvars[inventory_hostname]['ansible_%s' | format(item)] }}"
    with_items: "{{ ansible_interfaces }}"
    
por 07.03.2016 / 14:34
1

Você realmente pode fazer isso. Você só precisa conhecer a sintaxe j2 muito bem, pesquisar um pouco e combiná-la com alguns hacks. DOH. acabou de perder 2 horas. Espero que eu salve para alguém!

É factível assim:

    - name: Display all interfaces
  debug:
    msg: "{{ msg.split('\n') }}"
  vars:
    msg: |
        {% for iface in ansible_interfaces|sort %}
            System interface {{ iface }}
            {{ vars.ansible_facts[iface] | to_nice_json }}
        {% endfor %}

E, como suspeito, as pessoas que estão pesquisando para fazer isso, querem calcular a próxima interface gratuita (que eu procurava).

Eu fiz assim:

    - name: calc next free interface
      set_fact:
        nextFreeIf: "{% set ifacePrefix = vars.ansible_default_ipv4.alias %}{% set ifaceNum = { 'cnt': 0 } %}{% macro increment(dct, key, inc=1)%}{% if dct.update({key: dct[key] + inc}) %} {% endif %}{% endmacro %}{% for iface in ansible_interfaces|sort %}{% if iface| regex_search('^' ~ vars.ansible_default_ipv4.alias) %}{{ increment(ifaceNum, 'cnt') }}{% endif %}{% endfor %}{{ifacePrefix}}:{{ifaceNum.cnt}}"

o nextFreeIf está em uma linha, porque senão você recebe espaços vazios e dores de cabeça para cortá-lo. É feio, mas ei, funciona.

Realmente esperamos poupar tempo às pessoas. Felicidades.

    
por 29.07.2018 / 22:36

Tags