Add function which increments network addresses and
returns list of first host addresses
Issue: PROD-21241
Change-Id: I500d27d9adebc739d81ff960ad512c39fa9c84a0
diff --git a/README.rst b/README.rst
index 1621ce9..2cb9608 100644
--- a/README.rst
+++ b/README.rst
@@ -224,6 +224,8 @@
ip_ranges:
single_address: '172.16.10.97-172.16.10.98'
tenant_address: '172.16.20.97-172.16.20.98'
+ network_ranges:
+ sriov_address: '10.10.0.1/24-10.10.50.1/24'
start: 1
count: 50
digits: 3
diff --git a/_modules/netutils.py b/_modules/netutils.py
index 2efd7e6..6cc8e83 100644
--- a/_modules/netutils.py
+++ b/_modules/netutils.py
@@ -1,4 +1,5 @@
-from netaddr import iter_iprange
+from itertools import chain
+from netaddr import iter_iprange, IPAddress, IPNetwork
__virtualname__ = 'netutils'
@@ -7,12 +8,12 @@
return __virtualname__
-def parse_network_ranges(ranges, needed):
+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_network_ranges("192.168.1.101-192.168.1.103,192.168.2.101-192.168.2.103")
+ >>> 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(',')
@@ -23,3 +24,31 @@
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)
diff --git a/reclass/storage/node.sls b/reclass/storage/node.sls
index 0678b6d..d34ff9c 100644
--- a/reclass/storage/node.sls
+++ b/reclass/storage/node.sls
@@ -18,6 +18,22 @@
{%- for node_name, node in storage.get('node', {}).iteritems() %}
{%- if node.repeat is defined %}
+
+ {%- if node.repeat.ip_ranges is defined %}
+ {%- set ip_ranges = {} %}
+ {%- for ip_range_name, ip_range in node.repeat.ip_ranges.iteritems() %}
+ {%- set ip_list = salt['netutils.parse_ip_ranges'](ip_range, node.repeat.count) %}
+ {%- do ip_ranges.update({ip_range_name: ip_list}) %}
+ {%- endfor %}
+ {%- endif %}
+ {%- if node.repeat.network_ranges is defined %}
+ {%- set network_ranges = {} %}
+ {%- for network_range_name, network_range in node.repeat.network_ranges.iteritems() %}
+ {%- set ip_list = salt['netutils.parse_network_ranges'](network_range, iterate=True) %}
+ {%- do network_ranges.update({network_range_name: ip_list}) %}
+ {%- endfor %}
+ {%- endif %}
+
{%- for i in range(node.repeat.count) %}
{%- set extra_params = {} %}
@@ -25,9 +41,13 @@
{%- set param_count = (param.get('start', 1) + i)|string %}
{%- set param_value = {'value': param.value|replace(storage.repeat_count_replace_symbol, param_count.rjust(param.get('digits', 1), '0'))} %}
{%- if node.repeat.ip_ranges is defined %}
- {%- for range_name, range in node.repeat.ip_ranges.iteritems() %}
- {%- set ip_list = salt['netutils.parse_network_ranges'](range, node.repeat.count) %}
- {%- do param_value.update({'value': param_value['value']|replace('<<' + range_name + '>>', ip_list[i])}) %}
+ {%- for ip_range_name, ip_range in node.repeat.ip_ranges.iteritems() %}
+ {%- do param_value.update({'value': param_value['value']|replace('<<' + ip_range_name + '>>', ip_ranges[ip_range_name][i])}) %}
+ {%- endfor %}
+ {%- endif %}
+ {%- if node.repeat.network_ranges is defined %}
+ {%- for network_range_name, network_range in node.repeat.network_ranges.iteritems() %}
+ {% do param_value.update({'value': param_value['value']|replace('<<' + network_range_name + '>>', network_ranges[network_range_name][i])}) %}
{%- endfor %}
{%- endif %}
{%- do extra_params.update({param_name: {'value': param_value['value'], 'interpolate': param.get('interpolate', False)}}) %}
diff --git a/tests/pillar/generate_multi.sls b/tests/pillar/generate_multi.sls
index dfaffd2..ee7c049 100644
--- a/tests/pillar/generate_multi.sls
+++ b/tests/pillar/generate_multi.sls
@@ -13,17 +13,18 @@
ip_ranges:
single_address: '172.16.10.101-172.16.10.254'
deploy_address: '172.16.20.101-172.16.20.254'
+ network_ranges:
+ sriov_address: '172.16.10.1/24-172.16.100.1/24'
count: 2
start: 5
digits: 2
params:
single_address:
value: <<single_address>>
- start: 100
deploy_address:
value: <<deploy_address>>
- start: 5
- digits: 3
+ sriov_address:
+ value: <<sriov_address>>
params:
salt_master_host: <<salt-master-ip>>
linux_system_codename: trusty
diff --git a/tests/pillar/generate_multi_interpolate.sls b/tests/pillar/generate_multi_interpolate.sls
index abc15ae..71fefc8 100644
--- a/tests/pillar/generate_multi_interpolate.sls
+++ b/tests/pillar/generate_multi_interpolate.sls
@@ -11,15 +11,16 @@
repeat:
ip_ranges:
single_address: '172.16.10.101-172.16.10.254'
+ network_ranges:
+ sriov_address: '172.16.10.1/24-172.16.100.1/24'
count: 2
start: 5
digits: 2
params:
single_address:
value: <<single_address>>
- start: 1
- digits: 2
- interpolate: true
+ sriov_address:
+ value: <<sriov_address>>
params:
salt_master_host: <<salt-master-ip>>
linux_system_codename: trusty