如何使用 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"
      }
    ]
  }
]