我什么时候应该在Ansible中使用from_json 过滤器?
我发现有时使用它有时会产生影响.
请考虑以下示例,说明我得到的不一致.
反向顺序包括:问题 - 预期结果 - 实际结果 - 剧本 - 数据.数据来自这个问题,剧本基于这个答案.
问题:
为什么将json_query以下表达式的左侧部分(之前)存储在变量中然后json_query对变量使用会导致表达式的计算方式不同?
"{{ lookup('file','test.json') | json_query(query) }}"
Run Code Online (Sandbox Code Playgroud)
为什么添加from_json过滤器会改变结果(但如果处理变量则不会):
"{{ lookup('file','test.json') | from_json | json_query(query) }}"
Run Code Online (Sandbox Code Playgroud)预期结果:
最后四个任务应该给出相同的结果.或者,最后两个任务应该提供与前两个任务相同的结果.
实际结果(仅限最后四个任务):
一项任务结果不同.
TASK [This query is run against lookup value with from_json stored in a variable] ***
ok: [localhost] => {
"msg": [
678
]
}
TASK [This query is run against lookup value without from_json stored in a variable] ***
ok: [localhost] => {
"msg": [
678
]
}
TASK [This query is run directly against lookup value with from_json] **********
ok: [localhost] => {
"msg": [
678
]
}
TASK [This query is run directly against lookup value without from_json - the result is empty - why?] ***
ok: [localhost] => {
"msg": ""
}
Run Code Online (Sandbox Code Playgroud)剧本:
---
- hosts: localhost
gather_facts: no
connection: local
tasks:
- set_fact:
from_lookup_with_from_json: "{{ lookup('file','test.json') | from_json }}"
- set_fact:
from_lookup_without_from_json: "{{ lookup('file','test.json') }}"
- name: Save the lookup value stored in a variable in a file for comparison
copy: content="{{ from_lookup_with_from_json }}" dest=./from_lookup_with_from_json.txt
- name: Save the lookup value stored in a variable in a file for comparison (they are the same)
copy: content="{{ from_lookup_without_from_json }}" dest=./from_lookup_without_from_json.txt
- name: This query is run against lookup value with from_json stored in a variable
debug: msg="{{ from_lookup_with_from_json | json_query(query) }}"
vars:
query: "Foods[].{id: Id, for: (Tags[?Key=='For'].Value)[0]} | [?for=='Tigger'].id"
- name: This query is run against lookup value without from_json stored in a variable
debug: msg="{{ from_lookup_without_from_json | json_query(query) }}"
vars:
query: "Foods[].{id: Id, for: (Tags[?Key=='For'].Value)[0]} | [?for=='Tigger'].id"
- name: This query is run directly against lookup value with from_json
debug: msg="{{ lookup('file','test.json') | from_json | json_query(query) }}"
vars:
query: "Foods[].{id: Id, for: (Tags[?Key=='For'].Value)[0]} | [?for=='Tigger'].id"
- name: This query is run directly against lookup value without from_json - the result is empty - why?
debug: msg="{{ lookup('file','test.json') | json_query(query) }}"
vars:
query: "Foods[].{id: Id, for: (Tags[?Key=='For'].Value)[0]} | [?for=='Tigger'].id"
Run Code Online (Sandbox Code Playgroud)数据(test.json):
{ "Foods" :
[ { "Id": 456
, "Tags":
[ {"Key":"For", "Value":"Heffalump"}
, {"Key":"Purpose", "Value":"Food"}
]
}
, { "Id": 678
, "Tags":
[ {"Key":"For", "Value":"Tigger"}
, {"Key":"Purpose", "Value":"Food"}
]
}
, { "Id": 911
, "Tags":
[ {"Key":"For", "Value":"Roo"}
, {"Key":"Purpose", "Value":"Food"}
]
}
]
}
Run Code Online (Sandbox Code Playgroud)Kon*_*rov 14
json_query 需要Python对象(dict)作为输入,如果用字符串提供它,它会给出空字符串作为结果.
由于Ansible模板引擎棘手的工作,你会得到不同的结果.
我绝对应该在我的网站上写一篇关于它的帖子......
在评估jijna2表达式后,Ansible尝试将复杂类型转换为Python对象(如dict或list).看到我的其他答案.
在你的情况下:
1.
- set_fact:
from_lookup_with_from_json: "{{ lookup('file','test.json') | from_json }}"
Run Code Online (Sandbox Code Playgroud)
from_lookup_with_from_json是一个字典,因为您手动将JSON字符串从文件转换为带有from_json过滤器的dict .
2.
- set_fact:
from_lookup_without_from_json: "{{ lookup('file','test.json') }}"
Run Code Online (Sandbox Code Playgroud)
from_lookup_with_from_json成为dict,因为当jinja2表达式结束时,Ansible会转换它}}.所以from_json实际上不需要作为链中的最后一个过滤器.
3.
debug: msg="{{ lookup('file','test.json') | from_json | json_query(query) }}"
Run Code Online (Sandbox Code Playgroud)
再次,您在此处手动转换JSON字符串.所以json_query得到dict作为输入.
4.
debug: msg="{{ lookup('file','test.json') | json_query(query) }}"
Run Code Online (Sandbox Code Playgroud)
在这种情况下,您将JSON-string(不是dict)作为输入json_query过滤.由于一切都发生在一个jinja2表达式中,Ansible不会尝试转换其间的任何内容.
您也可以通过这种方式获得带有变量的空字符串结果:
- set_fact:
from_lookup_force_string: "{{ lookup('file','test.json') | string }}"
Run Code Online (Sandbox Code Playgroud)
在这种情况下from_lookup_force_string,Ansible tempating引擎不会转换,并json_query会给你空响应.
| 归档时间: |
|
| 查看次数: |
12133 次 |
| 最近记录: |