Gana Sagar
Gana Sagar

Reputation: 131

Regular expression matching for IP range in Ansible Playbooks for grouping

I am trying to write a regular expression for a dynamic group in ansible-playbook for an sample ip range. if the address range is 172.30.0.(0 to 254).(0 to 254). My regex is like 172.30.[0-254].[0-254]. Is this correct ? Even though I have the hosts in the range, the tasks are being skipped and no groups are being formed.

tasks: - group_by: key=adda when: ansible_default_ipv4.network == '172.30.[0-254].[0-254]'

grouping picture

Upvotes: 2

Views: 8638

Answers (6)

Gana Sagar
Gana Sagar

Reputation: 131

I tried comparing networks it work out. So I tired what @ebel suggested and it worked the way I wanted. Thanks

enter image description here

Upvotes: 0

Vor
Vor

Reputation: 35099

You probably want to use Jinja2 match filter to match regex:

Something like this:

---

- hosts: localhost
  gather_facts: no
  connection: local
  vars:
    ip_not_ok: '172.31.0.1'
    ip_ok: '172.30.0.1'
  tasks:
   - debug: msg='OK'
     when: ip_ok | match('172.30')

   - debug: msg='OK'
     when: ip_not_ok | match('172.30')

Upvotes: 0

Konstantin Suvorov
Konstantin Suvorov

Reputation: 68229

If you compare networks, you shouldn't care about ranges!

tasks:
  - group_by: key=adda
    when: ansible_default_ipv4.network == '172.30.0.0'

This will (generally) match all hosts with IPs 172.30.0.1 - 172.30.255.255.

If you need to compare IP addresses, use ipaddr filter:

tasks:
  - group_by: key=adda
    when: ansible_default_ipv4.address | ipaddr('172.30.0.0/16') | ipaddr('bool')

Upvotes: 2

ebal
ebal

Reputation: 375

When using the operator '==' then in python you are trying to find a matched string with the name '172.30.[0-254[.[0-254]'

In ansible you can use python expression like search or match.

So you need to type something like this:

when: ansible_default_ipv4.address | match("172.30.")

Did a test ansible playbook to verify it.

Upvotes: 2

GingerPlusPlus
GingerPlusPlus

Reputation: 5606

Regex isn't good tool for that.

from ipaddress import ip_address
import operator

def ip_check_range(ranges, s):
    return all(map(operator.contains,
        ranges,
        ip_address(s).packed
    ))

print(ip_check_range([[172], [30], range(255), range(255)], '172.30.1.2')) # => True
print(ip_check_range([[172], [30], range(255), range(255)], '172.30.1.255')) # => False

Alternatively, If you're on Python<3.3 and don't have ipaddress module:

def ip_check_range(ranges, s):
    ip = s.split('.')
    if len(ip) != 4:
        raise ValueError
    return all(map(operator.contains,
        ranges,
        (int(octet) for octet in ip)
    ))

Upvotes: 0

baddger964
baddger964

Reputation: 1227

[0-225] is an incorrect regex. [] Define a range of character from one to another character in the ACII table and 255 is not an ASCII character.

replace it by (?:25[0-4]|2[0-4][0-9]|[01]?[0-9][0-9]?)

So the complete regex is :

173\.30\.(?:25[0-4]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(?:25[0-4]|2[0-4][0-9]|[01]?[0-9][0-9]?)

as this post said : Regex to match an IP address

Upvotes: 1

Related Questions