Назад | Перейти на главную страницу

Ansible: перебрать зарегистрированный вывод в следующей задаче

Ansible версия: ansible 2.6.2 python версия 2.7.5

Я изо всех сил пытаюсь перебрать зарегистрированные IP-адреса из одной задачи в другой, используя with_items, и получить отладочный вывод из доступной книги воспроизведения, которая дает следующее:

Пособие:

- name: Check DVS portgroup from vCenter and allocate IP address from EPG description
  hosts: localhost
  connection: local
  gather_facts: no
  vars:
    nios_provider:
     host: "dns1"
     username: ""
     password: ""

  tasks:
  - name: Find unused IP address from EPG
    local_action: command sh /free.sh "{{ item }}"
    with_items: "DM-SNAP (VLAN-869) in DM AMZ, IP: 11.25.2.0/24 BD: BD-DH-VLAN-869 BD: BD_AZX_NO1, IP: 11.25.3.0/24"
    register: dvs_output

  - name: The IP
    debug: msg={{ dvs_output.results | map(attribute='stdout_lines') | list }}
#    debug: msg={{ dvs_output }}
    register: ip_dns

  - name: return next available IP address for network {{ ip_dns }}
    set_fact:
      ipaddr: "{{ lookup('nios_next_ip', '{{ item }}', num=10, provider=nios_provider) }}"
    with_items: "{{ ip_dns.msg }}"
    ignore_errors: true
    register: lookup

Это результат воспроизведения. Здесь воспроизведение не удается из-за неформатированного ввода из предыдущей зарегистрированной переменной.

    PLAY [Check DVS portgroup from vCenter and allocate IP address from EPG description] ***********************************************************************************************************************

TASK [Find unused IP address from EPG] *********************************************************************************************************************************************************************
changed: [localhost -> localhost] => (item=DM-SNAP (VLAN-869) in DM AMZ, IP: 11.25.2.0/24 BD: BD-DH-VLAN-869 BD: BD_AZX_NO1, IP: 11.25.3.0/24)

TASK [The IP] **********************************************************************************************************************************************************************************************
ok: [localhost] => {
    "msg": [
        [
            "11.25.2.0",
            "11.25.3.0"
        ]
    ]
}

TASK [return next available IP address for network {'msg': [[u'11.25.2.0', u'11.25.3.0']], 'failed': False, 'changed': False}] ***************************************************************************

ok: [localhost] => (item=11.25.2.0)
fatal: [localhost]: FAILED! => {"msg": "Unexpected templating type error occurred on ({{ lookup('nios_next_ip', '{{ item }}', num=10, provider=nios_provider) }}): 'dict' object is not callable"}
...ignoring

TASK [Debug IP] ********************************************************************************************************************************************************************************************
fatal: [localhost]: FAILED! => {"msg": "The task includes an option with an undefined variable. The error was: 'dict object' has no attribute 'ansible_facts'\n\nThe error appears to have been in '/etc/ansible/playbooks/vmware/dev/test_allocate.yml': line 37, column 5, but may\nbe elsewhere in the file depending on the exact syntax problem.\n\nThe offending line appears to be:\n\n\n  - name: Debug IP\n    ^ here\n"}

PLAY RECAP *************************************************************************************************************************************************************************************************
localhost                  : ok=3    changed=1    unreachable=0    failed=1

Как я могу лучше заставить цикл работать внутри второй задачи, когда значение IP некорректно загружается на {{item}} и, таким образом, зацикливается?

Вы регистрируете переменную в первой задаче. Эта переменная содержит IP-адреса, затем вы фильтруете эту переменную, чтобы она была списком, и выводите ее как отладочную, и регистрируете этот вывод отладки, а затем вы пытаетесь перебрать вывод отладки. Это не хорошо.

Почему бы вам не перебрать фильтр, который вы выводите при отладке? Так что используйте:

- name: return next available IP address for network {{ ip_dns }}
  set_fact:
    ipaddr: "{{ lookup('nios_next_ip', '{{ item }}', num=10, provider=nios_provider) }}"
  with_items: "{{ dvs_output.results | map(attribute='stdout_lines') | list }}"

Также - следующая проблема - вы перебираете список и устанавливаете переменную со значением. Итак, после этой задачи остается одна переменная ipaddr который содержит последний IP. Если вы хотите что-то сделать со всеми IP-адресами, вам следует использовать:

- name: return next available IP address for network {{ ip_dns }}
  include_tasks: loop_over_an_ip.yml
  with_items: "{{ dvs_output.results | map(attribute='stdout_lines') | list }}"

В loop_over_an_ip.yml содержит список задач, которые необходимо выполнить для каждого IP-адреса (который хранится в item). Вы можете переименовать его через loop_var.

- name: return next available IP address for network {{ ip_dns }}
  include_tasks: loop_over_an_ip.yml
  with_items: "{{ dvs_output.results | map(attribute='stdout_lines') | list }}"
  loop_control:
    loop_var: newip