i bumped into an issue after migrated from python2 to python3. Seems that migration somehow changed the way how json query is being processed. Maybe anyone has a hint how to fix this
vars:
vmk_out:
host_vmk_info:
hostname:
[
{
ipv4_address: "10.10.10.101",
ipv4_subnet_mask: "255.255.255.0",
stack: "defaultTcpipStack"
},
{
ipv4_address: "10.10.20.101",
ipv4_subnet_mask: "255.255.255.0",
stack: "vmotion"
}
]
tasks:
- name: Extract list of IPs
set_fact:
output: "{{ vmk_out.host_vmk_info.values() |json_query('[].ipv4_address') }}"
Above ran under Python2 with Ansible 2.9.1 returns list of IP addresses but running the same under Python3 returns the empty list
I did not take time to dig into the root of the problem, but there is clearly a difference in the return of the values()
function between python 2.7 and 3.x.
Here is what a direct debug or vmk_out.host_vmk_info.values()
looks like from my tests:
ansible 2.9.1 - python 3.6
ok: [localhost] => {
"msg": "dict_values([[{'ipv4_address': '10.10.10.101', 'ipv4_subnet_mask': '255.255.255.0', 'stack': 'defaultTcpipStack'}, {'ipv4_address': '10.10.20.101', 'ipv4_subnet_mask': '255.255.255.0', 'stack': 'vmotion'}]])"
}
ansible 2.9.1 - python 2.7
ok: [localhost] => {
"msg": [
[
{
"ipv4_address": "10.10.10.101",
"ipv4_subnet_mask": "255.255.255.0",
"stack": "defaultTcpipStack"
},
{
"ipv4_address": "10.10.20.101",
"ipv4_subnet_mask": "255.255.255.0",
"stack": "vmotion"
}
]
]
}
You have 2 solutions to fix your current code and make it compatible with both versions.
Solution 1: make sure the output of values()
always produces a list:
output: "{{ vmk_out.host_vmk_info.values() | list | json_query('[].ipv4_address') }}"
Solution 2: stop using values()
and directly map the existing hostname
list
output: "{{ vmk_out.host_vmk_info.hostname | json_query('[].ipv4_address') }}"