Ansible json_query 在 python3 和 python2 中的不同结果

Ansible json_query different result in python3 vs python2

我从 python2 迁移到 python3 后遇到了一个问题。似乎迁移以某种方式改变了 json 查询的处理方式。也许有人知道如何解决这个问题

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') }}"

运行 上面 Python2 与 Ansible 2.9.1 returns IP 地址列表但 运行 Python3 returns 下相同空列表

我没有花时间深究问题的根源,但是python 2.7 和[=] 之间的values() 函数的return 明显不同。 43=].

这是直接调试或 vmk_out.host_vmk_info.values() 从我的测试中看起来的样子:

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"
            }
        ]
    ]
}

您有 2 个解决方案来修复您当前的代码并使其与两个版本兼容。

解决方案 1:确保 values() 的输出始终生成一个列表:

output: "{{ vmk_out.host_vmk_info.values() | list | json_query('[].ipv4_address') }}"

方案二:停止使用values(),直接映射已有的hostname列表

output: "{{ vmk_out.host_vmk_info.hostname | json_query('[].ipv4_address') }}"