0

我正在尝试运行一个 ansible 的“uri”任务,该任务在“直到”循环中获取状态,直到返回的状态为成功或失败。我的任务如下所示:

- name: Fetching recycle status
  uri:
    url: "http://{{ restarter }}/status?job_id={{ item }}"
    method: GET
    body_format: json
    headers:
      Accept: 'application/json'
    return_content: yes
  register: restart_status
  with_items:
     - 14502414
     - 14552415
  until: (restart_status.results|json_query('[*].json')| json_query('[*][*].status')|flatten) in ['SUCCESS', 'FAILED']

restart_status是一个包含返回的 json 有效负载的变量,它看起来像这样:

{
        "changed": false,
        "results": [
            {
                "_ansible_ignore_errors": null,
                "item": 14502414,
                "json": [
                    {
                        "created_date": 1635348569000,
                        "job": {
                            "application_name": "testapp",
                            "id": 14552414,
                            "user": "gui"
                        },
                        "status": "FAILED"
                    }
                ],
                "vary": "Accept-Encoding"
            },
            {
                "_ansible_ignore_errors": null,
                "item": 14552415,
                "json": [
                    {
                        "created_date": 1635348569000,
                        "job": {
                            "application_name": "testapp",
                            "id": 14502415,
                            "user": "gui"
                        },
                        "status": "FAILED"
                    }
                ],
                "vary": "Accept-Encoding"
            }
        ]
    }

(restart_status.results|json_query('[ ] .json')| json_query('[ ][*].status')|flatten) 的输出是

ok: [localhost] => {
    "msg": [
        "FAILED",
        "FAILED"
    ]
}

我似乎无法让直到子句起作用。我尝试了多种方法,例如“包含”、“在”、“不在”、==,但没有一个起作用。这是引发的错误。

TASK [Fetching recycle status] **************************************************************************************************
fatal: [localhost]: FAILED! => {"msg": "The conditional check '(restart_status.results|json_query('[*].json')| json_query('[*][*].status')|flatten) not in ['INIT', 'PROGRESS']' failed. The error was: Unexpected templating type error occurred on ({% if (restart_status.results|json_query('[*].json')| json_query('[*][*].status')|flatten) not in ['INIT', 'PROGRESS'] %} True {% else %} False {% endif %}): 'NoneType' object is not iterable"}

非常感谢任何帮助或指出我做错了什么。

4

2 回答 2

0

不要测试累积的结果。使用直到您必须在每次迭代中测试注册变量,例如

- hosts: localhost
  tasks:
    - command: echo FAILED
      register: status
      loop: [1,2,3]
      until: status.stdout in ['FAILED', 'SUCCESS']
    - debug:
        msg: "{{ status.results|json_query('[].stdout') }}"

这个简单的例子将通过迭代。将命令更改为例如“echo XXX”。您将看到until条件在起作用。


在您的情况下,条件可能是

      until: restart_status.json.0.status in ['FAILED', 'SUCCESS']

,但我不确定为什么属性json是一个列表。也许它会保留所有尝试的结果?无论如何,为了安全起见,下面的条件也应该适用于列表中的多个项目

      until: restart_status.json|
             json_query('[].status')|unique|
             intersect(['FAILED', 'SUCCESS'])|length > 0
于 2021-10-27T16:56:13.890 回答
0

由于您收到的 JSON 响应包含输出中json[].status所示的列表,debug因此该列表的多个(动态)项目无法与in ['SUCCESS', 'FAILED'].

但是匹配所需的状态会起作用,例如'SUCCESS' in ['SUCCESS', 'FAILED']. 如果我们想匹配多个状态,我们可以使用and/or组合。

就像是:

    - debug:
        msg: Fetching recycle status
      until: |
        'SUCCESS' in restart_status.results | json_query('[].json[].status') or
        'FAILED' in restart_status.results | json_query('[].json[].status')
于 2021-10-27T16:25:51.863 回答