I would like to cocatenate a group of ips into a string.
example ip1:2181,ip2:2181,ip3:2181,etc
{% for host in groups['zookeeper'] %}
{{ hostvars[host]['ansible_eth0']['ipv4']['address'] }}
{% endfor %}
I have the above code, but can't seem to quite figure out how to concatenate into a string.
searching for "Jinja2 concatenate" doesn't give me the info I need.
Updated this answer, because I think I misunderstood your question.
If you want to concatenate the IP's of each host with some string, you can work with the loop controls, to check if you're in the last iteration:
{% for host in groups['zookeeper'] -%}
{{ hostvars[host]['ansible_eth0']['ipv4']['address'] }}
{%- if not loop.last %}, {% endif -%}
{%- endfor %}
Old answer:
The word you're looking for is join:
{{ hostvars[host]['ansible_eth0']['ipv4']['address'] | join(", ") }}
You can use the 'extract' filter for this (provided you use ansible>=2.1):
{{ groups['zookeeper'] | map('extract', hostvars, ['ansible_eth0', 'ipv4', 'address']) | join(',') }}
More info:
http://docs.ansible.com/ansible/playbooks_filters.html#extracting-values-from-containers
Found a similar solution at https://adamj.eu/tech/2014/10/02/merging-groups-and-hostvars-in-ansible-variables/ .
I did a set_fact using a groups variable as suggested in the post:
- hosts: all
connection: local
tasks:
- set_fact:
fqdn_list: |
{% set comma = joiner(",") %}
{% for item in play_hosts -%}
{{ comma() }}{{ hostvars[item].ansible_default_ipv4.address }}
{%- endfor %}
This relies on joiner, which has the advantage of not having to worry about the last loop conditional. Then with set_fact I can make use of the new string in later tasks.
Related
I have a use case where I would like to define the name of a macro and then apply it to one column.
A simplified example could be as follows. I have two macros defined that I want to call dynamically in my model (both take one column as an input):
cast_to_string
convert_empty_string_to_null_value
Now, I want to call them dynamically. See the example below
{%- set macro_names = ["cast_to_string", "convert_empty_string_to_null_value"] -%}
select
{% for macro_name in macro_names %}
-- this should dynamically be evaluated to `{{ cast_to_string(my_column) }}`
-- and `{{ convert_empty_string_to_null_value(my_column) }}`
{{ macro_name(my_column) }}
{% endfor %}
from my_model
However, this will throw an error saying that a string is not callable.
I also tried using {% raw %} {{ {% endraw %} to escape brackets, but that didn’t work either.
So, my question is, if there is a way to dynamically call macros in jinja/dbt?
I think it should work if you remove the quotes :
{%- set macro_names = [cast_to_string, convert_empty_string_to_null_value] -%}
So that jinja doesn't interpret it as string and you can use it as a Callable
I achieve it using this example :
{%- set macro_names = [print_lower, print_upper] -%}
{% for macro_name in macro_names %}
{{ macro_name("test") }}
{% endfor %}
and
{% macro print_lower(string) %}
{{ print(string|lower) }}
{% endmacro %}
{% macro print_upper(string) %}
{{ print(string|upper) }}
{% endmacro %}
I am configuring a Jinja template in Cisco DNAC Template editor to provision new switches. The problem I am having is getting Jinja to split the string variable within the Cisco Template tool. I tried using this split command.
{% set list1 = variable1.split(';') %}
This works fine if I hard code in the {{ HOSTNAME }} variable, for example using ABC-DEF-111-AS-10-11-12-13
{# {% set hname = '{{ HOSTNAME }}' %} #}
{% set hname = 'ABC-DEF-111-AS-10-11-12-13' %}
Device name is {{ hname }}
{% set list1 = hname.split('-') %}
{% for list in list1 %}
<p>{{ list }}</p>
{% endfor %}
The campus is {{ list1[0] }}
The building is {{ list1[1] }}
Room number is {{ list1[2] }}
Switch type is {{ list1[3] }}
IP address is {{ list1[4] }}.{{ list1[5] }}.{{ list1[6] }}.{{ list1[7] }}
However, when I use the {{ HOSTNAME }} variable to input the hostname, the split command will not split the hostname, instead it passes the hostname through in its entirity within {{ list1[0] }}. This happens even if I use the variable directly within the split command, for example.
{% set list1 = '{{ HOSTNAME }}'.split('-') %}
I have also tried splitting the resultant {{ list1[0] }} but it too just passes the hostname on through in its entirety.
I am not sure if this is a problem with the version of Jinja used in the Template Editor because I get a systax error when ever I tried using this split command:
{% set item1, item2 = variable1.split(';') %}
Is there away to get {{ HOSTNAME }} split? What am I missing?
The solution is that I should change the variable into a statement like this:
{% set list1 = **HOSTNAME**.split('-') %}
How can I pass the name of the current model using {{this}} as a parameter for a macro in a config function?
I have tried a couple of options and none of them works.
model/Table1.sql
{{ config(post_hook= calculate_test("{{this}}") ) }}
macro/calculate_test.sql
{% macro calculate_test(tableN) %}
{%- set tableName = tableN -%}
{% set sql %}
SELECT
COUNT(*) as cnt
FROM {{ tableName }}
{% endset %}
{% set results = run_query(sql) %}
{% endmacro %}
The error is:
You’re almost there! Only thing is that you’ve got extra curly brackets and misplaced quotes. The entire config block is Jinja so you don’t need the curly brackets around ‘this’.
{{ config(post_hook= “calculate_test(this)” ) }}
I can't figure out how to remove the last empty line from the output generated by a for and an if Jinja2 statments on SaltStack. I couldn't find a post pointing out the solution neither, as the solutions on internet that I could find don't involve for and if nested statements.
Any help is welcome, thanks.
This is what I tried so far:
{% for user in list_users -%}
{% if user.enabled == True -%}
{{ user.name }}:{{ user.passwd }}
{%- endif %}
{% endfor %}
user1:encrypted_pass
user2:encrypted_pass
user3:encrypted_pass
I also tried adding - at the beginning of the {endfor}:
{% for user in list_users -%}
{% if user.enabled == True -%}
{{ user.name }}:{{ user.passwd }}
{%- endif %}
{%- endfor %}
user1:encrypted_passuser2:encrypted_passuser3:encrypted_pass
Edit: this is the output that I am trying to achieve:
user1:encrypted_pass
user2:encrypted_pass
user3:encrypted_pass
PS: I had a look to the Jinja's whitespace control without success.
Jinja2 supports very useful filters to modify a string, eg.
{{ my_string|capitalize }}
What about you want to build the input string? When the string is simple you can always use
{% set my_string = string_1 + string_2 %}
{{ my_string|capitalize }}
But it would be wonderful to actually build this string using templates, just like
{% set my_string = "{{ 'a' }}b{{ 'c' }}" %}
{{ my_string|capitalize }}
that would output Abc..
Did I miss something?
Answer exists in Jinja 2.8, as documented here
The answer is
{% set my_string %}
{{ 'a'}}b{{ 'c' }}
{% endset %}