
scsi_controller 값이 0이 아닐 때 VM에서 RDM 디스크를 제거하기 위해 Ansible 작업을 생성하려고 합니다. 그러나, 그언제조건은 루프를 순회하고 값이 0인 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,
}
이제 속성 목록을 생성합니다(_키),발췌문자열,나뉘다아이템, 그리고가입하다필터에 대한 인수zip2. 그런 다음 생성선택모든 것으로부터_키. 예를 들어, 테스트를 위해 단순화된 데이터가 주어지면
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