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