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