Ansible:使用json_query选择嵌套值

时间:2019-05-08 13:28:37

标签: ansible jinja2

我正在尝试通过REST API和ansbile的uri模块验证几个服务端点

    - name: Wait until service is fully deployed
      local_action:
        module: uri
        url: http://somerestserver/{{ app_name }}-{{ item }}/tasks
        methon: GET
      register: response
      loop: "{{ range(0, instances) | list }}"

响应变量看起来像这样:

"response": {
        "changed": false,
        "msg": "All items completed",
        "results": [
            {
                "item": 0,
                "json": {
                    "tasks": [
                        {
                            "appId": "node-0",
                            "healthCheckResults": [
                                {
                                    "alive": true,
                                    ...
                                }
                            ],
                            ...
                        }
                    ]
                },
                "msg": "OK (674 bytes)",
            },
            {
                "item": 1,
                "json": {
                    "tasks": [
                        {
                            "appId": "node-1",
                            "healthCheckResults": [
                                {
                                    "alive": true,
                                    ...
                                }
                            ],
                        }
                    ]
                },
                "msg": "OK (674 bytes)",
            },
            {
                "item": 2,
                "json": {
                    "tasks": [
                        {
                            "appId": "node-2",
                            "healthCheckResults": [
                                {
                                    "alive": true,
                                    ...
                                }
                            ],
                        }
                    ]
                },
                "msg": "OK (674 bytes)",
            }
        ]
    }

我现在想做的就是等到我的所有服务报告alive: true

    - name: Wait until service is fully deployed
      local_action:
        module: uri
        url: http://somerestserver/{{ app_name }}-{{ item }}/tasks
        methon: GET
      register: response
      loop: "{{ range(0, instances) | list }}"
      until: <All services report alive>

有没有简单的方法可以做到这一点?我尝试过

until: response | json_query('results[*].json.tasks[*].healthCheckResults[*].alive') == [true]*instances

不幸的是,这不起作用

1 个答案:

答案 0 :(得分:1)

因此,今天我了解到可以将loopuntil组合在一个任务上,这真是令人惊讶。太酷了。

无论如何,您是如此接近解决方案。给定您的输入数据,您的查询将产生以下结果:

[
  [
    [
      true
    ]
  ],
  [
    [
      true
    ]
  ],
  [
    [
      true
    ]
  ]
]

这永远不会与您要比较的[true, true, true]列表相匹配。您只需要应用几个jmespath flatten运算符,就像这样:

results[*].json.tasks[*].healthCheckResults[*].alive[][]

给您输入示例,结果为:

[true, true, true]

在您的剧本中,应该是:

- name: Wait until service is fully deployed
  local_action:
    module: uri
    url: http://somerestserver/{{ app_name }}-{{ item }}/tasks
    methon: GET
  register: response
  loop: "{{ range(0, instances) | list }}"
  until: response|json_query('results[*].json.tasks[*].healthCheckResults[*].alive[][]') == [true]*instances

将来,您可以通过将数据粘贴到http://jmespath.org/的文本框中,然后在其上方键入查询来尝试查询。