简体   繁体   中英

How to exclude a word with regex in ansible playbook?

I am trying to develop a Ansible playbook to select and display the list of datastores in vCenter, however for validation purpose I should not select the datastore that contains the local or Local in its name.

For example consider the following 4 datastores:

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

It should only select:

  • vnx_dwcesxbl_ecom_lun7
  • tqaesx37d_1

Should not select:

  • datastore:local8
  • TQAESXHOST05-Local01

Here is the playbook

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

Need suggestions on writing the regex expression to exclude the datastores containing the word local .

Using a regex for this is probably an overkill. You can use the in test of Jinja to assert that a sub-string is contained in a string — since a string is just a sequence of characters, the in test works on strings.

So, given:

- 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

This yield:

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

And if you don't care about the casing of local at all ( Local , lOcAl , ...), you can even simplify it further with the lower filter and do:

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

Q: " Exclude the datastores containing the word 'local' or 'Local'. "

A: Reject the items where the attribute name can search Python regex '[lL]ocal' . For example, given the data below for testing

    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}

the task

    - 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 }}"

gives

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

If you want to keep all attributes of the items you can combine additional attributes. This simplifies the code. For example, the task below gives the same result

    - 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 }}"

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM