Jinja2 extract single value for key/value pair without looping

27,508 views
Skip to first unread message

jepper

unread,
Jun 27, 2014, 4:27:10 AM6/27/14
to ansible...@googlegroups.com

I have the following defined in vars or defaults:

fusemq_authentication:
  - { 'username':'admin',     'password’:'blah',         'groups':'admin' }
  - { 'username':'LOGSTASH',  'password’:'bing',  'groups':'LOGSTASH' }

I want to know the password for LOGSTASH in a template. Today I loop until I find it. Is there a simpler way?

{% for value in fusemq_authentication %}
{% if value.username=="LOGSTASH" %}
fuseMQ_password={{ value.password }}
{% endif %}
{% endfor %}

Petros Moisiadis

unread,
Jun 27, 2014, 5:14:47 AM6/27/14
to ansible...@googlegroups.com
--
You received this message because you are subscribed to the Google Groups "Ansible Project" group.
To unsubscribe from this group and stop receiving emails from it, send an email to ansible-proje...@googlegroups.com.
To post to this group, send email to ansible...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/ansible-project/72470009-3f65-4b70-85f1-e31c83b468bb%40googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

You could transform your data definition like this:

fusemq_users:
  admin:
    password: blah
    groups:
      - admin
  logstash:
    password: bing
    groups:
      - logstash

Then in a template you could access the password for 'logstash' user like this:

{{ fusemq_users['logstash']['password'] }} or {{ fusemq_users.logstash.password }}

Tomasz Kontusz

unread,
Jun 27, 2014, 5:24:11 AM6/27/14
to ansible...@googlegroups.com


jepper <jesp...@gmail.com> napisał:
>
>
>I have the following defined in vars or defaults:
>
>fusemq_authentication:
>- { 'username':'admin', 'password’:'blah', 'groups':'admin'
>}
> - { 'username':'LOGSTASH', 'password’:'bing', 'groups':'LOGSTASH' }
This should be a dictionary

>I want to know the password for LOGSTASH in a template. Today I loop
>until
>I find it. Is there a simpler way?
>
>{% for value in fusemq_authentication %}
>{% if value.username=="LOGSTASH" %}
>fuseMQ_password={{ value.password }}
>{% endif %}
>{% endfor %}
Yes, with fusemq_authentication as a dict it would be:
fuseMQ_password={{ fusemq_authentication. LOGSTASH.password }}
--
Wysłane za pomocą K-9 Mail.

kesten broughton

unread,
Jun 27, 2014, 2:13:03 PM6/27/14
to ansible...@googlegroups.com
I've hit this before,

The problem is, sometimes it's nice to have a list to loop over especially if the client code doesn't know the keys.
Other times it would be nice to have a dict if you have the key since writing loops can be messy.

I think it would be very nice in these cases to have a dict_to_list adapter and list_to_dict adapter as jinja2 plugins, so the original datastructure can be whichever.


I got started on this but never finished.

Serge van Ginderachter

unread,
Jun 27, 2014, 2:18:43 PM6/27/14
to ansible...@googlegroups.com

On 27 June 2014 20:13, kesten broughton <kesten.b...@gmail.com> wrote:
The problem is, sometimes it's nice to have a list to loop over especially if the client code doesn't know the keys.
Other times it would be nice to have a dict if you have the key since writing loops can be messy.

I think it would be very nice in these cases to have a dict_to_list adapter and list_to_dict adapter as jinja2 plugins, so the original datastructure can be whichever.


​You can already easily use a dict as a list:

dict.keys()
dict.values()
dict.items()

Timothy Appnel

unread,
Jun 27, 2014, 4:13:42 PM6/27/14
to ansible...@googlegroups.com
Theoretically in Jinja 2.8 when it's released you could perform this operation with something like this:

{{ fusemq_auth|selectattr('username','equalto','LOGSTASH')|map(attribute='password')|first }}

selectattr and map are new to version 2.7. The 'equalto' test is the problem you'll run in to.

So the map function with an optional selectattr provides the dict_to_list function you are looking for. (Your gist wouldn't load.) I don't see how a general purpose list_to_dict would be possible without some specific logic be written.

<tim/>

Reply all
Reply to author
Forward
0 new messages