I am using Ansible and I am encountering an issue that I do not understand or know how to solve. Hopefully someone can help me.
The problem occurs with a failed_when
conditional:
fatal: [localhost]: FAILED! => { "msg": "The conditional check ''must not contain special characters or whitespace' not in result.results[0].json['localizedMessage']' failed. The error was: error while evaluating conditional ('must not contain special characters or whitespace' not in result.results[0].json['localizedMessage']): 'dict object' has no attribute 'results'" }
My task is:
- name: Create instance - must not contain special characters or whitespace uri: url: "https://{{PROXY_ADDRESS}}/api/sol005/etsi/nslcm/v2/ns_instances" status_code: 400 validate_certs: no body_format: json method: POST headers: Content-type: application/json Authorization: "{{'Bearer'+' '+access_token}}" Version: "2.0.0" Accept: "*/*" body: > { "nsdId": "instance::int::1.0", "nsName": "{{ item }}", "nsDescription": "Test instance with name containing invalid characters." } register: result # - set_fact: # localizedMessage: "{{ result.results[0].json['localizedMessage'] }}" with_items: - "caesar:test" failed_when: "'must not contain special characters or whitespace' not in result.results[0].json['localizedMessage']"
In attempting to debug, I have written the following:
- debug: msg: - "============ Printing result output ============" - "Showing result type: {{ result | type_debug }}" - "Showing result contents: {{ result}}" - "Showing result.keys(): {{ item }}" with_items: "{{ result.keys() }}" - debug: msg: - "============ Printing result.results output ============" - "Showing result.results type: {{ result.results | type_debug }}" - "Showing result.results contents: {{ result.results }}" - debug: msg: - "============ Printing result.results[0] output ============" - "Showing result.results[0].type: {{ result.results[0] | type_debug }}" - "Showing result.results[0].contents: {{ result.results[0] }}" - "Showing result.results[0].keys(): {{ item }}" with_items: "{{ result.results[0].keys() }}" - debug: msg: - "============ Printing result.results[0].json output ============" - "Showing result.results[0].json type: {{ result.results[0].json | type_debug }}" - "Showing result.results[0].json contents: {{ result.results[0].json }}" - "Showing result.results[0].json.keys(): {{ item }}" with_items: "{{ result.results[0].json.keys() }}" - debug: msg: - "============ Printing result.results[0].json.localizedMessage output ============" - "Showing result.results[0].json.localizedMessage type: {{ result.results[0].json.localizedMessage | type_debug }}" - "Showing result.results[0].json.localizedMessage contents: {{ result.results[0].json.localizedMessage }}"
where, I think, the important information here is:
"============ Printing result output ============", "Showing result type: dict", "Showing result.keys(): dict_keys(['results', 'msg', 'changed'])" "============ Printing result.results output ============", "Showing result.results type: list", "============ Printing result.results[0] output ============", "Showing result.results[0].type: dict", "Showing result.results[0].keys(): dict_keys(['redirected', 'url', 'status', 'x_content_type_options', 'x_xss_protection', 'cache_control', 'pragma', 'expires', 'strict_transport_security', 'x_frame_options', 'vary', 'content_type', 'transfer_encoding', 'date', 'connection', 'server', 'msg', 'elapsed', 'changed', 'json', 'invocation', 'failed', 'item', 'ansible_loop_var'])" "============ Printing result.results[0].json output ============", "Showing result.results[0].json type: dict", "Showing result.results[0].json.keys(): dict_keys(['url', 'localizedMessage', 'details'])" "============ Printing result.results[0].json.localizedMessage output ============", "Showing result.results[0].json.localizedMessage type: AnsibleUnsafeText", "Showing result.results[0].json.localizedMessage contents: A INVALID_REQUEST error has occurred: name must not contain special characters or whitespace (excluding: '-', '_')"
I am new to Ansible, perhaps that is why I am not seeing it, but with the wording 'dict object' has no attribute 'results'
it suggests that result
, which is a dict, does not have the attribute results
, which my debugging suggests it does.
I have been able to traverse to result.results[0].json
& result.results[0].json.localizedMessage
so it looks OK to me.
Can anyone advise? I would like to understand where I am going wrong, alternatively I’ll take suggestions on performing the failed_when
check using some other approach.
Advertisement
Answer
Your issue is coming from the fact that Ansible is creating results
in a very peculiar way:
- The items are registered as if you where using no loop at all, and you can reference the previous element via your registered variable.
- When you exist the loop, then the
results
key is created in the dictionary and then populated from all the results.
This is described in a really short fashioned way in this sentence and example:
During iteration, the result of the current item will be placed in the variable:
- name: Place the result of the current item in the variable shell: echo "{{ item }}" loop: - one - two register: echo changed_when: echo.stdout != "one"
So if you want a self registered task that check for its own items status you will just have to do something like:
failed_when: "'must not contain special characters or whitespace' not in result.json.localizedMessage"
Here are two example playbooks:
- The playbook
That yields the recap:
- hosts: localhost gather_facts: no tasks: - uri: url: "{{ item }}" loop: - https://httpbin.org/get - https://httpbin.org/anything register: result failed_when: "result.json.url == 'https://httpbin.org/get'"
PLAY [localhost] *************************************************************************************************** TASK [uri] ********************************************************************************************************* failed: [localhost] (item=https://httpbin.org/get) => {"access_control_allow_credentials": "true", "access_control_allow_origin": "*", "ansible_loop_var": "item", "changed": false, "connection": "close", "content_length": "274", "content_type": "application/json", "cookies": {}, "cookies_string": "", "date": "Fri, 18 Dec 2020 18:17:12 GMT", "elapsed": 0, "failed_when_result": true, "item": "https://httpbin.org/get", "json": {"args": {}, "headers": {"Accept-Encoding": "identity", "Host": "httpbin.org", "User-Agent": "ansible-httpget", "X-Amzn-Trace-Id": "Root=1-5fdcf228-559950431b1315ce1ea53e71"}, "url": "https://httpbin.org/get"}, "msg": "OK (274 bytes)", "redirected": false, "server": "gunicorn/19.9.0", "status": 200, "url": "https://httpbin.org/get"} ok: [localhost] => (item=https://httpbin.org/anything) PLAY RECAP ********************************************************************************************************* localhost : ok=0 changed=0 unreachable=0 failed=1 skipped=0 rescued=0 ignored=0
- The playbook
That yields the recap:
- hosts: localhost gather_facts: no tasks: - uri: url: "{{ item }}" loop: - https://httpbin.org/get - https://httpbin.org/anything register: result failed_when: "result.json.url == 'https://httpbin.org/anything'"
PLAY [localhost] *************************************************************************************************** TASK [uri] ********************************************************************************************************* ok: [localhost] => (item=https://httpbin.org/get) failed: [localhost] (item=https://httpbin.org/anything) => {"access_control_allow_credentials": "true", "access_control_allow_origin": "*", "ansible_loop_var": "item", "changed": false, "connection": "close", "content_length": "362", "content_type": "application/json", "cookies": {}, "cookies_string": "", "date": "Fri, 18 Dec 2020 18:18:40 GMT", "elapsed": 0, "failed_when_result": true, "item": "https://httpbin.org/anything", "json": {"args": {}, "data": "", "files": {}, "form": {}, "headers": {"Accept-Encoding": "identity", "Host": "httpbin.org", "User-Agent": "ansible-httpget", "X-Amzn-Trace-Id": "Root=1-5fdcf280-71b7cca020b6fda0055b4603"}, "json": null, "method": "GET", "origin": "127.0.0.1", "url": "https://httpbin.org/anything"}, "msg": "OK (362 bytes)", "redirected": false, "server": "gunicorn/19.9.0", "status": 200, "url": "https://httpbin.org/anything"} PLAY RECAP ********************************************************************************************************* localhost : ok=0 changed=0 unreachable=0 failed=1 skipped=0 rescued=0 ignored=0