I am checking for pushing data based upon variables set true or false.
My varaibles file which is json file has
{
"isfs" : True
}
and my template (t2.j2)has below condition
{% if '{ isfs | d() | bool }' -%}
<perform operation >
{% else -%}
<perform 2 operation
Every time it executes <perform opertaion >even if change value of json file "isfs": False.
Please pour some suggestion.
I tried d(true) and also I tried with elif condition nothing helping me
just test the variable. This shoud do what you want. Any True or true value is supposed to return true.
{% if isfs %}
cast if needed:
{% if isfs | bool %}
edit: I think i misunderstood that you are evaluating against a json file that contains '{ "isfs" : True }'. You'll need to parse the json file to get the value. Considering the json file content is in the json_file variable:
{% if json_file.isfs %}
Related
I'm using Jinja2 with YAML and have the following structure:
{%- set example = [ (20, "on"), (40, "off")] %}
- name: example_yaml
loop:
{%- for value, state in example %}
- TheNumber: {{ value }}
TheState: {{ state }}
{%- endfor %}
When the first loop is rendered, TheNumber is correct with 20, but TheState ends up being True. I've looked through the documentation and have tried adding a string filter like this:
{{ state | string }}
But that did not work either. I have also Tried switching the string "on" to something else like "StateShouldBeOn" just to test with. With that I get what I expect TheState = "StateShouldBeOn".
My question is, why is it that "on" renders to a boolean value?
Try to use 'on' instead of "on". That should help.
I am trying to upgrade a server for a web application, I have to iterate through a key value dictionary, but I am given the following error
FAILED! => {"changed": false, "msg": "AnsibleUndefinedVariable: 'ansible.utils.unsafe_proxy.AnsibleUnsafeText object' has no attribute 'iteritems'"}
I tried
{
"version":"{{ version.actual_version_number }}",
"integrations": {
{% for id, port in integration_details.items() %}
{% if integration_details is defined and integration_details is not empty %}
{{ id }} : {{ port }}
{% endif %}
{%- if not loop.last -%},{% endif %}
{% endfor %}
}
}
If anyone could help with this problem would be really appreciated!
Assuming that your data structure is a dict use if integration_details is defined and integration_details.keys()|length > 0 this will check if there are any subkeys present. If its a list use if integration_details is defined and integration_details|length > 0
But seeing the error you posted you might have a for loop with iteritems()somewhere, which is not in the code you posted.
This may be because you use python3 but want to iterate your dict with iteritems() instead of items() or your variable is not a dict but a different type.
I need to dynamically generate a dict and assign it to an Ansible var so that the same data is available to every host and does not need to be regenerated on each one. This will be looped over by a task and template. It is possible to build lists by nesting Jinja in a var definition like so:
var_list: >
[
{% set data = [] %}
{% for host in groups['all'] %}
{{ data.append(host) }}
{% endfor %}
{{ data }}
]
However, I am not able to do so with dicts:
var_dict: >
{
{% set data = dict() %}
{% for host in groups['all'] %}
{{ data | combine({host: []}) }}
{% endfor %}
{{ data }}
}
This results in a giant, garbled string: {u'host.subdom.dom.tld': []} {}...
What I am expecting is a var set to a true dict object that can have its components referenced individually (like {{ var_dict.host1[0] }}), with a structure similar to the following JSON:
{
"host1": [],
"host2": []
}
Is there a way to cause this to expand into a proper dict when assigned to the variable? Or is there perhaps another way to generate a dict from a loop without that awful set_fact hackery?
Either of your templates is broken (the first one produces nested lists, the second one prints data in loop with this expression {{ data | combine({host: []}) }}, the value of data remains empty until the end).
Jinja2 is a templating engine, you don't really need to create data structures to print them later. You can form your output directly.
For the list:
var_list: >
[ {% for host in groups['all'] %}'{{ host }}',{% endfor %} ]
For the dictionary:
var_dict: >
{ {% for host in groups['all'] %}'{{ host }}': [],{% endfor %} }
As you expect the values to be interpreted by Ansible, you don't need to pay attention to the trailing coma, otherwise there is loop.last.
I have read a number of examples of how to re-write the when clause to avoid the warning about jinja2 template delimiters {{ and }} - but have not seen any on avoid use of {% for ... %}.
I have roughly the following step:
- name: Wait for Started status to clear
uri:
url: http://{{ container.ip }}:8080/upgrade/api/v1/upgrades/{{ theuuid }}
return_content: yes
register: progress_status
until: >
{% for c in (progress_status.content | from_json).data.states %}
{{ c.state != 'Started' }}
{% if not loop.last %}and{% endif %}
{% endfor %}
retries: 30
delay: 15
The uri call returns a list of containers and their 'state' in a json form. I want to keep querying this uri until none of the containers are in the Started state.
This generates the warning due to the {% for ... %} loop.
I could do a less specific test by look at the entire response for the json string representing a state of Started. But that seems more cryptic than looking at the state of each container (building up a boolean expression of true and true and ...). But this is my alternative for now.
Or I could use a block and do the query, and then build the condition as a fact, and then use the fact as the until on the block. But that too seems harder to read.
Suggestions for how to handle this sort of pattern?
You can use selectattr/rejectattr filters to fetch/delete specific items from lists:
until: (progress_status.content | from_json).data.states | rejectattr('state','equalto','Started') | list | length == 0
Here we take (progress_status.content | from_json).data.states list, remove all elements that have state=='Started' and check length of remaining list.
Task will complete when the list after reject is empty meaning all items have Started state.
I'm using entityview to retrieve records from CRM using a liquid template. This is the code I use.
{% entityview logical_name:'new_consul', name:"Most Recent Consul" %}
{% assign cons = entityview.records %}
{% for item in cons %}
But I would like to add a filter to limit to 5 the results, so if I use this code:
{% assign count = count | default: 5 %}
{% assign recent_cons = entityview.records | recent: count %}
I get following error: Liquid syntax error: Error - Filter 'recent' does not have a default value for 'lang' and no value was supplied
What makes me think that filter should is applied correctly, so I then tried with:
{% assign languagecode = 'English' %}
{% assign recent_cons = entityview.records | recent: count,languagecode %}
But then I get this error: Liquid error: Missing a valid input parameter. Parameter name: input
How can I apply the filter to this entitiview query correctly?
Ok, found it on the adxstudios Portal documentation.
https://community.adxstudio.com/products/adxstudio-portals/documentation/configuration-guide/liquid-templates/tags/crm-entity-tags/#page_size
{% entityview logical_name:'new_consul', name:"Most Recent Consult", page_size:5 %}