jinja2 template - {% else %} not honored

17 views
Skip to first unread message

subin

unread,
Feb 11, 2019, 1:02:30 AM2/11/19
to Ansible Project
I have the following data structure:

client_groups:
  apache:
    - '10.5.10.111'
    - '10.2.10.112'
    - '10.5.10.11'

  mail:
    - '1.2.3.4'
    - '5.6.7.8'

  database:
    - '10.9.8.7'

client_destinations:
  apache:
    - var: '$syslogtag'
      contains: 'apache-access:'
      destination: '/logs/apache-servers/access.log'

    - var: '$syslogtag'
      contains: 'apache-error:'
      destination: '/logs/apache-servers/error.log'

  mail:
    - var: 'local5'
      contains: 'dovecot'
      destination: '/logs/mail/mail.log'

  database:
    - var:
      contains:
      destination: '/logs/db/activity.log'

In my jinja2 template-file, I have the below:

{% for k in client_groups %}
{% if client_destinations[k][0].var is defined %}
{% for i in range(0,client_destinations[k]|length) %}
if $fromhost-ip ==  {{ client_groups[k] | to_json }} and {{ client_destinations[k][i].var }} == '{{ client_destinations[k][i].contains }}' then {{ client_destinations[k][i].destination }}
{% endfor %}
{% endif %}
{% else %}
if $fromhost-ip ==  {{ client_groups[k] | to_json }} then {{ client_destinations[k].destination }}
{% endfor %}

The desired output is:

if $fromhost-ip ==  ["10.5.10.111", "10.2.10.112", "10.5.10.11"] and $syslogtag == 'apache-access:' then /logs/apache-servers/access.log
if $fromhost-ip ==  ["10.5.10.111", "10.2.10.112", "10.5.10.11"] and $syslogtag == 'apache-error:' then /logs/apache-servers/error.log
if $fromhost-ip ==  ["1.2.3.4", "5.6.7.8"] and local5 == 'dovecot' then /logs/mail/mail.log
if $fromhost-ip ==  ["10.9.8.7"] == then /logs/db/activity.log

But, I get the below output:

if $fromhost-ip ==  ["10.5.10.111", "10.2.10.112", "10.5.10.11"] and $syslogtag == 'apache-access:' then /logs/apache-servers/access.log
if $fromhost-ip ==  ["10.5.10.111", "10.2.10.112", "10.5.10.11"] and $syslogtag == 'apache-error:' then /logs/apache-servers/error.log
if $fromhost-ip ==  ["1.2.3.4", "5.6.7.8"] and local5 == 'dovecot' then /logs/mail/mail.log
if $fromhost-ip ==  ["10.9.8.7"] and  == '' then /logs/db/activity.log

This means, the statement after {% else %} - if $fromhost-ip ==  {{ client_groups[k] | to_json }} then {{ client_destinations[k].destination }} - is getting included in the `for` loop ({% for i in range(0,client_destinations[k]|length) %}); {% else %} is not being honored. 

What should be changed? 

Thanks in advance.

Felix Fontein

unread,
Feb 11, 2019, 2:20:37 AM2/11/19
to ansible...@googlegroups.com
Hi,

> In my jinja2 template-file, I have the below:
>
> {% for k in client_groups %}
> {% if client_destinations[k][0].var is defined %}
> {% for i in range(0,client_destinations[k]|length) %}
> if $fromhost-ip == {{ client_groups[k] | to_json }} and {{
> client_destinations[k][i].var }} ==
> '{{ client_destinations[k][i].contains }}' then
> {{ client_destinations[k][i].destination }} {% endfor %}
> {% endif %}
> {% else %}
> if $fromhost-ip == {{ client_groups[k] | to_json }} then {{
> client_destinations[k].destination }}
> {% endfor %}

First: you should **really** indent stuff for better readability:

{% for k in client_groups %}
{% if client_destinations[k][0].var is defined %}
{% for i in range(0,client_destinations[k]|length) %}
if $fromhost-ip == {{ client_groups[k] | to_json }} and {{
client_destinations[k][i].var }} == '{{ client_destinations[k][i].contains
}}' then {{ client_destinations[k][i].destination }}
{% endfor %}
{% endif %}
{% else %}
if $fromhost-ip == {{ client_groups[k] | to_json }} then {{
client_destinations[k].destination }}
{% endfor %}

> The desired output is:
> [...]
>
> This means, the statement after {% else %} - if $fromhost-ip == {{
> client_groups[k] | to_json }} then
> {{ client_destinations[k].destination }}
> - is getting included in the `for` loop ({% for i in
> range(0,client_destinations[k]|length) %}); {% else %} is not being
> honored.

It is being honored. Please check the documentation:
http://jinja.pocoo.org/docs/2.10/templates/#for

The else branch of a for loop is executed only if the loop is over zero
elements. Since your loop is over a non-zero amount of elements, the
else branch of the for loop is ignored.

You probably don't want an else branch for the for loop, but for the if
construct. You can see from the indented version that you don't have
that right now.

Cheers,
Felix


Reply all
Reply to author
Forward
0 new messages