Jinja "eval" type method?

Is there anything in jinja templating to “eval” a variable name? Where I can add a string to a variable, and reference another variable
I’m interesting in doing something like this (example pseudocode)

#print the mac addresses and driver (or similar)
{% for interface in ansible_interfaces %}

{{ interface }}
mac= {{ eval(‘ansible_’ + interface).macaddress }}
driver = {{ eval(‘ansible_’ + interface).module }}

{% endfor %}

Where the host variables are like this ( an example ):

“ansible_interfaces”: [
“eth1”,
“eth2”
],
“ansible_eth1”: {
“active”: false",
“device”: “eth1”,
“macaddress”: “00:00:00:FF:FF:FF”,
“module”: “igb”,
“mtu”: 1500,
“type”: “ether”
},
“ansible_eth2”: {
“active”: false",
“device”: “eth2”,
“macaddress”: “AA:00:00:FF:FF:AA”,
“module”: “ixgbe”,
“mtu”: 9000,
“type”: “ether”
},

Is something like this possible, or do I have to some combination of templating using with_items, and then using assemble to stick it together?

Thank God, no Python evals.

You can access hostvars programatically like this:

hostvars[hostname][factname]

So you can build the factname string programatically and get to them that way.

Is there anything in jinja templating to "eval" a variable name? Where I
can add a string to a variable, and reference another variable
I'm interesting in doing something like this (example pseudocode)

I did this recently for testing a lookup plugin; I think it's along the
lines of what you want:

        {% for name in names -%}

        {# Build param consisting of key and file= #}
        {%
            set param = ' '.join(( name, "file=input.csv", "default=OhNo!", "delimiter=;"))
        -%}
        {% set val = lookup('csvfile', param) -%}
        {{ name }} is in fact "{{ val }}"
        {% endfor %}

using the variables you want, of course. :slight_smile:

        -JP

Random aside: using that CSV lookup plugin will be pretty inefficient – particularly in larger setups. It will load the local file for every host in the host loop, and then once for every name in the names list.

A better way to do this would be to save the mapping as a YAML dictionary and use the stock systems in Ansible here. However, that’s not always possible.

The idea of a way to cache lookup plugin results was explored previously though technically requires some IPC so we maintain the cache in one process OR we extend fact caching proposed for 1.5 to also cache lookup plugin results when evaluated, with, say, lookup_cached, versus lookup, and specify a timeout.

lookup_cached(‘plugin_name’, ‘param string’, timeout_in_seconds)

Hmmm… ideas… :slight_smile:

Thanks God ERB templates allow to embed Ruby code.
It is discouraged, but when it’s really necessary you can do it!.