Compare two grain values inside state.sls using jinja expressions - jinja2

I am creating a state which will trigger some module if both of the grains are not matching. I have tried several options, but no luck.
Based on comparison, False will trigger my module and that module will change GRAIN_B value to match with GRAIN_A. So during every highstate my module will not get triggered, unless there is a change in GRAIN_A.
Any suggestions please.
I have tried several jinja expressions.
{% if grains['GRAIN_A'] not in grains.get('GRAIN_B','None') %}
{% set GRAIN_B = grains.get('GRAIN_B','None') %}
{% if grains['GRAIN_A'] != {{ GRAIN_B }} %}```
```{% if grains['GRAIN_A'] not in grains.get('GRAIN_B','None') %}
MY_MODULE:
module.run:
- func: MYMODULE.FUNCTION_A
{% endif %}```

Issue fixed, there is a \n character in my GRAIN_A output, which makes the evaluation condition fails.
This condition works already.
{% if grains['GRAIN_A'] not in grains.get('GRAIN_B','None') %}
MY_MODULE:
module.run:
- func: MYMODULE.FUNCTION_A
{% endif %}

Related

Condition based on the three first letters of a string?

In my Jinja template, model.DataType value can be user defined or built in. My requirenement is if model.DataType start with the three letters ARR, then do a specific operation.
Example of values:
ARRstruct124
ARR_int123
ARR123123
CCHAR
UUINT
etc.
{% set evenDataType = model.eventDataType %}
{%if evenDataType | regex_match('^ARR', ignorecase=False) %}
// do the operation
{%else%}
// do the operation
{% endif %}
With this template, I am getting the error
{%if evenDataType | regex_match('^ARR', ignorecase=False) %}
jinja2.exceptions.TemplateAssertionError: no filter named 'regex_match'
There is indeed no regex_match filter in the Jinja builtin filters. You might have found some examples using it, but this is an additional filter provided by Ansible, so it won't work outside of Ansible.
This said, your requirement does not need a regex to be fulfilled, you can use the startswith() method of a Python string.
So, you template should be:
{% set evenDataType = model.eventDataType %}
{% if evenDataType.startswith('ARR') %}
`evenDataType` starts with 'ARR'
{% else %}
`evenDataType` does not starts with 'ARR'
{% endif %}

Passing list of Relation object to dbt_utils.union_relation macro fails

Related to dbt and jinja2
I am using union_relations from dbt_utils package (0.5.0).
I created my macro which takes list of fully qualified name (like database.schema.identifier) splits it and uses api.Relations.create (link) to create a relation and append each relation to a list.
{{ list_of_relation }} is given to dbt_utils.union_relations(as relations=my_macro([list of fully qualified names])), it's giving me an _is_relation error, I did use log to debug and see if it actually creates a relation and it does. What could be wrong?
It sounds like you have a macro written something like this:
{% macro my_macro(names) %}
{% set list_of_relations = [] %}
{% for name in names %}
{% set relation = something(name) %}
{% do list_of_relations.append(relation) %}
{% endfor %}
{{ list_of_relations }}
{% endmacro %}
Instead of using {{ list_of_relation }}, you’ll want {{ return(list_of_relation) }} or {% do return(list_of_relation) %}. The problem is that {{ ... }} turns things into strings in jinja macros, and macros by default return strings.
The documentation on return is here.

Hide attribute definition if the value is empty in Jinja?

<vcpu placement='{{cpu.placement}}' cpuset='{{cpu.cpuset}}' current={{cpu.current}}>{{ cpu['maximum'] }}</vcpu>
Giving that we have 3 possible attributes and any of them can be empty.
Is there a neat way to hide the attribute definition if the value is empty? Let's say if cpu.placement is empty, the line placement='' shouldn't be there in the XML definition.
Just put the attribute definition inside an if-block:
<vcpu
{% if cpu.placement %}placement='{{cpu.placement}}'{% endif %}
{% if cpu.cpuset %}cpuset='{{cpu.cpuset}}'{% endif %}
{% if cpu.current %}current={{cpu.current}}>{{ cpu['maximum'] }}{% endif %}
</vcpu>
See the list of builtin tests in you need more complicated test for a variable.

Jinja "==" (compare condition) doesn't work?

while writing an application in django, I've encountered a problem. I want to make page-number links, with current page not being a link. So in template I do this:
{% for i in pages %}
{% if i == curr_page %} {{ i }}
{% else %} {{ i }}
{% endif %}
Only problem? Jinja doesn't seem to notice two numbers being equal. I've changed the 2nd line to {% if i != curr_page %} {{i}}!={{curr_page}} and got "... 5!=6 6!=6 7!=6 ...".
What should I do?
Because they are not of same data type. In your view, cast them to int before passing to context dict.
pages = list(map(int, pages))
curr_page = int(curr_page)

How to check if a variable is an integer in Jinja2?

The aim is to check whether a variable is an integer and if that is true insert hello.
Attempt
{% if int(variable) %} hello {% endif %}
Result
'int' is undefined"
To use the Jinja2 int builtin filter (which tries to cast the value to an int):
You need to use the filter format, like this:
{% if variable|int != 0 %} hello {% endif %}
By default, if casting to int fails it returns 0, but you can change this by specifying a different default value as the first parameter. Here I've changed it to -1 for a case where 0 might be a valid value for variable.
{% if variable|int(-1) != -1 %} hello {% endif %}
see the: Jinja2 Docs - int builtin filter for more info
To use the Jinja2 number builtin test (which returns true if the variable is already a number):
a better solution, rather than using the int filter (which will cast a integer like string to an int) is to use the builtin test number, like this:
{% if variable is number %} hello {% endif %}
see the: Jinja2 Docs - number builtin test
For anyone using Salt, this did not work for me when put is saltstack state.
{% if variable|number %} hello {% endif %}
This did work however:
{% if variable is number %} hello {% endif %}
None of these solutions worked for me, however this did :
{% if variable is even or variable is odd %}