проблемы с вложенным json_query - PullRequest
0 голосов
/ 10 мая 2019

У меня следующая структура json.

    "results": [
        {
            "ltm_pools": [
                {
                    "members": [
                        {
                            "full_path": "/Common/10.49.128.185:8080",
                        },
                        {
                            "full_path": "/Common/10.49.128.186:8080",
                        }

                    "name": "Staging-1-stresslab",
                },
                {
                    "members": [
                        {
                            "full_path": "/Common/10.49.128.187:0",
                        },
                        {
                            "full_path": "/Common/10.49.128.188:0",
                        }
                    ],
                    "name": "Staging-2-lab",
                },

Я получаю сообщение об ошибке при попытке сделать что-то подобное

  - debug:
      msg: "{{item[0].host}} --- {{ item[1] }} ---  {{ item[2] }}"
    with_nested:
      - "{{F5_hosts}}"
      - "{{bigip_facts | json_query('[results[0].ltm_pools[*].name]') | flatten }}"
      - "{{bigip_facts | json_query('[results[0].ltm_pools[?name.contains(@,'Staging'].members[::2].full_path]') | flatten }}"

Я не могу заставить работать третий массив.

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

Я надеюсь, что кто-то может помочь мне, я боролся с этим в течение нескольких дней.

Ответы [ 2 ]

0 голосов
/ 11 мая 2019

Из того, что я вижу / читаю / пробовал сам, вы попали в этот баг: https://github.com/ansible/ansible/issues/27299

Это проблема «содержит» функцию JMESPath, поскольку она запускается Ansible, чтобы процитировать: https://github.com/ansible/ansible/issues/27299#issuecomment-331068246

Проблема связана с тем, что Ansible использует собственные типы для строк: AnsibleUnicode и AnsibleUnsafeText. И поскольку библиотека jmespath имеет очень строгую проверку типов, она не может принимать эти типы как строковые литералы.

Существует также предложенный обходной путь, если вы преобразуете переменную в json и обратно, там строки имеют правильный тип. Короче говоря, это не работает:

"{{bigip_facts | json_query('results[0].ltm_pools[?name.contains(@,`Staging`)==`true`].members[::2].full_path') }}"

но это делает:

"{{bigip_facts | to_json | from_json | json_query('results[0].ltm_pools[?name.contains(@,`Staging`)==`true`].members[::2].full_path') }}"

Мне удалось запустить такой код:

- hosts: all
  gather_facts: no
  tasks:
    - set_fact:
        bigip_facts: 
          results: 
            - ltm_pools:
                - members: 
                    - full_path: "/Common/10.49.128.185:8080"
                    - full_path: "/Common/10.49.128.186:8080"
                  name: "Staging-1-stresslab"
                - members: 
                    - full_path: "/Common/10.49.128.187:0"
                    - full_path: "/Common/10.49.128.188:0"
                  name: "Staging-2-stresslab"

    - name: "Debug ltm-pools"
      debug:
        msg: "{{ item }}"
      with_items:
        - "{{bigip_facts | to_json | from_json | json_query('results[0].ltm_pools[?name.contains(@,`Staging`)==`true`].members[::2].full_path') }}"

И все работает так, как вы хотели:

PLAY [all] *****************************************************************************************

TASK [set_fact] ************************************************************************************
ok: [localhost]

TASK [Debug ltm-pools] *****************************************************************************
ok: [localhost] => (item=[u'/Common/10.49.128.185:8080']) => {
    "msg": [
        "/Common/10.49.128.185:8080"
    ]
}
ok: [localhost] => (item=[u'/Common/10.49.128.187:0']) => {
    "msg": [
        "/Common/10.49.128.187:0"
    ]
}

PLAY RECAP *****************************************************************************************
localhost                  : ok=2    changed=0    unreachable=0    failed=0   
0 голосов
/ 10 мая 2019

Я сделал некоторые изменения, но все равно не повезло

- name: "Debug ltm-pools"
  vars:
    query: "results[0].ltm_pools[?name.contains(@,'Staging') == 'true'].members[::2].full_path"
  debug:
    msg: "{{item[0].host}} --- {{ item[1] }} --  {{ item[2] }}"
  with_nested:
    - "{{F5_hosts}}"
    - "{{bigip_facts | json_query('[results[0].ltm_pools[*].name]') | flatten }}"
    - "{{bigip_facts | json_query(query) | flatten }}"

Error

fatal: [dtvsbepsta1avrbnc2-mgt]: FAILED! => {"msg": "JMESPathError in json_query filter plugin:\nIn function contains(), invalid type for value: MUM1_pool, expected one of: ['array', 'string'], received: \"unknown\""}
...