我有一个 Ansible 任务,它向网站发出 URI 请求以获取 JSON 响应。如果嵌套的 JSON 变量已定义,我希望 Ansible 执行某些操作,如果未定义,则执行其他操作。
- name: Get JSON from the Interwebs
uri: url="http://whatever.com/jsonresponse" return_content=yes
register: json_response
- name: Write nested JSON variable to disk
copy: content={{json_response.json.nested1.nested2}} dest="/tmp/foo.txt"
请注意,使用ignore_errors
仅适用于任务的命令失败,不适用于检查 Jinja 模板内嵌套数据结构中的未定义值。因此,如果json_response.json.nested1.nested2
没有定义,则此任务尽管已设置,仍将失败ignore_errors=yes
。
/tmp/foo.txt
如果请求失败或者请求没有定义正确的嵌套值,我该如何让这个剧本存储一些默认值?
答案1
您需要使用 jinja2 过滤器(http://docs.ansible.com/ansible/playbooks_filters.html)。在本例中,过滤器的名称是来自json。在下面的例子中,当找到密钥时我将采取一个操作,而当找不到密钥时我将采取其他操作:
---
- hosts: somehost
sudo: yes
tasks:
- name: Get JSON from the Interwebs
uri: url="https://raw.githubusercontent.com/ljharb/node-json-file/master/package.json" return_content=yes
register: json_response
- debug: msg="Error - undefined tag"
when: json_response["non_existent_tag"] is not defined
- debug: msg="Success - tag defined =>{{ (json_response.content|from_json)['scripts']['test'] }}<="
when: (json_response.content|from_json)['scripts']['test'] is defined
现在将调试替换为适当的,以采取所需的操作。
希望能帮助到你,
答案2
在寻找如何从 github api 中提取 json 字段的方法后,我偶然发现了这里。我最终得到了以下解决方案。
uri: url="https://api.github.com/repos/.../.../releases/latest" return_contents=yes
register: github_json
并在其他地方使用它,如下所示:
"{{ github_json.json.$key }}"
答案3
根据文件https://docs.ansible.com/ansible/latest/modules/uri_module.html
是否将响应正文作为字典结果中的“内容”键返回。无论此选项如何,如果报告的 Content-type 为“application/json”,则 JSON 始终加载到字典结果中名为 json 的键中。
---
- name: Example of JSON body parsing with uri module
connection: local
gather_facts: true
hosts: localhost
tasks:
- name: Example of JSON body parsing with uri module
uri:
url: https://jsonplaceholder.typicode.com/users
method: GET
return_content: yes
status_code: 200
body_format: json
register: data
# failed_when: <optional condition based on JSON returned content>
- name: Print returned json dictionary
debug:
var: data.json
- name: Print certain element
debug:
var: data.json[0].address.city