I switched from using Python2 to Python3 on the Ansible controller side.
I was using the expression {{ osd['data_devices'].items()[0][0] }}
in a Jinja2 template loop {% for osd in osd_spec %}
to get the key paths
from the below dictionary:
osd_spec:
- spec_name: osd_spec1
data_devices:
paths:
- /dev/sdg
- /dev/sdh
- spec_name: osd_spec2
data_devices:
paths:
- /dev/sda
- /dev/sdb
After switching to Python3 the expression did not work anymore and I am getting the error:
dict_items object has no element 0
I then figured out that the items()
function in Python3 returns a view object instead of a list and though, as suggested here, the output should be wrapped by a list.
Trying list(d.items())[0][0]
in Python3 works as expected.
What would be the equivalent expression in Jinja2?
I tried {{ osd['data_devices'].items() | list[0] }}
, but, this didn't work.
Any ideas?
CodePudding user response:
On your dictionary, you could use the keys()
function and do:
{{ (osd.data_devices.keys() | list)[0] }}
Or use the dict2items
filter and do:
{{ (osd.data_devices | dict2items)[0].key }}
As a demonstration, given:
- block:
- debug:
msg: >-
{% for osd in osd_spec %}
{{- (osd.data_devices | dict2items)[0].key -}}
{% endfor %}
- debug:
msg: >-
{% for osd in osd_spec %}
{{- (osd.data_devices.keys() | list)[0] -}}
{% endfor %}
vars:
osd_spec:
- spec_name: osd_spec
data_devices:
paths:
- /dev/sdg
- /dev/sdh
It will yield:
TASK [debug] ******************************************************
ok: [localhost] =>
msg: paths
TASK [debug] ******************************************************
ok: [localhost] =>
msg: paths
CodePudding user response:
Grouping the statement will do the job
{{ (osd.data_devices.items()|list)[0][0] }}
Defining a variable will also work
{% set paths = osd.data_devices.items() | list %}
{{ paths[0][0] }}