Collectives™ on Stack Overflow

Find centralized, trusted content and collaborate around the technologies you use most.

Learn more about Collectives

Teams

Q&A for work

Connect and share knowledge within a single location that is structured and easy to search.

Learn more about Teams

I am trying to run an ansible "uri" task that fetches the status in an "until" loop till the status returned is either SUCCESS or FAILED. My task looks like this:

- name: Fetching recycle status
    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 is a variable that contains the json payload that is returned and it looks like this:

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

The output of (restart_status.results|json_query('[].json')| json_query('[][*].status')|flatten) is

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

I somehow cant seem to get the until clause to work.I have tried multiple things like "contain", "in" ,"not in", ==, but none of it is working. This is the error that is thrown.

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

Any help or pointer to what I am doing wrong is greatly appreciated.

until is testing the condition on each iteration, i.e. you have to test restart_status. Do not test restart_status.results which is the cumulative list of all results. Test it on a simpler example first. – Vladimir Botka Oct 27, 2021 at 16:33 You say that you want to run the task " till the status returned is either SUCCESS or FAILED". Both iterations in the results are FAILED. Just to be sure, is this the expected result? – Vladimir Botka Oct 27, 2021 at 16:43 yes. That is expected. It can be both successes, both failures or a combination of the two. – sdhir Oct 27, 2021 at 17:18

Since the JSON response you receive contains a list in json[].status as shown in debug output, the multiple (dynamic) items of that list cannot be matched with in ['SUCCESS', 'FAILED'].

However matching the desired status would work, like 'SUCCESS' in ['SUCCESS', 'FAILED']. If we want to match multiple statuses, we can use and/or combination.

Something like:

    - 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')
                Thank you so much for your response. I still get the same error  with the code below                                                                                                        - 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: |     'FAILED' in restart_status.results|json_query('[].json[].status')
– sdhir
                Oct 27, 2021 at 18:06
                The error posted in question relates to using conditions with NoneType, which is not what the debug output shows. Using the same data structure, I'm able to match these conditions. Is it the same error as before?
– seshadri_c
                Oct 28, 2021 at 3:53

Do not test the cumulative results. Using until you have to test the registered variable in each iteration, e.g.

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

This trivial example will pass the iterations. Change the command to e.g. "echo XXX". You'll see the until condition in action.

In your case, the condition might be

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

, but I'm not sure why the attribute json is a list. Maybe it keeps the results from all attempts? Anyway, to be on the safe side, the condition below should work also with multiple items in the list

      until: restart_status.json|
             json_query('[].status')|unique|
             intersect(['FAILED', 'SUCCESS'])|length > 0
        

Thanks for contributing an answer to Stack Overflow!

  • Please be sure to answer the question. Provide details and share your research!

But avoid

  • Asking for help, clarification, or responding to other answers.
  • Making statements based on opinion; back them up with references or personal experience.

To learn more, see our tips on writing great answers.