Trying to replace single quote with regex_replace

223 views
Skip to first unread message

Dimitri Yioulos

unread,
Jan 10, 2024, 9:08:46 AM1/10/24
to Ansible Project
Hello, all.

I'm working with VMware modules in removing snapshots across all vCenter folders. In order for this to work, I first have to get the folders in which the virtual machines live. Here's the playbook:

---

- hosts: all
  become: false
  gather_facts: false

  vars_prompt:

    - name: "vcenter_username"
      prompt: "Enter your Vcenter username"
      private: no
    - name: "vcenter_password"
      prompt: "Enter your VMware password"
      private: yes

  vars:
    vcenter_hostname: vcenter1.mycompany.com
    vcenter_datacenter: First Datacenter

  tasks:

    - name: Find virtual machine's folder name
      vmware_guest_find:
        hostname: "{{ vcenter_hostname }}"
        username: "{{ vcenter_username }}"
        password: "{{ vcenter_password }}"
        name: "{{ inventory_hostname }}"
        validate_certs: False
      delegate_to: localhost
      ignore_errors: true
      register: vm_facts
      tags:
        - folder

    - name: Show folders
      ansible.builtin.debug:
        msg: "{{ vm_facts.folders }}"
      tags:
        - folder

    - name: Remove all snapshots of a VM
      community.vmware.vmware_guest_snapshot:
        hostname: "{{ vcenter_hostname }}"
        username: "{{ vcenter_username }}"
        password: "{{ vcenter_password }}"
        datacenter: "{{ vcenter_datacenter }}"
        folder: "{{ vm_facts.folders | regex_replace('(\\[)|(\\])',  '') }}"
        name: "{{ inventory_hostname }}"
        state: remove_all
        validate_certs: False
      delegate_to: localhost


Previous to my having employed regex_replace, this is the output I'd get, e.g., for a vm's folder:

"['/First Datacenter/vm/Prod-SRM']"

The problem with that is [' and ']. They can't be part pf the folder name. After employing regex-replace, the output is:

" '/Bedford Datacenter/vm/Bedford-Prod-SRM' "

Try as I may, I've not been able to find a way to also remove the single quotes (the double quotes can remain). I've tried appending to the regex_replace, but every piece of code i've used has failed.

regex_replace('(\\[)|(\\])'|(addlcodehere),  '') }}

Your kinf assistance requested.

Rowe, Walter P. (Fed)

unread,
Jan 10, 2024, 9:27:25 AM1/10/24
to ansible...@googlegroups.com
Have you tried:

regex_replace('(\\[)|(\\])|(\\')', '')

Walter
--
Walter Rowe, Division Chief
Infrastructure Services Division
Mobile: 202.355.4123

--
You received this message because you are subscribed to the Google Groups "Ansible Project" group.
To unsubscribe from this group and stop receiving emails from it, send an email to ansible-proje...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/ansible-project/34393455-5021-4342-89b4-de276d68ccd9n%40googlegroups.com.

Dimitri Yioulos

unread,
Jan 10, 2024, 9:56:37 AM1/10/24
to Ansible Project
Hi, Walter.

Yes, and it fails:

fatal: [api-dev-01 -> localhost]: FAILED! => {
    "msg": "template error while templating string: expected token 'end of print statement', got 'string'. String: {{ vm_facts.folders | regex_replace('(\\\\[)|(\\\\])|(\\\\')',  '') }}. expected token 'end of print statement', got 'string'"
}


Rowe, Walter P. (Fed)

unread,
Jan 10, 2024, 10:14:32 AM1/10/24
to ansible...@googlegroups.com
This works.

regex_replace(\"([\\[\\]'])\",'')


Escaping the double quotes that define the search regex gets around needing to escape the single quote. Also note that I collapsed your search into a single character set.

---

- name: test

  hosts: localhost

  become: false

  gather_facts: false

  vars:

    mystr: "['/First Datacenter/vm/Prod-SRM']"

  tasks:

    - debug: msg="{{ mystr | regex_replace(\"([\\[\\]'])\",'') }}"



% ansible-playbook -i localhost, foo.yml


PLAY [test] ************************************************************************************************************


TASK [debug] ***********************************************************************************************************

ok: [localhost] => {

    "msg": "/First Datacenter/vm/Prod-SRM"

}


PLAY RECAP *************************************************************************************************************

localhost                  : ok=1    changed=0    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0   


The solution was found on this stack overflow page.


Walter
--
Walter Rowe, Division Chief
Infrastructure Services Division
Mobile: 202.355.4123

Dimitri Yioulos

unread,
Jan 10, 2024, 10:33:53 AM1/10/24
to Ansible Project
Walter, that worked, and thanks so much! I both appreciate the regex solution, and it simplification. I also probably be able to reuse this, with some modifications, depending on what I'm trying to accomplish. Double win. Thanks again!

Dimitri Yioulos

unread,
Jan 10, 2024, 11:03:17 AM1/10/24
to Ansible Project
Walter, to further my knowledge, would you mind explaining further what this regex  \"([\\[\\]'])\",'  does? Is the regex specifi to regex_replace?

Rowe, Walter P. (Fed)

unread,
Jan 10, 2024, 11:18:23 AM1/10/24
to ansible...@googlegroups.com
In plain terms it is really this:

[[]']

The outside square brackets define a character set. The characters in between mean "any of these".

Since square brackets define a character set we have to escape the inside square brackets to be see as characters in the set.

[\[\]']

Since this is ansible we have to escape the backslashes.

[\\[\\]']

You could place any characters in that set. The regex matches *any* of them any number of times.

For example I could use [walter] and it would look for any of those characters.

You also can use ranges like [a-dv-z]. This all follows Python regex rules.

Walter
--
Walter Rowe, Division Chief
Infrastructure Services Division
Mobile: 202.355.4123

Vladimir Botka

unread,
Jan 10, 2024, 12:17:10 PM1/10/24
to ansible...@googlegroups.com
> "['/First Datacenter/vm/Prod-SRM']"
> The problem is [' and ']. They can't be part pf the folder name.

FWIW, convert the string to a list

s: "['/First Datacenter/vm/Prod-SRM']"
l: "{{ s|from_yaml }}"

gives

l.0: /First Datacenter/vm/Prod-SRM

--
Vladimir Botka

Rowe, Walter P. (Fed)

unread,
Jan 10, 2024, 12:24:40 PM1/10/24
to ansible...@googlegroups.com
Even better! Brilliant!


Walter
--
Walter Rowe, Division Chief
Infrastructure Services Division
Mobile: 202.355.4123
--
You received this message because you are subscribed to the Google Groups "Ansible Project" group.
To unsubscribe from this group and stop receiving emails from it, send an email to ansible-proje...@googlegroups.com.

Dimitri Yioulos

unread,
Jan 12, 2024, 12:05:16 PM1/12/24
to Ansible Project
Thanks, Vladimir. Forgive my stupidity but, for my edification, how is that actually written in the playbook?

Vladimir Botka

unread,
Jan 12, 2024, 3:20:51 PM1/12/24
to Dimitri Yioulos, ansible...@googlegroups.com
> > On Jan 10, 2024, at 12:16 PM, Vladimir Botka <vbo...@gmail.com> wrote:
> > FWIW, convert the string to a list
> >
> > s: "['/First Datacenter/vm/Prod-SRM']"
> > l: "{{ s|from_yaml }}"

On Fri, 12 Jan 2024 09:05:16 -0800 (PST)
Dimitri Yioulos <dyio...@gmail.com> wrote:
> how is that actually written in the playbook?


For example,

shell> cat pb1.yml
- hosts: all
vars:
s: "['/First Datacenter/vm/Prod-SRM']"
l: "{{ s|from_yaml }}"
tasks:
- debug:
var: l|type_debug
- debug:
var: l.0

gives (abridged)

l|type_debug: list
l.0: /First Datacenter/vm/Prod-SRM

But, the code in your first email shows you get *vm_facts* as
registered output of *community.vmware.vmware_guest_find*. Take a
look at the Return Values of this module
https://docs.ansible.com/ansible/latest/collections/community/vmware/vmware_guest_find_module.html#return-values

The documentation says *folders* is "list/elements=string". In this
case, no conversion is needed to get the element of the list. For
example,

shell> cat pb2.yml
- hosts: all
vars:
vm_facts:
folders: ['/First Datacenter/vm/Prod-SRM']
tasks:
- debug:
var: vm_facts.folders|type_debug
- debug:
var: vm_facts.folders.0

gives (abridged)

vm_facts.folders|type_debug: list
vm_facts.folders.0: /First Datacenter/vm/Prod-SRM

FWIW, try community.general.yaml callback. YAML is much easier to
read compared to JSON. See
https://docs.ansible.com/ansible/latest/collections/community/general/yaml_callback.html

--
Vladimir Botka
Reply all
Reply to author
Forward
0 new messages