Apply action for each regexp match found on same line

Assume the following line:

vif = ['mac=00:21:f6:04:16:f3,bridge=101498d8ff', 'mac=00:21:f6:80:0b:d9,bridge=1017dc5841']

If I use lineinfile, replace, etc to do a regular expression match, can I somehow apply the following to each instances (instead of just once for both instances):
Action:

regexp: (vif\W+)?((?:, )?'mac=00:21:f6:)((\w{2}:?){3})(,bridge=\w+')(?:])? line: \1\2AA:{{ 99 | random(start=10, step=1) }}:{{ 99 | random(start=10, step=1) }}\5

Regexp Testing link:
https://regex101.com/r/JcgI7i/1

Desired (As shown above, keep first three octets of mac, change 4th to AA, and the last two are random numbers between 10-99):

vif = ['mac=00:21:f6:AA:21:56,bridge=101498d8ff', 'mac=00:21:f6:AA:17:27,bridge=1017dc5841']

Actual (notice that they are both the same–which is what I don’t want)

vif = ['mac=00:21:f6:AA:58:16,bridge=101498d8ff', 'mac=00:21:f6:AA:58:16,bridge=1017dc5841']

As I think about it I don’t know of a way to do this within a single task. Possibly in 2 tasks or more, but that number of vifs will vary from time to time. It may be anywhere from 1-5 possibly.

bump

John, you can do all instances via the replace command or the last instance from the lineinfile command.

When I use the replace module, all instances get the same mac address. I need each mac address to be different. How can I use replace to make each one different?

This isn't easy with Ansible modules so that's probably why you haven't gotten an answer.
I probably wont give you one either.

To get different values you need multiple runs over the file.
When you run the fist one it will change all the lines, the same will happened on the second run but with different value but same value on each line.
To do this you would need a way to know which line you already changed and then avoid them.

The best thing in this circumstances is to let Ansible create the file with the template module.
Or use some external script like perl, awk, sed or python.

John,

What problem are you actually trying to solve ? Generating random numbers especially around MAC certainly can get you in trouble. Are you trying to generate a Pool and apply something 1 time from that Pool ?

Explain the use case, and we could help a lot more.

-Thad

Thanks Kai. I was thinking along those lines. A template isn’t applicable in this scenario. I will just have to go with an outside script.

Thad,
We clone systems in Oracle VM. There are a handful of steps to clean up the vm.cfg from the clone, which has details about the VM. If you don’t change the MAC address (for instance), when you bring up the clone it will pull the NIC from the live system (one of those wonderful Oracle VM features). I am just trying to take a repetitive process and clean it up without direct human intervention. That will prevent human error (in case we miss something) and make it easier. I have all steps done except this one. If there is just one nic it works fine too, but when testing it out I happened to clone a system with 2 nics and I discovered the issue. I have some systems with 3 nics. I think I will have to script it as Kai said.

I know that messing with NIC MAC addresses can get you in trouble, but right now we are just doing the same thing manually. The clones don’t usually last that long, and when done they are usually purged. I don’t believe any of our current VMs have AA in the fourth octet (and if they did I could change it to something else), and then the last 2 octets are randomized… chances of hitting an existing MAC are about nil.

OK, sounds good, yes a script should do the trick. You can even write it in Python and later contribute a nice Ansible module :slight_smile: :slight_smile:

Here’s inspiration:
https://docs.ansible.com/ansible/latest/modules/list_of_cloud_modules.html#vmware
https://docs.ansible.com/ansible/latest/modules/list_of_cloud_modules.html#misc

https://docs.ansible.com/ansible/latest/modules/ovirt_mac_pool_module.html?highlight=mac
https://docs.ansible.com/ansible/latest/modules/vmware_guest_module.html?highlight=mac

You can click “Edit on Github” in top right corner to get right to the existing code for those modules.

In case anybody else is looking to do the same thing, here is my BASH solution:

`

  • name: Sanitize Virtual Interface(s)
    shell: |
    file=“/var/ftp/vm.cfg”
    total=$( grep ^vif “$file” | grep -o mac | wc -l )
    for i in seq 1 $total; do
    my_random=$(xxd -l 1 -p /dev/urandom )
    my_random2=$(xxd -l 1 -p /dev/urandom )
    sed -ri “s|mac=00:21:f6:((\w{2}(:)?){3})|mac=00:21:f6:aa:${my_random}:${my_random2}|${i}” $file
    done

`