如何在ansible playbook中使用regex排除单词?

jmp7cifd  于 2023-04-07  发布在  其他
关注(0)|答案(2)|浏览(117)

我正在尝试开发一个Ansible剧本来选择和显示vCenter中的数据存储列表,但是出于验证目的,我不应该选择名称中包含localLocal的数据存储。
例如,考虑以下4个数据存储区:

  • datastore:local8
  • TQAESXHOST05-Local01
  • vnx_dwcesxbl_ecom_lun7
  • tqaesx37d_1

它应该只选择:

  • vnx_dwcesxbl_ecom_lun7
  • tqaesx37d_1

选择:

  • datastore:local8
  • TQAESXHOST05-Local01

这是战术手册

tasks:
- name: List of datastores with calculated values
  set_fact:
    ds_size_list: "{{ ds_size_list | default([]) + [{ 'name' : item.name, 'capacity' : item.capacity, 'freeSpace' : item.freeSpace, 'freeSpaceAfter' : freeSpaceAfter | int, 'percentFreeAfter' : percentFreeAfter | int }] }}"
  with_items: "{{ datastore_info.datastores }}"
  vars:
    freeSpaceAfter: "{{ item.freeSpace - (vm_size_b | int) }}"
    percentFreeAfter: "{{ freeSpaceAfter | int / item.capacity * 100 }}"
  when: item.accessible
  when: when: item.name is regex(?!local) #should exclude datastores containing "local" word

需要有关编写regex表达式以排除包含单词local的数据存储区的建议。

wf82jlnq

wf82jlnq1#

问:"排除包含单词'local'或'Local'的数据存储区。"
A:拒绝属性 name 可以 search Python regex '[lL]ocal'的项目。例如,给定以下测试数据

datastores:
      - {name: datastore:local8, capacity: 100, freeSpace: 10}
      - {name: TQAESXHOST05-Local01, capacity: 200, freeSpace: 20}
      - {name: vnx_dwcesxbl_ecom_lun7, capacity: 300, freeSpace: 30}
      - {name: tqaesx37d_1, capacity: 400, freeSpace: 40}

任务

- set_fact:
        ds_size_list: "{{ ds_size_list|default([]) +
                          [{'name': item.name,
                            'capacity': item.capacity,
                            'freeSpace' : item.freeSpace,
                            'percentFreeAfter': percentFreeAfter|int }] }}"
      loop: "{{ datastores|rejectattr('name', 'search', '[lL]ocal') }}"
      vars:
        percentFreeAfter: "{{ item.freeSpace|int / item.capacity|int * 100 }}"

给予

ds_size_list:
  - capacity: 300
    freeSpace: 30
    name: vnx_dwcesxbl_ecom_lun7
    percentFreeAfter: 10
  - capacity: 400
    freeSpace: 40
    name: tqaesx37d_1
    percentFreeAfter: 10

如果你想保留项目的所有属性,你可以 * 合并 * 额外的属性。这简化了代码。例如,下面的任务给出了相同的结果

- set_fact:
        ds_size_list: "{{ ds_size_list|default([]) +
                          [item|combine({'percentFreeAfter': percentFreeAfter|int})] }}"
      loop: "{{ datastores|rejectattr('name', 'search', '[lL]ocal') }}"
      vars:
        percentFreeAfter: "{{ item.freeSpace|int / item.capacity|int * 100 }}"
zlwx9yxi

zlwx9yxi2#

使用正则表达式可能有些矫枉过正。你可以使用Jinja的in测试来Assert一个子字符串包含在一个字符串中-因为字符串只是一个字符序列,所以in测试对字符串有效。
因此,给定:

- debug:
    msg: "{{ item.name }}"
  loop: "{{ datastore_info.datastores }}"
  when: 
    - item.accessible
    - "'Local' not in item.name"
    - "'local' not in item.name"
  loop_control:
    label: "{{ item.name }}"
  vars:
    datastore_info:
      datastores:
        - name: datastore:local8
          accessible: yes
        - name: TQAESXHOST05-Local01
          accessible: yes
        - name: vnx_dwcesxbl_ecom_lun7
          accessible: yes
        - name: tqaesx37d_1
          accessible: yes

该产量:

TASK [debug] ******************************************************
skipping: [localhost] => (item=datastore:local8) 
skipping: [localhost] => (item=TQAESXHOST05-Local01) 
ok: [localhost] => (item=vnx_dwcesxbl_ecom_lun7) => 
  msg: vnx_dwcesxbl_ecom_lun7
ok: [localhost] => (item=tqaesx37d_1) => 
  msg: tqaesx37d_1

如果你根本不关心local的大小写(LocallOcAl,...),你甚至可以用lower过滤器进一步简化它:

when: 
  - item.accessible
  - "'local' not in item.name | lower"

相关问题