web-dev-qa-db-ja.com

ansibleのJinja2テンプレートの辞書にキーが存在するかどうかを確認します

私はすべてのインターフェイスを持つdictでansibleのHost_varを持っています:

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

そして、dictがキーを持っているかどうかを確認したいvlan1if OK put the template valuevlan1.ipelse putvlan2.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 %};

しかし、私はエラーがあります:

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

I found Jinja2で動作する必要があるが、ansibleでは動作しないようです。たぶん誰かがこの問題を解決する別の方法を持っていますか? vlan1を定義すると、正常に動作します。 Ansibleバージョン1.9.2

私はpythonでそれを再現しようとしていましたが、辞書にキーvlan1がなければエラーはありません。 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

答えは簡単で、アンシブルエラーメッセージに表示されます。まず、varが定義されているかどうかを確認する必要があります。

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

この組み合わせはうまく機能します。

26
Alex

(Ansibleだけでなく、Jinja2コンテキストで)辞書にキーが存在するかどうかを確認する最善の方法は、in演算子を使用することです。例:

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