我有一个证书创建工具,可以像这样输出证书:
{
"cert": "abc123......",
"id": 10,
"key": "abc123....."
}
实际的
cert
和key
属性是base64编码的,但这与这里的问题无关。
当我从 ansible 运行它并将输出注册为变量时,它会使用转义的双引号存储:
{
"cert_output": {
"changed": true,
"delta": "0:00:00.673537",
"end": "2024-05-14 13:34:45.492559",
"failed": false,
"msg": "",
"rc": 0,
"start": "2024-05-14 13:34:44.819022",
"stderr": "",
"stderr_lines": [],
"stdout": "{\"id\":233370662,\"cert\":\"abc123...\",\"key\":\"abc123...\"}",
}
}
我找不到解析单个键的方法。
下面
set_fact
的两种口味没有按预期工作:
- set_fact:
cert: "{{ cert_output.stdout|from_json|json_query('.cert') }}"
key: "{{ cert_output.stdout|from_json|json_query('.key') }}"
- set_fact:
cert: "{{ cert_output.stdout|json_query('.cert') }}"
key: "{{ cert_output.stdout|json_query('.key') }}"
Ansible 错误:
失败了! => {“msg”:“json_query过滤器插件中的JMESPathError: 无效标记:第 0 列解析错误,标记“.” (点),用于表达: “.cert” ^"}
对于此用例,您不需要使用 JMESPath,Ansible 具有很强的 JSON 功能。一旦您有了 JSON,而不是 JSON 的字符串表示形式,由于您正确使用了
from_json
过滤器,那么您就可以使用点符号返回查询字典属性:
- set_fact:
cert: "{{ (cert_output.stdout | from_json).cert }}"
key: "{{ (cert_output.stdout | from_json).key }}"
这会导致
ok: [localhost] => changed=false
ansible_facts:
cert: abc123...
key: abc123...
注意:上面的输出是使用选项
-v
运行 playbook 时生成的,其中除其他有用信息外,还显示了 set_fact
任务的结果。
对于 JMESPath 查询,访问 JSON 的“root”节点上的 JSON 标识符只需通过寻址其键(不带任何点)即可完成,因此:
- set_fact:
cert: "{{ cert_output.stdout | from_json | json_query('cert') }}"
key: "{{ cert_output.stdout | from_json | json_query('key') }}"
结果与上面相同。