I am trying to following but I am getting this error "The conditional check 'item.vrf = 'default'' failed. The error was: template error while templating string: expected token 'end of statement block', got '='. String: {% if item.vrf = 'default' %} True {% else %} False {% endif %}" how to fix it?
proc_vrf: [{''proc'': ''T1'', ''vrf'': ''default''}, {''proc'': ''T2'', ''vrf'': ''vrf_T2''}, {''proc'': ''T3'', ''vrf'': ''default''}, {''proc'': ''T3'', ''vrf'': ''vrf_T3''}]
- name: Shut ospf for default vrf
cisco.nxos.nxos_config:
lines:
- shutdown
parents: router ospf {{ item.proc }}
save_when: modified
when: item.vrf|lower == 'default'
with_items: "{{ proc_vrf }}"
- name: Shut ospf for other vrf
cisco.nxos.nxos_config:
lines:
- shutdown
parents: router ospf {{ item.proc }}; vrf {{ proc_vrf }}
save_when: modified
when: item.vrf|lower != 'default'
with_items: "{{ proc_vrf }}"
There was an operator error. corrected comparison operator, ==
Related
I am trying to associate users in a aws-auth config map using Helm. I'd like to loop through a nested map in our values file. My attempt to do this is as follows:
mapUsers: |
{{- range $username := .Values.users }}
- groups:
- system:masters
userarn: {{ $username.adminArn }}
username: {{ $username }}
{{- end }}
And the values file is as follows:
users:
username: user.name
userArn: user/Arn
adminArn: user/AdminArn
I'm not certain if this will solve my problem and would like some feedback.
After taking feedback from #Andrew, I was able to get this to work by first changing the structure of my values file to:
users:
testuser:
username: test.user
userArn: testuser/arn
adminArn: testuser/adminArn
I then was able to update my loop to:
{{- range $k := .Values.users }}
- groups:
- system:masters
userarn: {{ .adminArn }}
username: {{ .username }}
{{- end }}
I would like to iterate over a variable in ansible yaml and add key and value in jinja template
variable:
my:
variable:
- name: test
path: /etc/apt
cert: key.crt
my template
{% for key, value in item() %}
{{key}}: {{value}}
{% endfor %}
ansible yaml
- name: test
template:
force: yes
src: test.conf.j2
dest: /tmp/test.conf"
become: yes
with_items:
- "{{ my.variable }}"
How my yaml should look like:
path: /etc/apt
cert: key.crt
You actually have three issues in your task:
When using a loop, may it be loop or all the flavour of with_* you access the element currently looped in with the variable item, so not a function like you used in your task (item())
You are doing a superfluous list of list in
with_items:
- "{{ my.variable }}"
A first step would be to do with_items: "{{ my.variable }}".
An ever better step would be to use the loop replacement of the with_* syntax as suggested in the documentation
We added loop in Ansible 2.5. It is not yet a full replacement for with_<lookup>, but we recommend it for most use cases.
So you will end up with
loop: "{{ my.variable }}"
Then accessing properties of a dictionary in Jinja is done using the syntax
{% for key, value in dict.items() %}
Source: https://jinja.palletsprojects.com/en/2.11.x/templates/#for
So in your case:
{% for key, value in item.items() %}
All together, a working playbook demonstrating this would be:
- hosts: all
gather_facts: no
tasks:
- debug:
msg: |
{% for key, value in item.items() %}
{{key}}: {{value}}
{% endfor %}
loop: "{{ my.variable }}"
vars:
my:
variable:
- name: test
path: /etc/apt
cert: key.crt
That yields the result:
PLAY [all] *******************************************************************************************************
TASK [debug] *****************************************************************************************************
ok: [localhost] => (item={'name': 'test', 'path': '/etc/apt', 'cert': 'key.crt'}) => {
"msg": " name: test\n path: /etc/apt\n cert: key.crt\n"
}
PLAY RECAP *******************************************************************************************************
localhost : ok=1 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
Now you just have to reuse this in your template and loop and you should have what you expect.
Objective
I am trying to append a string to a list belonging to a key which is a few layers down within a dictionary.
Explanation
I initialize an empty list buried within some pre-existing variable called info:
tasks:
- set_fact:
info: "{{ info | combine( { host: { repo: { folders: [] }}}, recursive=true ) }}"
In a later task, I wish to append a string to that empty list. This may happen over multiple tasks, so I don't want to replace the empty list, but add onto it as needed. I am currently trying this:
tasks:
- set_fact:
info: "{{ info | combine( { 'host': { 'repo': { 'folders': [] }}}, recursive=true ) }}"
- set_fact:
info: "{{ info.host.repo.folders + ['ERROR. folderX does not exist'] }}"
when: folderX does not exist
- set_fact:
info: "{{ info.host.repo.folders + ['ERROR. folderY does not exist'] }}"
when: folderY does not exist
However, I receive a template error:
FAILED! => {"msg": "template error while templating string: expected name or number. String: {{ info.host.repo.folder + ['ERROR. folderX does not exist'] }}"}
I know that you can simply add elements to a list when the destination is on topmost layer. For example:
- set_fact:
folders: []
- set_fact:
folders: "{{ folders + ['ERROR. folderX does not exist'] }}"
when: folderX does not exist
- set_fact:
folders: "{{ folders + ['ERROR. folderY does not exist'] }}"
when: folderY does not exist
- debug: var=folders
Which, as desired, gives:
TASK [debug] ***************************************************************************************************
"folders": [
"ERROR. folderX does not exist",
"ERROR. folderY does not exist"
]
So, how does the syntax change when I am trying to descend multiple layers and access a list that resides in a nested dictionary? Thank you!
dicts and lists in ansible are "live", so you can update them via set statements
- set_fact:
info: >-
{%- set _ = info.host.repo.update({"folders": []}) -%}
{{ info }}
- set_fact:
info: >-
{%- set _ = info.host.repo.folders.append("ERROR. folderY does not exist") -%}
{{ info }}
when: folderY does not exist
that set _ = business is because ansible's jinja does not support the do statement so one cannot have an assignment statement by itself
I'm having issues at the moment I have a map of some aws subnets with their routing tables like so ( example output via ansible) :
"subnetwork_route_map": [
{
"route_table_id": "rtb-xxxxxx",
"subnet_id": "subnet-xxxxxx"
},
{
"route_table_id": "rtb-xxxxxx",
"subnet_id": "subnet-xxxxxxx"
},
{
"route_table_id": "rtb-xxxxxx",
"subnet_id": "subnet-xxxxxx"
}
]
I wish to insert these values in to a template file and I thought I could do something like this after seeing a few example:
{% for item in subnetwork_route_map %}
{{ item[1]['subnet_id'] }},{{ item[1]['route_table_id'] }}§
{% endfor %}
how ever i'm getting an error when I try this I get an error from ansible:
fatal: [localhost]: FAILED! => {"failed": true, "msg": "dict object has no element 1"}
subnetwork_route_map is a list of dictionaries, item is an individual dictionary, you don't need the [1] part:
{% for item in subnetwork_route_map %}
{{ item['subnet_id'] }},{{ item['route_table_id'] }}§
{% endfor %}
I'm trying to access the id field in JSON in a Django template, but it has a colon in it.
When I include it in the template, I get the following error:
"Could not parse the remainder: ':id' from 'result.id.attributes.im:id'".
I've tried escaping the name and the colon with no success.
I've included the JSON output when I use it's parent, as well as the Django template.
Any suggestions?
*HTML Output with JSON when passing up the parent (result.id.attribute) *
1 id: {**u'im:id': u'422689480'**, u'im:bundleId': u'com.google.Gmail'} Name: Gmail - Google, Inc.
2 id: {u'im:id': u'530755375', u'im:bundleId': u'com.kfactormedia.mycalendarfree'} Name: MyCalendar Free - K-Factor Media, LLC.
3 id: {u'im:id': u'518972315', u'im:bundleId': u'com.click2mobile.textGramFree'} Name: Textgram - Texting with Instagram FREE - click2mobile
4 id: {u'im:id': u'521863802', u'im:bundleId': u'com.appmosys.emoji2free'} Name: Emoji 2 Free - 300+ NEW Emoticons and Symbols - Appmosys
Django Template
<html>
<body>
{% for result in app_data.entry %}
<h3>
{{ forloop.counter }}
Id: {{ result.id.attributes }}
Name: {{ result.title.label }}
{% endfor %}
</h3>
</body>
</html>
Edit to include the View:
View
def findAppRank(request,AppId=424909112):
URL="http://itunes.apple.com/us/rss/topfreeapplications/limit=300/genre=6007/json"
r=requests.get(URL)
output=r.content
data=json.loads(output)
AppData=data['feed']
t=get_template('myrank.html')
html=t.render(Context({'app_data': AppData, 'app_id': AppId }))
return HttpResponse(html)
You're looking for the slice filter.
{{ result.id.attributes|slice:"'im:id'" }}