【发布时间】:2019-07-17 07:30:32
【问题描述】:
我正在尝试从 aws ec2 describe-security-groups 输出中提取一些数据,寻找具有以值开头的描述(即 Temp-JDoe ...)的入口规则,使用过滤器来限制结果返回。我得到了我想要的结果,但是在一个带有嵌入式数组的深度嵌套数组中。我想将第一级的所有值与嵌套级别的值结合起来,并用“:”连接,这样我就可以遍历生成的多行字符串,创建一个 aws ec2 revoke-security-group-ingress命令删除这些规则。
我以为我已经煞费苦心地解决了一个复杂的 JMESPath 查询的每个部分,其中每个部分独立工作,但是当结合起来时,我遇到了一个我无法弄清楚的错误。
我目前还有两个过滤器,当第二个数组级别的匹配集为空时,这似乎是消除第一级数组值所必需的,这看起来很复杂,我想知道是否有更优雅的方法来获得相同的结果.
我们的目标是创建一对 bash 脚本,当云管理员必须在未知位置工作时,它们可以运行以快速添加和删除临时安全组规则到堡垒主机安全组。我认为这可能是其他人会遇到的问题。在创建时,我们要先清除所有具有“Temp-JDoe *”描述的规则,然后创建所需的具有“Temp-JDoe (SSH)”描述的包含当前 IP 的集合,因此当工作完成时,规则可以再次通过此查询找到并删除。
大部分灵感都来自这里:https://opensourceconnections.com/blog/2015/07/27/advanced-aws-cli-jmespath-query/
我在这里发现了一个类似的问题:JMESPath - Joining items in a nested array,但由于我使用了过滤器,这不是一个很好的匹配。
这个语句返回我想要的数据。显示 json 输出格式以显示我要折叠和加入的结构:
prefix=Temp
username=JDoe
aws ec2 describe-security-groups --group-id $sg \
--query 'SecurityGroups[].IpPermissions[?not_null(IpRanges[?Description!=`null`]|[?starts_with(Description, `'$prefix-$username'`) == `true`])].[IpProtocol,FromPort,ToPort,IpRanges[?Description!=`null`]|[?starts_with(Description, `'$prefix-$username'`) == `true`].[CidrIp,Description]]' \
--profile $profile --region $region --output json
有了这个原始输出:
[
[
[
"tcp",
22,
22,
[
[
"77.111.222.223/32",
"Temp-JDoe (SSH)"
]
]
],
[
"udp",
1194,
1194,
[
[
"77.111.222.223/32",
"Temp-JDoe (VPN-UDP)"
]
]
]
]
]
我需要进入这个最终形式:
udp:1194:1194:70.185.154.223/32:Temp-JDoe (VPN-UDP)
tcp:22:22:70.185.154.223/32:Temp-JDoe (SSH)
虽然这个带有连接的语句在没有过滤器的情况下可以限制数组数据(在外层获取所有数据,在内层获取第一个):
aws ec2 describe-security-groups --group-id $sg \
--query 'SecurityGroups[].IpPermissions[].[join(`:`,[IpProtocol,to_string(FromPort),to_string(ToPort),IpRanges[0].join(`:`,[CidrIp,Description])])]' \
--profile $profile --region $region --output text
示例输出(错误的记录,正确的格式):
[
[
"tcp:22:22:111.55.111.123/32:Home-FName (SSH)"
],
[
"udp:1194:1194:111.55.111.123/32:Home-FName (VPN-UDP)"
],
[
"tcp:943:943:70.185.154.223/32:Home-JDoe (Console)"
],
[
"tcp:443:443:111.55.111.123/32:Home-FName (VPN-TCP)"
],
[
"icmp:-1:-1:192.66.55.0/24:Office-NewYork (ICMP)"
]
]
一旦我结合了两个工作子集来过滤我想要的数据,然后加入它,它就不起作用了,第二个加入有问题。这是合并后的声明:
aws ec2 describe-security-groups --group-id $sg \
--query 'SecurityGroups[].IpPermissions[?not_null(IpRanges[?Description!=`null`]|[?starts_with(Description, `'$prefix-$username'`) == `true`])].[join(`:`,[IpProtocol,to_string(FromPort),to_string(ToPort),IpRanges[?Description!=`null`]|[?starts_with(Description, `'$prefix-$username'`) == `true`].join(`:`,[CidrIp,Description])])]' \
--profile $profile --region $region --output text
还有错误信息:
In function join(), invalid type for value: ['70.185.154.223/32:Temp-JDoe (VPN-UDP)'], expected one of: ['array-string'], received: "list"
【问题讨论】:
标签: jmespath