gpt4 book ai didi

ansible - JMESpath 表达式按属性过滤对象并返回具有此属性集的对象名称列表

转载 作者:行者123 更新时间:2023-12-05 07:34:16 24 4
gpt4 key购买 nike

是否可以编写 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"]

最佳答案

简答(长话短说)

是的,这是可能的,但它非常麻烦,因为至少在使用 JMESpath 方面,源数据集对于这种通用查询规范化不佳。 p>

上下文

  • 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

关于ansible - JMESpath 表达式按属性过滤对象并返回具有此属性集的对象名称列表,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50249516/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com