Ansible
在循環內過濾的 Ansible 條件
當 scsi_controller 值不為零時,我正在嘗試創建一個 Ansible 任務以從 VM 中刪除 RDM 磁碟。但是,when條件是跳過整個任務,而不是遍歷循環並僅跳過值為 0 的 scsi_controller(s)。我也試過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 多個小時。
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