Как отфильтровать подэлементы этих данных JSON с помощью JMESPath

Я использую Ansible для создания пользователей в нескольких средах. Я пытаюсь объединить свою пользовательскую переменную, содержащую все данные, необходимые для создания новых пользователей unix, в глобально разделяемую переменную. Для этого я планировал использовать подэлементы, чтобы контролировать, какие пользователи создаются на каких хостах и ​​т. Д.

Однако я изо всех сил пытаюсь понять, как отфильтровать эти данные, чтобы получить правильный набор учетных данных для текущего хоста.

Мне нужно отфильтровать ключ «среды» только до элемента со значением «имя», которое я ищу, но сохранить в результате ключи родительского объекта.

Что у меня есть / что я хочу:

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"
        }
      ]
    }
  ]
}

Больше информации:

Мне удалось приблизиться с помощью этого запроса, но я не знаю, как еще больше сузить результат, чтобы все ключи в каждом объекте «пользователь» остались, но отфильтровали «среды» подэлементов до тех, которые соответствуют мой запрос.

Запрос 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

person Ryan Fisher    schedule 12.01.2018    source источник


Ответы (1)


Что ж, я нашел решение, которое будет работать:

- 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 + "']}") }}

Было бы лучше, если бы я мог каким-то образом включить все ключи элемента «пользователи», не вызывая их явно (имя, токен, unix ...), чтобы запрос не изменился, если я добавлю к этому элементу больше полей. . Но я не знаю, возможно ли это.

Результат запроса:

[
  {
    "name": "user1",
    "token": "token",
    "unix": "unixstring",
    "mysql": "mysqlstring",
    "environments": [
      {
        "name": "env_one",
        "key": "keystring",
        "user_groups": [
          "one",
          "two"
        ],
        "host_groups": "all"
      }
    ]
  }
]
person Ryan Fisher    schedule 12.01.2018