40 |
40 |
from django.utils import simplejson as json
|
41 |
41 |
|
42 |
42 |
from snf_django.lib.api import utils
|
43 |
|
from synnefo.db.models import Subnet, Network
|
|
43 |
from synnefo.db.models import Subnet, Network, IPPoolTable
|
44 |
44 |
from synnefo.logic import networks
|
45 |
45 |
|
46 |
46 |
from ipaddr import IPv4Network, IPv6Network, IPv4Address, IPAddress, IPNetwork
|
... | ... | |
148 |
148 |
|
149 |
149 |
allocation_pools = subnet.get('allocation_pools', None)
|
150 |
150 |
|
151 |
|
if allocation_pools:
|
|
151 |
# FIX ME
|
|
152 |
sub = Subnet.objects.create(name=name, network=network, cidr=cidr,
|
|
153 |
ipversion=ipversion, gateway=gateway,
|
|
154 |
dhcp=dhcp, host_routes=hosts,
|
|
155 |
dns_nameservers=dns)
|
|
156 |
|
|
157 |
pool_list = list()
|
|
158 |
if allocation_pools is not None:
|
|
159 |
# If the user specified IP allocation pools, validate them and use them
|
152 |
160 |
if ipversion == 6:
|
153 |
161 |
raise api.faults.Conflict("Can't allocate an IP Pool in IPv6")
|
154 |
162 |
pools = parse_ip_pools(allocation_pools)
|
155 |
|
validate_subpools(pools, cidr_ip, gateway_ip)
|
156 |
|
else:
|
157 |
|
# FIX ME
|
158 |
|
pass
|
|
163 |
pool_list = string_to_ipaddr(pools)
|
|
164 |
validate_subpools(pool_list, cidr_ip, gateway_ip)
|
|
165 |
if allocation_pools is None and ipversion == 4:
|
|
166 |
# Check if the gateway is the first IP of the subnet, in this case
|
|
167 |
# create a single ip pool
|
|
168 |
if int(gateway_ip) - int(cidr_ip) == 1:
|
|
169 |
pool_list = [[gateway_ip + 1, cidr_ip.broadcast - 1]]
|
|
170 |
else:
|
|
171 |
# If the gateway isn't the first available ip, create two different
|
|
172 |
# ip pools adjacent to said ip
|
|
173 |
pool_list.append([cidr_ip.network + 1, gateway_ip - 1])
|
|
174 |
pool_list.append([gateway_ip + 1, cidr_ip.broadcast - 1])
|
159 |
175 |
|
160 |
|
# FIX ME
|
161 |
|
try:
|
162 |
|
sub = Subnet.objects.create(name=name, network=network, cidr=cidr,
|
163 |
|
ipversion=ipversion, gateway=gateway,
|
164 |
|
dhcp=dhcp, host_routes=hosts,
|
165 |
|
dns_nameservers=dns)
|
166 |
|
except:
|
167 |
|
raise
|
168 |
|
return "Error"
|
|
176 |
if pool_list:
|
|
177 |
create_ip_pools(pool_list, cidr_ip, sub)
|
169 |
178 |
|
170 |
179 |
subnet_dict = subnet_to_dict(sub)
|
171 |
180 |
data = json.dumps({'subnet': subnet_dict})
|
... | ... | |
246 |
255 |
"""Returns a dictionary containing the info of a subnet"""
|
247 |
256 |
dns = check_empty_lists(subnet.dns_nameservers)
|
248 |
257 |
hosts = check_empty_lists(subnet.host_routes)
|
249 |
|
#allocation_pools =
|
|
258 |
allocation_pools = subnet.ip_pools.all()
|
|
259 |
pools = list()
|
|
260 |
|
|
261 |
if allocation_pools:
|
|
262 |
for pool in allocation_pools:
|
|
263 |
cidr = IPNetwork(pool.base)
|
|
264 |
start = str(cidr.network + pool.offset)
|
|
265 |
end = str(cidr.network + pool.offset + pool.size - 1)
|
|
266 |
pools.append([{"start": start, "end": end}])
|
250 |
267 |
|
251 |
268 |
dictionary = dict({'id': str(subnet.id),
|
252 |
269 |
'network_id': str(subnet.network.id),
|
... | ... | |
259 |
276 |
'enable_dhcp': subnet.dhcp,
|
260 |
277 |
'dns_nameservers': dns,
|
261 |
278 |
'host_routes': hosts,
|
262 |
|
'allocation_pools': []})
|
|
279 |
'allocation_pools': pools if pools is not None else []})
|
263 |
280 |
|
264 |
281 |
if subnet.ipversion == 6:
|
265 |
282 |
dictionary['slac'] = subnet.dhcp
|
... | ... | |
267 |
284 |
return dictionary
|
268 |
285 |
|
269 |
286 |
|
|
287 |
def string_to_ipaddr(pools):
|
|
288 |
"""
|
|
289 |
Convert [["192.168.42.1", "192.168.42.15"],
|
|
290 |
["192.168.42.30", "192.168.42.60"]]
|
|
291 |
to
|
|
292 |
[[IPv4Address('192.168.42.1'), IPv4Address('192.168.42.15')],
|
|
293 |
[IPv4Address('192.168.42.30'), IPv4Address('192.168.42.60')]]
|
|
294 |
and sort the output
|
|
295 |
"""
|
|
296 |
pool_list = [(map(lambda ip_str: IPAddress(ip_str), pool))
|
|
297 |
for pool in pools]
|
|
298 |
pool_list.sort()
|
|
299 |
return pool_list
|
|
300 |
|
|
301 |
|
|
302 |
def create_ip_pools(pools, cidr, subnet):
|
|
303 |
"""Placeholder"""
|
|
304 |
for pool in pools:
|
|
305 |
size = int(pool[1]) - int(pool[0]) + 1
|
|
306 |
base = str(cidr)
|
|
307 |
offset = int(pool[0]) - int(cidr.network)
|
|
308 |
ip_pool = IPPoolTable.objects.create(size=size, offset=offset,
|
|
309 |
base=base, subnet=subnet)
|
|
310 |
|
|
311 |
|
270 |
312 |
def check_empty_lists(value):
|
271 |
313 |
"""Check if value is Null/None, in which case we return an empty list"""
|
272 |
314 |
if value is None:
|
... | ... | |
338 |
380 |
return pool_list
|
339 |
381 |
|
340 |
382 |
|
341 |
|
def validate_subpools(pools, cidr, gateway):
|
|
383 |
def validate_subpools(pool_list, cidr, gateway):
|
342 |
384 |
"""
|
343 |
385 |
Validate the given IP pools are inside the cidr range
|
344 |
386 |
Validate there are no overlaps in the given pools
|
345 |
387 |
Finally, validate the gateway isn't in the given ip pools
|
346 |
|
Input must be a list containing a sublist with start/end ranges as strings
|
347 |
|
[["192.168.42.1", "192.168.42.15"], ["192.168.42.30", "192.168.42.60"]]
|
|
388 |
Input must be a list containing a sublist with start/end ranges as
|
|
389 |
ipaddr.IPAddress items eg.,
|
|
390 |
[[IPv4Address('192.168.42.11'), IPv4Address('192.168.42.15')],
|
|
391 |
[IPv4Address('192.168.42.30'), IPv4Address('192.168.42.60')]]
|
348 |
392 |
"""
|
349 |
|
pool_list = [(map(lambda ip_str: IPAddress(ip_str), pool))
|
350 |
|
for pool in pools]
|
351 |
|
pool_list.sort()
|
352 |
|
|
353 |
393 |
if pool_list[0][0] <= cidr.network:
|
354 |
394 |
raise api.faults.Conflict("IP Pool out of bounds")
|
355 |
395 |
elif pool_list[-1][1] >= cidr.broadcast:
|