Проверить данную строку во вложенной структуре данных с помощью ansible playbook - PullRequest
2 голосов
/ 03 августа 2020

Данная строка 'vivek' для поиска в вложенной структуре данных ниже, и если строка 'vivek' присутствует, то я хочу, чтобы внешняя 'id' использовала ansible playbook:

{'results': [{'details': [{'id': '1', 'name': 'vivek'},
                          {'id': '2', 'name': 'ashwin'}],
              'id': '100'},
             {'details': [], 'id': '101'},
             {'details': [{'id': '1', 'name': 'vivek'},
                          {'id': '2', 'name': 'ashwin'}],
              'id': '102'}]}

Требуется вывод:

skipping: [localhost] => (item=['101'])
ok: [localhost] => (item=['100') => {
    "msg": "100"
}
ok: [localhost] => (item=['102') => {
    "msg": "102"
}

Пробовал:

- name: List IDs which contains 'vivek'
  hosts: localhost
  connection: local
  vars:
    results:
      - id: '100'
        details:
          - id: '1'
            name: 'vivek'
          - id: '2'
            name: 'ashwin'
      - id: '101'
        details:
          -
      - id: '102'
        details:
          - id: '1'
            name: 'vivek'
          - id: '2'
            name: 'ashwin'
  tasks:

    - debug:
        var: results

    - set_fact:
        all_details: "{{ results | map(attribute='details') | list }}"

    - debug:
        var: all_details

#    - name: List of IDs, contains 'vivek'
#      debug:
#        msg: "{{ item.id }}"
#      loop: "{{ all_details }}"
#      when: 'vivek' in items.names

Ответы [ 2 ]

2 голосов
/ 03 августа 2020

Использование фильтра json_query с results var из определения переменных playbook. id, используемые в переменных playbook, и ваш требуемый выход отличаются.

- debug:
    msg: "{{ results | json_query(query) }}"
  vars:
    query: "[?details[?name=='vivek']].id"

дает,

ok: [localhost] => {
    "msg": [
        "100",
        "103"
    ]
}
1 голос
/ 03 августа 2020

Если вы действительно не хотите достичь этого с помощью добавления jmespath и json_query, вы можете добиться этого с помощью фильтра subelements .

Учитывая сценарий:

- hosts: all
  gather_facts: no  
  vars:
    results:
      - id: '100'
        details:
          - id: '1'
            name: 'vivek'
          - id: '2'
            name: 'ashwin'
      - id: '101'
        details:
          -
      - id: '102'
        details:
          - id: '1'
            name: 'vivek'
          - id: '2'
            name: 'ashwin'  
        
  tasks:
    - debug:
        msg: "{{ item.0.id }}"
      loop: "{{ results | subelements('details') }}"
      loop_control:
        label: "{{ item.1.name | default('None') }}"
      when: 
        - item.1.name is defined 
        - "'vivek' == item.1.name"

Это дает результат:

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

TASK [debug] ********************************************************************************************************************
ok: [localhost] => (item=vivek) => {
    "msg": "100"
}
skipping: [localhost] => (item=ashwin) 
skipping: [localhost] => (item=None) 
ok: [localhost] => (item=vivek) => {
    "msg": "102"
}
skipping: [localhost] => (item=ashwin) 

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