отфильтровать текст из сложного объекта json, созданного с помощью json_qry - PullRequest
0 голосов
/ 19 июня 2019

В частности, мне нужна «строка» идентификаторов учетных записей, отсутствующих в списке, который я даю задаче на сервере в своем инвентаре.

Я запускаю модуль getent в задаче и регистрирую результат, которыйкажется полным JSON-объектом с данными, которые я хочу получить в виде кета с именем "item", зарытого в массиве объектов, называемых "results", который сам является объектом "result".

Я пытаюсьпроанализируйте объект «result» для любого ключа с именем «failed», который имеет значение true, и извлеките значение ключа этого объекта для «item», который является идентификатором учетной записи.

Мне нужно хвастаться, чтобы преодолеть мою нехваткупонимания.

спасибо!

Ничего из того, что я пробовал, не работает.Я не уверен, является ли это моим синтаксисом или нехваткой понимания, как анализировать или «интерпретировать» объект JSON, хранящийся в «результате»

Я думаю, что мой синтаксис для переменной qry запрашивает любой элемент массива вresults (массив объектов), у которого есть ключ с именем «failed» со значением true, и если совпадение найдено, вернуть значение его ключа «item».Я знаю, если это сработает, он вернет список.мне нужна строка, но я не смог получить никакого результата, кроме пустого списка [].

Я пробовал много вариантов, но результат всегда пуст.

 qry: "result.results[?failed == true].item"
 qry: "results[?failed == true].item"
 qry: "[?failed == true].item"

Вот объект JSON, возвращаемый ansible "debug: var = result"

TASK [debug] *******************************************************************
ok: [x.y.z.abc.com] => {
    "result": {
        "changed": false,
        "failed": true,
        "msg": "All items completed",
        "results": [
            {
                "_ansible_item_result": true,
                "_ansible_no_log": false,
                "_ansible_parsed": true,
                "changed": false,
                "failed": true,
                "invocation": {
                    "module_args": {
                        "database": "passwd",
                        "fail_key": true,
                        "key": "abc123",
                        "split": null
                    }
                },
                "item": "abc123",
                "msg": "One or more supplied key could not be found in the database."
            },
            {
                "_ansible_item_result": true,
                "_ansible_no_log": false,
                "_ansible_parsed": true,
                "changed": false,
                "failed": true,
                "invocation": {
                    "module_args": {
                        "database": "passwd",
                        "fail_key": true,
                        "key": "pubsub",
                        "split": null
                    }
                },
                "item": "pubsub",
                "msg": "One or more supplied key could not be found in the database."
            }
        ]
    }
}

Вот раздел кода playbook:

- name: "Account checks"
    ignore_errors: True
    with_items:
        - abc123
        - pubsub
    getent: database=passwd key={{ item }}
    register: result
  - debug: var=result
  - debug: msg="Account id is {{ result | json_query(qry) }} "
    vars:
        qry: "result.results[?failed == true].item"

Вот результат выводамой вызов json_qry:

TASK [debug] *******************************************************************
ok: [xyz.abc.com] => {}

MSG:

Account id is

Что я хочу, это что-то вроде:

"Идентификатор учетной записи abc123, pubsub"

1 Ответ

0 голосов
/ 20 июня 2019

result - это верхняя конструкция, которую вы передаете json_query, поэтому она не существует в качестве верхнего элемента, когда начинает обрабатывать данные.Более того, проверка поля без сравнения позволит убедиться, что поле существует и что его значение не является ложным.

Поэтому правильный запрос для получения вашей информации: results[?failed].item

Как выуже догадался, что вернет список item строк для всех неудачных результатов.Вам просто нужно перебрать этот список, чтобы получить отдельные значения.

Ниже примера книги.Я изменил одно значение failed на false в ваших данных выборки для иллюстрации.

---
- name: Parse result list with json_query
  hosts: localhost
  gather_facts: false

  vars:
    "result": {
      "changed": false,
      "failed": true,
      "msg": "All items completed",
      "results": [
      {
        "_ansible_item_result": true,
        "_ansible_no_log": false,
        "_ansible_parsed": true,
        "changed": false,
        "failed": true,
        "invocation": {
          "module_args": {
            "database": "passwd",
            "fail_key": true,
            "key": "abc123",
            "split": null
          }
        },
        "item": "abc123",
        "msg": "One or more supplied key could not be found in the database."
      },
      {
        "_ansible_item_result": true,
        "_ansible_no_log": false,
        "_ansible_parsed": true,
        "changed": false,
        "failed": false,
        "invocation": {
          "module_args": {
            "database": "passwd",
            "fail_key": true,
            "key": "pubsub",
            "split": null
          }
        },
        "item": "pubsub",
        "msg": "One or more supplied key could not be found in the database."
      }
      ]
    }

  tasks:

    - name: Get item value of failed results
      vars:
        query: results[?failed].item
      debug:
        msg: "The user id is {{ item }}"
      loop: "{{ result | json_query(query) }}"

, что дает:

PLAY [Parse result list with json_query] PLAY RECAP **********************************

TASK [Get item value of failed results] PLAY RECAP ***********************************
ok: [localhost] => (item=abc123) => {
    "msg": "The user id is abc123"
}


PLAY RECAP ***********************************
localhost                  : ok=1    changed=0    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0
...