Ansible 循环内过滤条件

Ansible 循环内过滤条件

我正在尝试创建一个 Ansible 任务,以在 scsi_controller 值不为零时从虚拟机中删除 RDM 磁盘。但是,什么时候条件是跳过整个任务,而不是循环执行并仅跳过值为零的 scsi_controller。我也尝试过with_nested,结果更糟糕。

rdm_info(变量):

"scsi_controller": "0,0,1,1,1,2,2,3,3,3,3",
"unit_number": "0,1,2,0,1,0,1,0,1,14,15",
"vm_name": "test_vm"
    

剧本任务:

- name: Remove rdm disks
  community.vmware.vmware_guest_disk:
    validate_certs: false
    hostname: '{{ vc_server }}'
    username: '{{ vc_user }}'
    password: '{{ vc_pass }}'
    datacenter: '{{ datacenter_name }}'
    name: '{{ item.0 }}'
    disk:
      - state: absent
        scsi_controller: "{{ item.1 | int }}"
        unit_number: "{{ item.2 | int }}"
        destroy: no     
  loop: "{{ rdm_info | json_query('[*].vm_name') | zip( rdm_info | json_query('[*].scsi_controller') | map('split',','), rdm_info | json_query('[*].unit_number') | map('split',',')) }}"         
  when: item.1 | int != 0  
  delegate_to: localhost
  register: rdms_unmounted

我将非常感激任何帮助,因为我已经在这部戏上投入了超过 20 个小时。

答案1

2 个属性

添加属性选择对于项目,例如

    - set_fact:
        rdm_sel: "{{ rdm_sel|d([]) + [item|combine({'selection': selection})] }}"
      loop: "{{ rdm_info }}"
      vars:
        scsi_controller: "{{ item.scsi_controller.split(',') }}"
        unit_number: "{{ item.unit_number.split(',') }}"
        selection: "{{ scsi_controller|
                       zip(unit_number)|
                       rejectattr('0', 'eq', '0') }}"

给出

  rdm_sel:
    - scsi_controller: 0,0,1,1,1,2,2,3,3,3,3
      selection:
      - ['1', '2']
      - ['1', '0']
      - ['1', '1']
      - ['2', '0']
      - ['2', '1']
      - ['3', '0']
      - ['3', '1']
      - ['3', '14']
      - ['3', '15']
      unit_number: 0,1,2,0,1,0,1,0,1,14,15
      vm_name: test_vm

然后,迭代with_subelements

    - debug:
        msg: >-
          name: {{ item.0.vm_name }}
          scsi_controller: {{ item.1.0 }}
          unit_number: {{ item.1.1 }}
      with_subelements:
        - "{{ rdm_sel }}"
        - selection

给出

  msg: 'name: test_vm scsi_controller: 1 unit_number: 2'
  msg: 'name: test_vm scsi_controller: 1 unit_number: 0'
  msg: 'name: test_vm scsi_controller: 1 unit_number: 1'
  msg: 'name: test_vm scsi_controller: 2 unit_number: 0'
  msg: 'name: test_vm scsi_controller: 2 unit_number: 1'
  msg: 'name: test_vm scsi_controller: 3 unit_number: 0'
  msg: 'name: test_vm scsi_controller: 3 unit_number: 1'
  msg: 'name: test_vm scsi_controller: 3 unit_number: 14'
  msg: 'name: test_vm scsi_controller: 3 unit_number: 15'

(可选)添加所有单位

    - set_fact:
        rdm_units: "{{ rdm_units|d([]) + [item|combine({'units': units})] }}"
      loop: "{{ rdm_info }}"
      loop_control:
        label: "{{ item.vm_name }}"
      vars:
        scsi_controller: "{{ item.scsi_controller.split(',') }}"
        unit_number: "{{ item.unit_number.split(',') }}"
        units: "{{ scsi_controller|zip(unit_number) }}"

给出

  rdm_units:
    - scsi_controller: 0,0,1,1,1,2,2,3,3,3,3
      unit_number: 0,1,2,0,1,0,1,0,1,14,15
      units:
      - ['0', '0']
      - ['0', '1']
      - ['1', '2']
      - ['1', '0']
      - ['1', '1']
      - ['2', '0']
      - ['2', '1']
      - ['3', '0']
      - ['3', '1']
      - ['3', '14']
      - ['3', '15']
      vm_name: test_vm

然后,选择循环中的单元。下面的任务给出相同的结果。

    - debug:
        msg: >-
          name: {{ item.0.vm_name }}
          scsi_controller: {{ item.1.0 }}
          unit_number: {{ item.1.1 }}
      with_subelements:
        - "{{ rdm_units }}"
        - units
      when: item.1.0 != '0'

多个属性

Ansible 不提供过滤器来压缩列表列表。但是,您可以创建一个非常简单的自定义过滤器,例如

shell> cat filter_plugins/zip2.py
def zip2(l):
    return zip(*l)


class FilterModule(object):
    def filters(self):
        return {
            'zip2': zip2,
        }

现在,创建一个属性列表(_keys),提炼琴弦,分裂这些物品,以及加入过滤器的参数zip2.然后创建选择来自所有_keys例如,给定简化的测试数据

  rdm_info:
    - x: 0,2,3
      y: 4,5,6
      z: 7,8,9
      n: A
    - x: 1,0,3
      y: 4,5,6
      z: 7,8,9
      n: B
    - x: 1,2,0
      y: 4,5,6
      z: 7,8,9
      n: C

下面的任务

    - set_fact:
        rdm_sel: "{{ rdm_sel|d([]) + [item|combine({'selection': selection})] }}"
      loop: "{{ rdm_info }}"
      vars:
        _keys: [x, y, z]
        _args: "{{ _keys|map('extract', item)|map('split', ',')|join(',') }}"
        selection: "{{ _args|zip2|rejectattr('0', 'eq', '0') }}"

给出

  rdm_sel:
    - n: A
      selection:
      - ['2', '5', '8']
      - ['3', '6', '9']
      x: 0,2,3
      y: 4,5,6
      z: 7,8,9
    - n: B
      selection:
      - ['1', '4', '7']
      - ['3', '6', '9']
      x: 1,0,3
      y: 4,5,6
      z: 7,8,9
    - n: C
      selection:
      - ['1', '4', '7']
      - ['2', '5', '8']
      x: 1,2,0
      y: 4,5,6
      z: 7,8,9

相关内容