1

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

Marek
  • 127
  • 1
  • 8

1 Answers1

0

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') }}"
Zeitounator
  • 38,476
  • 7
  • 53
  • 66
  • Solution 1 works for me, thanks. I cant use Solution 2 as the hostname in this scenario is always a different , based on the result of the module – Marek Nov 20 '19 at 01:28