web-dev-qa-db-fra.com

Vérifiez si la clé existe dans un dict dans le modèle Jinja2 sur ansible

J'ai un Host_var en ansible avec dict avec toutes les interfaces:

---
interfaces:
  vlan0:
    ip: 127.0.0.1
    mask: 255.255.255.0
    state: true

  vlan2:
    ip: 127.0.1.1
    mask: 255.255.255.0
    state: true

Et je veux vérifier si dict a une clé vlan1 si ok mis à la valeur du modèle vlan1.ip else put vlan2.ip .

{% if interfaces.vlan1 %} 
# and also I try {% if 'vlan1' in interfaces %}
{{ interfaces.vlan1.ip }};
{% else %}
{{ interfaces.vlan2.ip|default("127.0.0.1") }};
{% endif %};

Mais j'ai une erreur:

fatal: [127.0.0.1] => {'msg': "AnsibleUndefinedVariable: One or more undefined variables: 'dict object' has no attribute 'vlan1'", 'failed': True}

I trouvé que cela doit fonctionner dans Jinja2 mais il semble que cela ne fonctionne pas dans ansible. Peut-être que quelqu'un a une autre façon de résoudre ce problème? Quand je définis vlan1 cela fonctionne très bien. Ansible version 1.9.2

J'essayais de le reproduire en python et je n'ai aucune erreur si mon dictionnaire n'a pas de clé vlan1 . Merci à @ GUIDO

>>> from jinja2 import Template
>>> b = Template("""
... {% if interfaces.vlan1 %}
... {{ interfaces.vlan1.ip }}
... {% else %}
... {{ interfaces.vlan2.ip|default("127.0.3.1") }}
... {% endif %}""")
>>> b.render(interfaces={'vlan3':{'ip':'127.0.1.1'},'vlan2':{'ip':'127.0.2.1'}})
u'\n\n127.0.2.1\n'
>>> b.render(interfaces={'vlan1':{'ip':'127.0.1.1'},'vlan2':{'ip':'127.0.2.1'}})
u'\n\n127.0.1.1\n'
20
Alex

La réponse est simple et elle apparaît sur le message d'erreur ansible. Tout d'abord, je dois vérifier si var est défini.

{% if interfaces.vlan1 is defined %}
{{ interfaces.vlan1.ip }}
{% else %}
{{ interfaces.vlan2.ip|default("127.0.3.1") }}
{% endif %}

Cette combinaison fonctionne bien.

26
Alex

La meilleure façon de vérifier si une clé existe dans un dictionnaire (dans n'importe quel contexte Jinja2, pas seulement avec Ansible) est d'utiliser l'opérateur in, par exemple:

{% if 'vlan1' in interfaces %}
{{ interfaces.vlan1.ip |default(interfaces.vlan2.ip) }};
{% endif %}
8
larsks