ansible - JMESpath 表达式按属性过滤对象并返回具有此属性集的对象名称列表
问题描述
是否可以编写 JMESPath 表达式以返回设置了特定子属性值的对象名称列表?在下面的示例中,我想获取fileexists.stat.exists设置为 true 的所有主机名的列表。
我的目标是使用 Ansible hostvars 结构来获取存在特定文件的所有主机的列表。
{
"hostvars": {
"oclab1n01.example.org": {
"fileexists": {
"changed": false,
"failed": false,
"stat": {
"exists": false
}
}
},
"oclab1n02.example.org": {
"fileexists": {
"changed": false,
"failed": false,
"stat": {
"exists": true
}
}
},
"oclab1n03.example.org": {
"fileexists": {
"changed": false,
"failed": false,
"stat": {
"exists": true
}
}
}
} }
在这个例子中,我想得到以下输出
["oclab1n02.example.org", "oclab1n03.example.org"]
解决方案
简答(TL;DR)
是的,这是可能的,但是非常麻烦,因为至少在使用 JMESpath 方面,对于这种通用查询,源数据集的标准化很差。
语境
- jmespath 查询语言
- 查询深度嵌套对象的对象属性
问题
- 如何使用过滤器表达式构造 jmespath 查询
- 目标是过滤具有任意嵌套对象属性的对象
解决方案
- 这个可以用jmespath来完成,但是操作会比较麻烦
- 一个有问题的问题:对于这种 jmespath 查询,源数据集的标准化很差
- 为了构造 jmespath 查询,我们必须假设所有主对象键在创建查询之前都是已知的
- 在这个具体的例子中,我们必须在构造 jmespath 查询之前知道只有三个主机名......如果我们想要灵活地指定任意数量的主机名,这不是一个有利的情况
例子
以下(太大)jmespath 查询...
[
{
"hostname": `oclab1n01.example.org`
,"fileexists_stat_exists": @.hostvars."oclab1n01.example.org".fileexists.stat.exists
}
,{
"hostname": `oclab1n02.example.org`
,"fileexists_stat_exists": @.hostvars."oclab1n02.example.org".fileexists.stat.exists
}
,{
"hostname": `oclab1n03.example.org`
,"fileexists_stat_exists": @.hostvars."oclab1n02.example.org".fileexists.stat.exists
}
]|[? @.fileexists_stat_exists == `true`]|[*].hostname
返回以下期望的结果
[
"oclab1n02.example.org",
"oclab1n03.example.org"
]
陷阱
- 这个用例的一个主要缺陷是源数据集对于这种查询的标准化很差
- 更扁平的数据结构更容易查询
- 因此,如果可能,更好的方法是在对源数据集运行 jmespath 查询之前将其展平
具有不同原始数据集的替代示例
如果将原始数据组织为对象列表,而不是对象中的一组嵌套对象,则搜索、排序和过滤列表会更容易,而无需事先知道涉及多少主机名条目。
{"hostvars": [
{"hostname":"oclab1n01.example.org"
,"fileexists": true
,"filechanged": false
,"filefailed": false
,"filestat_exists": false
,"we_can_even_still_deeply_nest":{"however":
{"im_only_doing":"it here","to":"prove a point"}
}
}
,{"hostname":"oclab1n02.example.org"
,"fileexists": true
,"filechanged": false
,"filefailed": false
,"filestat_exists": true
}
,{"hostname":"oclab1n03.example.org"
,"fileexists": true
,"filechanged": false
,"filefailed": false
,"filestat_exists": true
}
]
}
现在可以轻松查询上述重新归一化的数据集
hostvars|[? @.filestat_exists == `true`]|[*].hostname
推荐阅读
- c# - WPF 使用服务参考,但我无法获得授权的服务客户端
- jquery - Laravel - 如何对多个日期使用验证
- c++ - 如何启用 std::experimental::atomic_shared_pointer
- python - 尝试使用python控制游戏
- laravel - 未找到 Laravel 5.8 类“表单”
- c# - 用于存储长类型的 C# 快捷方式?
- gridview - 从 javascript 或 jquery 中清除 gridview 数据
- javascript - Chrome扩展中的VueJS多个页面
- c# - DM Join 消息在 Discord C# Bot 中不起作用
- asp.net-core-mvc - User.Identity.IsAuthenticated = false 登录成功后使用 web api mvc core 3.0