Ansible:使用 json_query 在任意深度寻找具有已知值的已知键?
Ansible: Looking for a known key with a known value at an arbitrary depth using json_query?
是否可以使用 json_query
完成这样的事情?经过相当多的搜索(json_query
和 jmespath
都没有找到任何东西)。我能够找到的所有内容都假定 dict/json
的结构是已知的(即搜索密钥的深度是已知的)。
示例 JSON 输入:
{
"changed": false,
"msg": {
"Data": {
"Message": "returned status code doesn't match with the expected success code",
"Status": "Failed",
"StatusCode": 409
},
"Message": "none",
"Status": "Failed",
"StatusCode": 409,
"error": {
"error": {
"@Message.ExtendedInfo": [
{
"Message": "Server is already powered OFF.",
"MessageArgs": [
],
"MessageArgs@odata.count": 0,
"MessageId": "IDRAC.1.6.PSU502",
"RelatedProperties": [
],
"RelatedProperties@odata.count": 0,
"Resolution": "No response action is required.",
"Severity": "Informational"
}
],
"code": "Base.1.0.GeneralError",
"message": "A general error has occurred. See ExtendedInfo for more information"
}
},
"retval": true
}
}
我想检查键 Message 是否存在且值为 Server is already powered OFF. 不假设深度JSON.
的 key/structure
$ ls -1 filter_plugins/*.py
filter_plugins/dict_utils.py
filter_plugins/list_methods.py
下面的任务
vars:
my_key: Message
my_value: Server is already powered OFF
tasks:
- debug:
msg: "{{ item.key }}: {{ item.value is search(my_value)|
ternary(my_value, 'NOT FOUND') }}"
loop: "{{ input|dict_flatten|dict2items }}"
when: item.key.split('.')|list_reverse|first == my_key
给予
"msg": "msg.Data.Message: NOT FOUND"
"msg": "msg.error.error.@Message.ExtendedInfo.0.Message: Server is already powered OFF"
"msg": "msg.Message: NOT FOUND"
详情
过滤示例 dict_flatten 来自下面 dict_utils
vars:
dict4: {
"a":{
"r": 1,
"s": 2,
"t": 3
},
"b":{
"u": 1,
"v": {
"x": 1,
"y": 2,
"z": [ 3, 4, 5 ]
},
"w": 3
}
}
tasks:
- debug:
var: dict4_flatten
vars:
dict4_flatten: "{{ dict4|dict_flatten('.') }}"
给予
"dict4_flatten": {
"a.r": 1,
"a.s": 2,
"a.t": 3,
"b.u": 1,
"b.v.x": 1,
"b.v.y": 2,
"b.v.z.0": 3,
"b.v.z.1": 4,
"b.v.z.2": 5,
"b.w": 3
}
我能够在另一个网站上找到以下答案(感谢 /u/boscopanda!):
- debug:
var: js.msg
when: (js | to_json).find('Server is already powered OFF') != -1
是否可以使用 json_query
完成这样的事情?经过相当多的搜索(json_query
和 jmespath
都没有找到任何东西)。我能够找到的所有内容都假定 dict/json
的结构是已知的(即搜索密钥的深度是已知的)。
示例 JSON 输入:
{
"changed": false,
"msg": {
"Data": {
"Message": "returned status code doesn't match with the expected success code",
"Status": "Failed",
"StatusCode": 409
},
"Message": "none",
"Status": "Failed",
"StatusCode": 409,
"error": {
"error": {
"@Message.ExtendedInfo": [
{
"Message": "Server is already powered OFF.",
"MessageArgs": [
],
"MessageArgs@odata.count": 0,
"MessageId": "IDRAC.1.6.PSU502",
"RelatedProperties": [
],
"RelatedProperties@odata.count": 0,
"Resolution": "No response action is required.",
"Severity": "Informational"
}
],
"code": "Base.1.0.GeneralError",
"message": "A general error has occurred. See ExtendedInfo for more information"
}
},
"retval": true
}
}
我想检查键 Message 是否存在且值为 Server is already powered OFF. 不假设深度JSON.
的 key/structure$ ls -1 filter_plugins/*.py
filter_plugins/dict_utils.py
filter_plugins/list_methods.py
下面的任务
vars:
my_key: Message
my_value: Server is already powered OFF
tasks:
- debug:
msg: "{{ item.key }}: {{ item.value is search(my_value)|
ternary(my_value, 'NOT FOUND') }}"
loop: "{{ input|dict_flatten|dict2items }}"
when: item.key.split('.')|list_reverse|first == my_key
给予
"msg": "msg.Data.Message: NOT FOUND"
"msg": "msg.error.error.@Message.ExtendedInfo.0.Message: Server is already powered OFF"
"msg": "msg.Message: NOT FOUND"
详情
过滤示例 dict_flatten 来自下面 dict_utils
vars:
dict4: {
"a":{
"r": 1,
"s": 2,
"t": 3
},
"b":{
"u": 1,
"v": {
"x": 1,
"y": 2,
"z": [ 3, 4, 5 ]
},
"w": 3
}
}
tasks:
- debug:
var: dict4_flatten
vars:
dict4_flatten: "{{ dict4|dict_flatten('.') }}"
给予
"dict4_flatten": {
"a.r": 1,
"a.s": 2,
"a.t": 3,
"b.u": 1,
"b.v.x": 1,
"b.v.y": 2,
"b.v.z.0": 3,
"b.v.z.1": 4,
"b.v.z.2": 5,
"b.w": 3
}
我能够在另一个网站上找到以下答案(感谢 /u/boscopanda!):
- debug:
var: js.msg
when: (js | to_json).find('Server is already powered OFF') != -1