嵌套json_query

时间:2019-05-10 08:07:31

标签: ansible json-query

我具有以下json结构。

    "results": [
        {
            "ltm_pools": [
                {
                    "members": [
                        {
                            "full_path": "/Common/10.49.128.185:8080",
                        },
                        {
                            "full_path": "/Common/10.49.128.186:8080",
                        }

                    "name": "Staging-1-stresslab",
                },
                {
                    "members": [
                        {
                            "full_path": "/Common/10.49.128.187:0",
                        },
                        {
                            "full_path": "/Common/10.49.128.188:0",
                        }
                    ],
                    "name": "Staging-2-lab",
                },

尝试执行此类操作时出现错误

  - debug:
      msg: "{{item[0].host}} --- {{ item[1] }} ---  {{ item[2] }}"
    with_nested:
      - "{{F5_hosts}}"
      - "{{bigip_facts | json_query('[results[0].ltm_pools[*].name]') | flatten }}"
      - "{{bigip_facts | json_query('[results[0].ltm_pools[?name.contains(@,'Staging'].members[::2].full_path]') | flatten }}"

我无法使第三个阵列正常工作。

我想从名称包含登台的所有对象中打印偶数成员full_path变量。

我希望有人可以帮助我,我为此一直挣扎了几天。

2 个答案:

答案 0 :(得分:0)

我做了一些修改,但还是没有运气

- name: "Debug ltm-pools"
  vars:
    query: "results[0].ltm_pools[?name.contains(@,'Staging') == 'true'].members[::2].full_path"
  debug:
    msg: "{{item[0].host}} --- {{ item[1] }} --  {{ item[2] }}"
  with_nested:
    - "{{F5_hosts}}"
    - "{{bigip_facts | json_query('[results[0].ltm_pools[*].name]') | flatten }}"
    - "{{bigip_facts | json_query(query) | flatten }}"

错误

fatal: [dtvsbepsta1avrbnc2-mgt]: FAILED! => {"msg": "JMESPathError in json_query filter plugin:\nIn function contains(), invalid type for value: MUM1_pool, expected one of: ['array', 'string'], received: \"unknown\""}

答案 1 :(得分:0)

根据我自己看到/阅读/尝试过的内容,您陷入了以下错误:https://github.com/ansible/ansible/issues/27299

这是Ansible运行的“包含” JMESPath函数的问题,引用一下: https://github.com/ansible/ansible/issues/27299#issuecomment-331068246

  

该问题与Ansible为字符串使用自己的类型有关:AnsibleUnicodeAnsibleUnsafeText。   而且,只要jmespath库具有非常严格的类型检查,它就不能接受这种类型作为字符串文字。

还有一个建议的解决方法,如果将变量转换为json并返回,则其中的字符串具有正确的类型。简而言之,这是行不通的:

"{{bigip_facts | json_query('results[0].ltm_pools[?name.contains(@,`Staging`)==`true`].members[::2].full_path') }}"

但是这样做:

"{{bigip_facts | to_json | from_json | json_query('results[0].ltm_pools[?name.contains(@,`Staging`)==`true`].members[::2].full_path') }}"

我设法运行了这样的代码:

- hosts: all
  gather_facts: no
  tasks:
    - set_fact:
        bigip_facts: 
          results: 
            - ltm_pools:
                - members: 
                    - full_path: "/Common/10.49.128.185:8080"
                    - full_path: "/Common/10.49.128.186:8080"
                  name: "Staging-1-stresslab"
                - members: 
                    - full_path: "/Common/10.49.128.187:0"
                    - full_path: "/Common/10.49.128.188:0"
                  name: "Staging-2-stresslab"

    - name: "Debug ltm-pools"
      debug:
        msg: "{{ item }}"
      with_items:
        - "{{bigip_facts | to_json | from_json | json_query('results[0].ltm_pools[?name.contains(@,`Staging`)==`true`].members[::2].full_path') }}"

它可以按您想要的方式工作:

PLAY [all] *****************************************************************************************

TASK [set_fact] ************************************************************************************
ok: [localhost]

TASK [Debug ltm-pools] *****************************************************************************
ok: [localhost] => (item=[u'/Common/10.49.128.185:8080']) => {
    "msg": [
        "/Common/10.49.128.185:8080"
    ]
}
ok: [localhost] => (item=[u'/Common/10.49.128.187:0']) => {
    "msg": [
        "/Common/10.49.128.187:0"
    ]
}

PLAY RECAP *****************************************************************************************
localhost                  : ok=2    changed=0    unreachable=0    failed=0