blob: 2be6079f9813f75cd8aae45fd06f96b975cabf7e [file] [log] [blame]
from itertools import chain
try:
from netaddr import iter_iprange, IPAddress, IPNetwork
HAS_NETADDR = True
except ImportError:
HAS_NETADDR = False
__virtualname__ = 'netutils'
def __virtual__():
if not HAS_NETADDR:
return False, "'netaddr' python library is unavailable"
return __virtualname__
def parse_ip_ranges(ranges, needed):
'''
Takes comma seprated list of IP ranges and returns full list of IP addresses in these ranges.
Second argument is used to check if there is enough IP addresses to cover the required number of nodes.
>>> parse_ip_ranges("192.168.1.101-192.168.1.103,192.168.2.101-192.168.2.103")
["192.168.1.101", "192.168.1.102", "192.168.1.103", "192.168.2.101", "192.168.2.102", "192.168.2.103"]
'''
range_list = ranges.split(',')
ip_obj_list = []
for _range in ranges.split(','):
ip_obj_list += list(iter_iprange(*_range.split('-')))
ip_list = [str(ip) for ip in ip_obj_list]
if len(ip_list) < needed:
raise ValueError('There is not enough IP addresses in ranges: "{}". {} available, {} required.'.format(ranges, len(ip_list), needed))
return ip_list
def parse_network_ranges(ranges, iterate=False):
'''
Takes comma separated list of network ranges and returns full list of first IP addresses in every given subnet.
Second argument is used to check if there is enough IP addresses to cover the required number of nodes.
>>> parse_network_ranges("10.10.0.1/24-10.10.10.1/24,192.168.0.1/24-192.168.10.1/24")
['10.10.0.1', '10.10.1.1', '10.10.2.1', '10.10.3.1', '10.10.4.1', '10.10.5.1', '10.10.6.1', '10.10.7.1', '10.10.8.1', '10.10.9.1', '10.10.10.1', '192.168.0.1', '192.168.1.1', '192.168.2.1', '192.168.3.1', '192.168.4.1', '192.168.5.1', '192.168.6.1', '192.168.7.1', '192.168.8.1', '192.168.9.1', '192.168.10.1']
'''
def _iter_subnet_list(start, end):
yield str(IPAddress(start.first) + 1)
if start != end:
for ip in _iter_subnet_list(start.next(), end):
yield ip
generators = tuple()
for _range in ranges.split(','):
start_str, end_str = _range.split('-')
start, end = IPNetwork(start_str), IPNetwork(end_str)
if start > end:
raise ValueError('Invalid network range, start address is higher than end address')
generators += (_iter_subnet_list(start, end),)
if iterate:
return [ip for ip in chain(*generators)]
return chain(*generators)