在 JMESPath 过滤器表达式中引用父元素

Reference Parent Element in JMESPath Filter Expression

我有以下 JMESPath 查询

query="Reservations[].Instances[].{ \
    InstanceId: InstanceId, \
    RootDeviceVolumeId: BlockDeviceMappings[?DeviceName==\`/dev/sda1\`] \
       | [].Ebs.VolumeId | [0], \
    RootDeviceName: RootDeviceName \
}"

aws ec2 describe-instances --query $query

这样的输出

+------------+------------------+----------------------+
| InstanceId | RootDeviceName   | RootDeviceVolumeId   |
+------------+------------------+----------------------+
|  i-12345678|  /dev/sda1       |  vol-abcdef12        |
|  i-98765432|  /dev/sda1       |  vol-ef123456        |
|  i-23456789|  /dev/sda1       |  vol-fedcba09        |
|  i-aabbccdd|  /dev/xvda       |  None                |
+------------+------------------+----------------------+

我想找到一种从 BlockDeviceMappings 过滤器表达式中引用 RootDeviceName 的方法,而不是对 /dev/sda1 设备名称进行硬编码,因为有时它是 /dev/xvda 例如。但是,我找不到在过滤器表达式中引用父元素的方法。

另一种选择是将 RootDeviceNameInstanceId 映射到所有设备的投影上,然后将其通过管道传递给过滤器表达式,但语法似乎不支持包含父元素在预测中。

我是不是遗漏了什么,或者这仅仅是 JMESPath 语法的限制?

我们需要有某种机制允许您绑定作用域,这在当前是不可能的……但是。我对添加这个很感兴趣。现在您必须使用替代工具。

如果您愿意使用 python 代码向您的 JMESPath 添加自定义函数,可以使用一种肮脏且丑陋的方法来执行类似的操作。它确实违反了 "functions should have no side effects" 规则。这是要点:https://gist.github.com/martinvirtel/366235401cf7fbec503d53eb44109f25

要点中的 fetchstore.py 文件向 JMESPath 添加了获取和存储功能。请参阅下面的测试或示例以了解其工作原理。以下是有关如何向使用 JMESPath 的 Python 项目添加函数的指南:https://pypi.python.org/pypi/jmespath#custom-functions.

输入:

 { "name" : "parent name",
    "data" : [
        { "x" : 1, "y" : 2 },
        { "x" : 3, "y" : 2 }
        ]
    }

JMESPath 表达式:

{ 
  name: store(name,'parent_name_attribute'), 
  data: data[][ fetch('parent_name_attribute'),x, y] 
}

结果:

{
 "name": "parent name",
 "data": [
           [ "parent name", 1, 2 ],
           [ "parent name", 3, 2 ]
         ]
}