ループ内でフィルタリングする Ansible 条件

ループ内でフィルタリングする Ansible 条件

scsi_controller値がゼロでない場合にVMからRDMディスクを削除するAnsibleタスクを作成しようとしています。しかし、いつ条件は、ループをたどるのではなく、タスク全体をスキップし、値がゼロのscsi_controller(s)のみをスキップすることです。私はまた試しましたネストあり、その結果はさらに悪化しました。

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

そして、繰り返しサブ要素あり

    - 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

関連情報