blob: 6cc8e839173ce38dc6f822389ee97a0fd75333b2 [file] [log] [blame]
Adam Tengler82074b02018-08-10 15:58:06 +00001from itertools import chain
2from netaddr import iter_iprange, IPAddress, IPNetwork
Adam Tenglera2f260a2018-07-12 17:35:28 +00003
4__virtualname__ = 'netutils'
5
6
7def __virtual__():
8 return __virtualname__
9
10
Adam Tengler82074b02018-08-10 15:58:06 +000011def parse_ip_ranges(ranges, needed):
Adam Tenglera2f260a2018-07-12 17:35:28 +000012 '''
13 Takes comma seprated list of IP ranges and returns full list of IP addresses in these ranges.
14 Second argument is used to check if there is enough IP addresses to cover the required number of nodes.
15
Adam Tengler82074b02018-08-10 15:58:06 +000016 >>> parse_ip_ranges("192.168.1.101-192.168.1.103,192.168.2.101-192.168.2.103")
Adam Tenglera2f260a2018-07-12 17:35:28 +000017 ["192.168.1.101", "192.168.1.102", "192.168.1.103", "192.168.2.101", "192.168.2.102", "192.168.2.103"]
18 '''
19 range_list = ranges.split(',')
20 ip_obj_list = []
21 for _range in ranges.split(','):
22 ip_obj_list += list(iter_iprange(*_range.split('-')))
23 ip_list = [str(ip) for ip in ip_obj_list]
24 if len(ip_list) < needed:
25 raise ValueError('There is not enough IP addresses in ranges: "{}". {} available, {} required.'.format(ranges, len(ip_list), needed))
26 return ip_list
Adam Tengler82074b02018-08-10 15:58:06 +000027
28
29def parse_network_ranges(ranges, iterate=False):
30 '''
31 Takes comma separated list of network ranges and returns full list of first IP addresses in every given subnet.
32 Second argument is used to check if there is enough IP addresses to cover the required number of nodes.
33
34 >>> parse_network_ranges("10.10.0.1/24-10.10.10.1/24,192.168.0.1/24-192.168.10.1/24")
35 ['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']
36 '''
37 def _iter_subnet_list(start, end):
38 yield str(IPAddress(start.first) + 1)
39 if start != end:
40 for ip in _iter_subnet_list(start.next(), end):
41 yield ip
42
43 generators = tuple()
44
45 for _range in ranges.split(','):
46 start_str, end_str = _range.split('-')
47 start, end = IPNetwork(start_str), IPNetwork(end_str)
48 if start > end:
49 raise ValueError('Invalid network range, start address is higher than end address')
50 generators += (_iter_subnet_list(start, end),)
51
52 if iterate:
53 return [ip for ip in chain(*generators)]
54 return chain(*generators)