перебор переменных в Ansible

#linux #api #rest #ansible #ansible-2.x

#linux #API #остальное #ansible #ansible-2.x

Вопрос:

Я пытаюсь получить несколько URL-адресов работоспособности Spring и распечатать результаты. Когда я запускаю этот сборник с одним единственным URL-адресом, я могу распечатать data.json.status, чтобы получить выходные данные запроса uri.

 # ansible --version
ansible 2.9.7
  config file = /etc/ansible/ansible.cfg
  configured module search path = [u'/root/.ansible/plugins/modules', u'/usr/share/ansible/plugins/modules']
  ansible python module location = /usr/lib/python2.7/site-packages/ansible
  executable location = /usr/bin/ansible
  python version = 2.7.5 (default, Apr  2 2020, 13:16:51) [GCC 4.8.5 20150623 (Red Hat 4.8.5-39)]
 
 ---
- hosts: localhost
  ignore_errors: true
  tasks:
    - name: check health
      uri:
        url: <REDACTED>
        method: GET
        validate_certs: no
        return_content: yes
        status_code: 200
        body_format: json
      register: data

    - name: print result
      debug: 
        msg: "{{ data.json.status }}"
 
 # ansible-playbook 1healthcheck.yml                                                                                                                                                                                   

PLAY [localhost] *****************************************************************************************************************************************************************************************************************************

TASK [Gathering Facts] ***********************************************************************************************************************************************************************************************************************
ok: [localhost]

TASK [check health] **************************************************************************************************************************************************************************************************************************
ok: [localhost]

TASK [print result] **************************************************************************************************************************************************************************************************************************
ok: [localhost] => {
    "msg": "UP"
}

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

Проблема в том, что я добавляю цикл для обработки нескольких URL-адресов.

 ---
- hosts: localhost
  ignore_errors: true
  vars_files:
    - ./healthchecks.yml
  tasks:
    - name: check health
      uri:
        url: api
        method: GET
        validate_certs: no
        return_content: yes
        status_code: 200
        body_format: json
      register: data
      with_items:
        - "{{ urls }}"

    - name: Print json status for each item
      debug: 
        msg: "{{ item.json.status }}"
      with_items: "{{ data }}"
 
 # ansible-playbook healthcheck.yml 

PLAY [localhost] *****************************************************************************************************************************************************************************************************************************

TASK [Gathering Facts] ***********************************************************************************************************************************************************************************************************************
ok: [localhost]

TASK [check health] **************************************************************************************************************************************************************************************************************************
failed: [localhost] (item=<REDACTED>) => {"ansible_loop_var": "item", "changed": false, "item": "<REDACTED>", "msg": "unknown url type: api", "status": -1, "url": "api"}
...ignoring

TASK [Print json status for each item] *******************************************************************************************************************************************************************************************************
fatal: [localhost]: FAILED! => {"msg": "The task includes an option with an undefined variable. The error was: 'ansible.utils.unsafe_proxy.AnsibleUnsafeBytes object' has no attribute 'json'nnThe error appears to be in '/root/healthcheck.yml': line 19, column 7, but maynbe elsewhere in the file depending on the exact syntax problem.nnThe offending line appears to be:nnn    - name: Print json status for each itemn      ^ heren"}
...ignoring

PLAY RECAP ***********************************************************************************************************************************************************************************************************************************
localhost                  : ok=3    changed=0    unreachable=0    failed=0    skipped=0    rescued=0    ignored=2   
 

Я думаю, что мне просто нужно разобраться со структурами данных, используемыми Ansible. Является {{{ data }} ли переменная, когда я использую цикл, просто сохранением списка? Если да, то как я могу распечатать только .json.status каждый элемент в списке?

Ответ №1:

Когда вы выполняете цикл для задач, результаты попадают в ключ словаря, results как указано в документации.

Таким образом, ваша отладка должна быть циклом на data.results :

 - name: Print json status for each item
  debug: 
    msg: "{{ item.json.status }}"
  loop: "{{ data.results }}"
 

Примечание: вы можете debug использовать целую структуру данных, такую как словарь или список, чтобы выяснить, в чем заключается ваша проблема.
Это можно сделать двумя способами:

  • либо
     - debug:
         var: data
     
  • или
     - debug:
         msg: "{{ data }}"