Ansible json_在python3和python2中查询不同的结果

Ansible json_在python3和python2中查询不同的结果,ansible,json-query,Ansible,Json Query,从python2迁移到python3后,我遇到了一个问题。迁移似乎以某种方式改变了json查询的处理方式。也许任何人都有一个解决这个问题的方法 vars: vmk_out: host_vmk_info: hostname: [ { ipv4_address: "10.10.10.101", ipv4_subnet_mask: "255.255.255.0",

从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返回IP地址列表,但在Python3下运行同样的操作会返回空列表

我没有花时间深入研究问题的根源,但是Python2.7和3.x之间的
values()
函数的返回明显不同

以下是直接调试或
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'}]])"
}
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"
            }
        ]
    ]
}

ansible 2.9.1-python 2.7

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

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

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

output: "{{ vmk_out.host_vmk_info.values() | list | json_query('[].ipv4_address') }}"
解决方案2:停止使用
值()
,直接映射现有的
主机名
列表

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

我没有花时间深入研究问题的根源,但python 2.7和3.x之间的
values()
函数的返回显然存在差异

以下是直接调试或
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'}]])"
}
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"
            }
        ]
    ]
}

ansible 2.9.1-python 2.7

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

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

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

output: "{{ vmk_out.host_vmk_info.values() | list | json_query('[].ipv4_address') }}"
解决方案2:停止使用
值()
,直接映射现有的
主机名
列表

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

解决方案1适合我,谢谢。我不能使用解决方案2,因为根据moduleGlad的结果,这种情况下的主机名总是不同的,我可以提供帮助。如果这解决了您的问题,您应该接受答案,以便其他用户知道它已解决,并最终投票表决,这是解决方案1对我有效,谢谢。我不能使用解决方案2,因为根据moduleGlad的结果,这种情况下的主机名总是不同的,我可以提供帮助。如果这解决了您的问题,您应该接受答案,以便其他用户知道它已解决,并最终投票决定它是否已解决