Apply action for each regexp match found on same line

19 views
Skip to first unread message

John Harmon

unread,
Nov 7, 2018, 11:36:43 AM11/7/18
to Ansible Project
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.

John Harmon

unread,
Nov 8, 2018, 11:14:20 AM11/8/18
to Ansible Project
bump

EspressoBeanies

unread,
Nov 8, 2018, 12:22:00 PM11/8/18
to Ansible Project
John, you can do all instances via the replace command or the last instance from the lineinfile command. 

On Thursday, November 8, 2018 at 11:14:20 AM UTC-5, John Harmon wrote:
bump

John Harmon

unread,
Nov 8, 2018, 12:27:26 PM11/8/18
to Ansible Project
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?

Kai Stian Olstad

unread,
Nov 10, 2018, 4:07:52 AM11/10/18
to ansible...@googlegroups.com
On Wednesday, 7 November 2018 17:36:43 CET John Harmon wrote:
> 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.

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.


--
Kai Stian Olstad


Thad Guidry

unread,
Nov 10, 2018, 11:48:17 AM11/10/18
to ansible...@googlegroups.com
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

--
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 post to this group, send email to ansible...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/ansible-project/118624768.r0sT80IGcL%40x1.
For more options, visit https://groups.google.com/d/optout.

John Harmon

unread,
Nov 12, 2018, 11:22:24 AM11/12/18
to Ansible Project
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.

John Harmon

unread,
Nov 12, 2018, 11:30:15 AM11/12/18
to Ansible Project

On Saturday, November 10, 2018 at 9:48:17 AM UTC-7, Thad Guidry wrote:
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


 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.

Thad Guidry

unread,
Nov 12, 2018, 1:23:21 PM11/12/18
to ansible...@googlegroups.com
OK, sounds good, yes a script should do the trick.  You can even write it in Python and later contribute a nice Ansible module :) :)

Here's inspiration:


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



--
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 post to this group, send email to ansible...@googlegroups.com.

John Harmon

unread,
Nov 13, 2018, 2:37:23 PM11/13/18
to Ansible Project
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


Reply all
Reply to author
Forward
0 new messages