Revision 4445f97a snf-cyclades-app/synnefo/api/subnets.py

b/snf-cyclades-app/synnefo/api/subnets.py
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:

Also available in: Unified diff