Итерация через вложенные циклы - PullRequest
0 голосов
/ 25 октября 2019

Файл packages.yml определен как:

---
- packages:
    - name: Some description 1,
      packageList:
        - package1,
        - package2,
        - package3

    - name: Some description 2,
      package: package4

Первый элемент содержит поле packageList, второй элемент не имеет его, но только поле package.

Playbook:

---
- hosts: all
  become: yes
  vars_files:
    - packages.yml

Как выполнить итерацию по всем packageList элементам списка packages, только если этот packageList определен для элемента.

Вот как я могу это сделатьперебирать элементы, которые содержат package поле:

- name: iteration
  debug:
    msg: "name: {{ item.package }}"
  when: item.package is defined
  with_items: "{{ packages }}"

Ответы [ 3 ]

0 голосов
/ 25 октября 2019

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

{{ item.packageList | default ([]) }}

Если packageList не определено, задание повторяется по пустому списку,что означает, что он ничего не делает.

0 голосов
/ 25 октября 2019

Вы можете использовать default, как упомянуто @ceving:

---
- hosts: localhost
  connection: local

  vars_files:
  - packages.yml

  tasks:
  - name: iteration
    debug:
      msg: "name: {{ item.packageList | default([item.package]) }}"
    with_items: "{{ packages }}"

Если существует packageList, он будет использовать это, иначе package поместит в массив из одного элемента, чтобы соответствовать формеиз packageList:

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

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

TASK [iteration] **********************************************************************************************
ok: [localhost] => (item=None) => {
    "msg": "name: [u'package1,', u'package2,', u'package3']"
}
ok: [localhost] => (item=None) => {
    "msg": "name: [u'package4']"
}

PLAY RECAP ****************************************************************************************************
localhost                  : ok=2    changed=0    unreachable=0    failed=0   
0 голосов
/ 25 октября 2019

Как отмечается в моем комментарии, если вы просто хотите установить несколько пакетов yum / apt, обычно более эффективно просто передать список в модуль apt/yum/package. Как состояние документов :

"При использовании с циклом: каждый пакет будет обрабатываться индивидуально, гораздо эффективнее передать список непосредственно параметру имени."

Однако, если вам действительно нужен цикл, вот возможное решение:

playbook.yml:

---
- hosts: all
  gather_facts: false
  vars_files:
    - packages.yml

  tasks:
  - name: iteration over single items
    debug:
      msg: "name: {{ item.package }}"
    when: item.package is defined
    with_items: "{{ packages }}"

  - name: iteration over lists
    debug:
      msg: "name: {{ item.packageList }}"
    when: item.packageList is defined
    with_items: "{{ packages }}"

  - name: Do something with individual packages in the list
    include_tasks: process_list.yml
    vars: 
      mylist: "{{outer.packageList}}"
    when: outer.packageList is defined
    loop: "{{ packages }}"
    loop_control:
      loop_var: outer

process_list.yml:

- name: See what we have received
  debug:
    var: item
  loop: "{{mylist}}"

результат:

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

TASK [iteration over single items] *******************************************************************************************************
skipping: [localhost] => (item={u'packageList': [u'package1,', u'package2,', u'package3'], u'name': u'Some description 1,'}) 
ok: [localhost] => (item={u'name': u'Some description 2,', u'package': u'package4'}) => {
    "msg": "name: package4"
}

TASK [iteration over lists] **************************************************************************************************************
ok: [localhost] => (item={u'packageList': [u'package1,', u'package2,', u'package3'], u'name': u'Some description 1,'}) => {
    "msg": "name: [u'package1,', u'package2,', u'package3']"
}
skipping: [localhost] => (item={u'name': u'Some description 2,', u'package': u'package4'}) 

TASK [Do something with individual packages in the list] *********************************************************************************
skipping: [localhost] => (item={u'name': u'Some description 2,', u'package': u'package4'}) 
included: /root/tmp/process_list.yml for localhost

TASK [See what we have received] *********************************************************************************************************
ok: [localhost] => (item=package1,) => {
    "ansible_loop_var": "item", 
    "item": "package1,"
}
ok: [localhost] => (item=package2,) => {
    "ansible_loop_var": "item", 
    "item": "package2,"
}
ok: [localhost] => (item=package3) => {
    "ansible_loop_var": "item", 
    "item": "package3"
}

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

Часть loop_control / loop_var используется, потому что в противном случае и внешний, и внутренний цикл будут использовать {{item}} в качестве переменной цикла - и это приведет к ... интересным результатам:)

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...