如何使用 JMESPath 过滤此 JSON 数据的子元素
How do I filter the subelements of this JSON data with JMESPath
我正在使用 Ansible 跨多个环境创建用户。我正在尝试将包含创建新 unix 用户所需的所有数据的用户 var 合并到一个全局共享的 var 中。为此,我计划使用子元素来控制在哪些主机上创建哪些用户等。
但是,我正在努力弄清楚如何过滤这些数据,以便我可以为当前主机设置正确的凭据。
我需要将 "environments" 键过滤到仅具有我要查找的 "name" 值的元素,但在结果中保留父对象的键。
我have/what想要什么:
JSON:
{
"users": [
{
"name": "user1",
"token": "token",
"unix": "unixstring",
"mysql": "mysqlstring",
"environments": [
{
"name": "env_one",
"key": "keystring",
"user_groups": [
"one",
"two"
],
"host_groups": "all"
},
{
"name": "env_two",
"key": "keystring",
"user_groups": [
"three",
"four"
],
"host_groups": "all"
}
]
},
{
"name": "user2",
"token": "token",
"unix": "unixstring",
"mysql": "mysqlstring",
"environments": [
{
"name": "env_three",
"key": "keystring",
"user_groups": [
"one",
"two"
],
"host_groups": "all"
}
]
}
]
}
我想要的:
{
"users": [
{
"name": "user1",
"token": "token",
"unix": "unixstring",
"mysql": "mysqlstring",
"environments": [
{
"name": "env_one",
"key": "keystring",
"user_groups": [
"one",
"two"
],
"host_groups": "all"
}
]
}
]
}
更多信息:
我可以使用这个查询来关闭,但我不知道如何进一步缩小结果范围,以便每个 "user" 对象中的所有键都保留下来,但过滤掉子元素"environments" 匹配我的查询。
JMESPath 查询:users[?environments[?name=='env_one']]
输出:
{
"users": [
{
"name": "user1",
"token": "token",
"unix": "unixstring",
"mysql": "mysqlstring",
"environments": [
{
"name": "env_one",
"key": "keystring",
"user_groups": [
"one",
"two"
],
"host_groups": "all"
},
{
"name": "env_two",
"key": "keystring",
"user_groups": [
"three",
"four"
],
"host_groups": "all"
}
]
}
]
}
如果有用,这是 YAML 中的原始数据集:
YAML:
---
users:
- name: user1
token: token
unix: unixstring
mysql: mysqlstring
environments:
- name: env_one
key: keystring
user_groups:
- one
- two
host_groups: all
- name: env_two
key: keystring
user_groups:
- three
- four
host_groups: all
- name: user2
toke n: token
unix: unixstring
mysql: mysqlstring
environments:
- name: env_three
key: keystring
user_groups:
- one
- two
host_groups: all
好吧,我找到了一个可行的解决方案:
- set_fact:
users: >
{{ users
| json_query("[?environments[?name=='" + ansible_environment + "']].{
name: name,
yubikey_public_id: yubikey_public_id,
unix_initial_password: unix_initial_password,
mysql_initial_password: mysql_initial_password,
environments: environments[?name=='" + ansible_environment + "']}") }}
如果我能以某种方式包含所有 "users" 元素的键而不显式调用它们(名称、令牌、unix...),这样查询就不必更改,那就更好了我向该元素添加了更多字段。但是不知道可不可以。
查询结果:
[
{
"name": "user1",
"token": "token",
"unix": "unixstring",
"mysql": "mysqlstring",
"environments": [
{
"name": "env_one",
"key": "keystring",
"user_groups": [
"one",
"two"
],
"host_groups": "all"
}
]
}
]
我正在使用 Ansible 跨多个环境创建用户。我正在尝试将包含创建新 unix 用户所需的所有数据的用户 var 合并到一个全局共享的 var 中。为此,我计划使用子元素来控制在哪些主机上创建哪些用户等。
但是,我正在努力弄清楚如何过滤这些数据,以便我可以为当前主机设置正确的凭据。
我需要将 "environments" 键过滤到仅具有我要查找的 "name" 值的元素,但在结果中保留父对象的键。
我have/what想要什么:
JSON:
{
"users": [
{
"name": "user1",
"token": "token",
"unix": "unixstring",
"mysql": "mysqlstring",
"environments": [
{
"name": "env_one",
"key": "keystring",
"user_groups": [
"one",
"two"
],
"host_groups": "all"
},
{
"name": "env_two",
"key": "keystring",
"user_groups": [
"three",
"four"
],
"host_groups": "all"
}
]
},
{
"name": "user2",
"token": "token",
"unix": "unixstring",
"mysql": "mysqlstring",
"environments": [
{
"name": "env_three",
"key": "keystring",
"user_groups": [
"one",
"two"
],
"host_groups": "all"
}
]
}
]
}
我想要的:
{
"users": [
{
"name": "user1",
"token": "token",
"unix": "unixstring",
"mysql": "mysqlstring",
"environments": [
{
"name": "env_one",
"key": "keystring",
"user_groups": [
"one",
"two"
],
"host_groups": "all"
}
]
}
]
}
更多信息:
我可以使用这个查询来关闭,但我不知道如何进一步缩小结果范围,以便每个 "user" 对象中的所有键都保留下来,但过滤掉子元素"environments" 匹配我的查询。
JMESPath 查询:users[?environments[?name=='env_one']]
输出:
{
"users": [
{
"name": "user1",
"token": "token",
"unix": "unixstring",
"mysql": "mysqlstring",
"environments": [
{
"name": "env_one",
"key": "keystring",
"user_groups": [
"one",
"two"
],
"host_groups": "all"
},
{
"name": "env_two",
"key": "keystring",
"user_groups": [
"three",
"four"
],
"host_groups": "all"
}
]
}
]
}
如果有用,这是 YAML 中的原始数据集:
YAML:
---
users:
- name: user1
token: token
unix: unixstring
mysql: mysqlstring
environments:
- name: env_one
key: keystring
user_groups:
- one
- two
host_groups: all
- name: env_two
key: keystring
user_groups:
- three
- four
host_groups: all
- name: user2
toke n: token
unix: unixstring
mysql: mysqlstring
environments:
- name: env_three
key: keystring
user_groups:
- one
- two
host_groups: all
好吧,我找到了一个可行的解决方案:
- set_fact:
users: >
{{ users
| json_query("[?environments[?name=='" + ansible_environment + "']].{
name: name,
yubikey_public_id: yubikey_public_id,
unix_initial_password: unix_initial_password,
mysql_initial_password: mysql_initial_password,
environments: environments[?name=='" + ansible_environment + "']}") }}
如果我能以某种方式包含所有 "users" 元素的键而不显式调用它们(名称、令牌、unix...),这样查询就不必更改,那就更好了我向该元素添加了更多字段。但是不知道可不可以。
查询结果:
[
{
"name": "user1",
"token": "token",
"unix": "unixstring",
"mysql": "mysqlstring",
"environments": [
{
"name": "env_one",
"key": "keystring",
"user_groups": [
"one",
"two"
],
"host_groups": "all"
}
]
}
]