Statistics
| Branch: | Tag: | Revision:

root / snf-cyclades-app / synnefo / logic / subnets.py @ 4e3789fd

History | View | Annotate | Download (11.1 kB)

1 9eb0710b Dionysis Grigoropoulos
# Copyright 2013 GRNET S.A. All rights reserved.
2 9eb0710b Dionysis Grigoropoulos
#
3 9eb0710b Dionysis Grigoropoulos
# Redistribution and use in source and binary forms, with or
4 9eb0710b Dionysis Grigoropoulos
# without modification, are permitted provided that the following
5 9eb0710b Dionysis Grigoropoulos
# conditions are met:
6 9eb0710b Dionysis Grigoropoulos
#
7 9eb0710b Dionysis Grigoropoulos
#   1. Redistributions of source code must retain the above
8 9eb0710b Dionysis Grigoropoulos
#      copyright notice, this list of conditions and the following
9 9eb0710b Dionysis Grigoropoulos
#      disclaimer.
10 9eb0710b Dionysis Grigoropoulos
#
11 9eb0710b Dionysis Grigoropoulos
#   2. Redistributions in binary form must reproduce the above
12 9eb0710b Dionysis Grigoropoulos
#      copyright notice, this list of conditions and the following
13 9eb0710b Dionysis Grigoropoulos
#      disclaimer in the documentation and/or other materials
14 9eb0710b Dionysis Grigoropoulos
#      provided with the distribution.
15 9eb0710b Dionysis Grigoropoulos
#
16 9eb0710b Dionysis Grigoropoulos
# THIS SOFTWARE IS PROVIDED BY GRNET S.A. ``AS IS'' AND ANY EXPRESS
17 9eb0710b Dionysis Grigoropoulos
# OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 9eb0710b Dionysis Grigoropoulos
# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
19 9eb0710b Dionysis Grigoropoulos
# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL GRNET S.A OR
20 9eb0710b Dionysis Grigoropoulos
# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
21 9eb0710b Dionysis Grigoropoulos
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
22 9eb0710b Dionysis Grigoropoulos
# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
23 9eb0710b Dionysis Grigoropoulos
# USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
24 9eb0710b Dionysis Grigoropoulos
# AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
25 9eb0710b Dionysis Grigoropoulos
# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
26 9eb0710b Dionysis Grigoropoulos
# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
27 9eb0710b Dionysis Grigoropoulos
# POSSIBILITY OF SUCH DAMAGE.
28 9eb0710b Dionysis Grigoropoulos
#
29 9eb0710b Dionysis Grigoropoulos
# The views and conclusions contained in the software and
30 9eb0710b Dionysis Grigoropoulos
# documentation are those of the authors and should not be
31 9eb0710b Dionysis Grigoropoulos
# interpreted as representing official policies, either expressed
32 9eb0710b Dionysis Grigoropoulos
# or implied, of GRNET S.A.
33 9eb0710b Dionysis Grigoropoulos
34 f82dfec6 Christos Stavrakakis
import ipaddr
35 9eb0710b Dionysis Grigoropoulos
from logging import getLogger
36 f82dfec6 Christos Stavrakakis
from functools import wraps
37 f82dfec6 Christos Stavrakakis
38 f82dfec6 Christos Stavrakakis
from django.conf import settings
39 f82dfec6 Christos Stavrakakis
from django.db import transaction
40 3549cb2f Dionysis Grigoropoulos
from django.db.models import Q
41 3549cb2f Dionysis Grigoropoulos
42 9eb0710b Dionysis Grigoropoulos
from snf_django.lib import api
43 9eb0710b Dionysis Grigoropoulos
from snf_django.lib.api import faults
44 ba6ad346 Dionysis Grigoropoulos
from synnefo.logic import utils
45 01def7a4 Dionysis Grigoropoulos
from synnefo.api import util
46 9eb0710b Dionysis Grigoropoulos
47 9eb0710b Dionysis Grigoropoulos
from synnefo.db.models import Subnet, Network, IPPoolTable
48 9eb0710b Dionysis Grigoropoulos
49 9eb0710b Dionysis Grigoropoulos
log = getLogger(__name__)
50 9eb0710b Dionysis Grigoropoulos
51 9eb0710b Dionysis Grigoropoulos
52 9eb0710b Dionysis Grigoropoulos
def subnet_command(action):
53 9eb0710b Dionysis Grigoropoulos
    def decorator(func):
54 9eb0710b Dionysis Grigoropoulos
        @wraps(func)
55 9eb0710b Dionysis Grigoropoulos
        @transaction.commit_on_success()
56 9eb0710b Dionysis Grigoropoulos
        def wrapper(subnet, *args, **kwargs):
57 9eb0710b Dionysis Grigoropoulos
            return func(subnet, *args, **kwargs)
58 9eb0710b Dionysis Grigoropoulos
        return wrapper
59 9eb0710b Dionysis Grigoropoulos
    return decorator
60 9eb0710b Dionysis Grigoropoulos
61 9eb0710b Dionysis Grigoropoulos
62 9eb0710b Dionysis Grigoropoulos
def list_subnets(user_id):
63 9eb0710b Dionysis Grigoropoulos
    """List all subnets of a user"""
64 3549cb2f Dionysis Grigoropoulos
    log.debug('list_subnets %s', user_id)
65 9eb0710b Dionysis Grigoropoulos
66 91430ce0 Dionysis Grigoropoulos
    query = (((Q(network__userid=user_id) & Q(network__public=False)) |
67 91430ce0 Dionysis Grigoropoulos
              Q(network__public=True)) & Q(deleted=False))
68 91430ce0 Dionysis Grigoropoulos
    user_subnets = Subnet.objects.filter(query)
69 5d83d2ff Dionysis Grigoropoulos
    return user_subnets
70 9eb0710b Dionysis Grigoropoulos
71 9eb0710b Dionysis Grigoropoulos
72 9eb0710b Dionysis Grigoropoulos
@transaction.commit_on_success
73 f82dfec6 Christos Stavrakakis
def create_subnet(*args, **kwargs):
74 f82dfec6 Christos Stavrakakis
    return _create_subnet(*args, **kwargs)
75 f82dfec6 Christos Stavrakakis
76 f82dfec6 Christos Stavrakakis
77 f82dfec6 Christos Stavrakakis
def _create_subnet(network_id, user_id, cidr, name, ipversion=4, gateway=None,
78 b7311f3d Dionysis Grigoropoulos
                   dhcp=True, slaac=True, dns_nameservers=None,
79 f82dfec6 Christos Stavrakakis
                   allocation_pools=None, host_routes=None):
80 316787ab Dionysis Grigoropoulos
    """Create a subnet
81 f82dfec6 Christos Stavrakakis

82 9eb0710b Dionysis Grigoropoulos
    network_id and the desired cidr are mandatory, everything else is optional
83 316787ab Dionysis Grigoropoulos

84 9eb0710b Dionysis Grigoropoulos
    """
85 9eb0710b Dionysis Grigoropoulos
    try:
86 4e3789fd Christos Stavrakakis
        network = Network.objects.select_for_update().get(id=network_id)
87 9eb0710b Dionysis Grigoropoulos
    except Network.DoesNotExist:
88 b7311f3d Dionysis Grigoropoulos
        raise api.faults.ItemNotFound("No network found with that id")
89 9eb0710b Dionysis Grigoropoulos
90 784a3f1e Dionysis Grigoropoulos
    if network.deleted:
91 784a3f1e Dionysis Grigoropoulos
        raise api.faults.BadRequest("Network has been deleted")
92 784a3f1e Dionysis Grigoropoulos
93 5d83d2ff Dionysis Grigoropoulos
    if user_id != network.userid:
94 5d83d2ff Dionysis Grigoropoulos
        raise api.faults.Unauthorized("Unauthorized operation")
95 5d83d2ff Dionysis Grigoropoulos
96 9eb0710b Dionysis Grigoropoulos
    if ipversion not in [4, 6]:
97 9eb0710b Dionysis Grigoropoulos
        raise api.faults.BadRequest("Malformed IP version type")
98 9eb0710b Dionysis Grigoropoulos
99 99718617 Dionysis Grigoropoulos
    check_number_of_subnets(network, ipversion)
100 99718617 Dionysis Grigoropoulos
101 1709a768 Dionysis Grigoropoulos
    if network.backend_networks.exists():
102 1709a768 Dionysis Grigoropoulos
        raise api.faults.BadRequest("Cannot create subnet in network %s, VMs"
103 1709a768 Dionysis Grigoropoulos
                                    " are already connected to this network" %
104 1709a768 Dionysis Grigoropoulos
                                    network_id)
105 1709a768 Dionysis Grigoropoulos
106 99718617 Dionysis Grigoropoulos
    try:
107 f82dfec6 Christos Stavrakakis
        cidr_ip = ipaddr.IPNetwork(cidr)
108 99718617 Dionysis Grigoropoulos
    except ValueError:
109 99718617 Dionysis Grigoropoulos
        raise api.faults.BadRequest("Malformed CIDR")
110 5d83d2ff Dionysis Grigoropoulos
111 9eb0710b Dionysis Grigoropoulos
    if ipversion == 6:
112 f23fbacf Christos Stavrakakis
        validate_subnet_params(subnet6=cidr, gateway6=gateway)
113 9eb0710b Dionysis Grigoropoulos
    else:
114 f23fbacf Christos Stavrakakis
        validate_subnet_params(subnet=cidr, gateway=gateway)
115 9eb0710b Dionysis Grigoropoulos
116 624f0d07 Dionysis Grigoropoulos
    utils.check_name_length(name, Subnet.SUBNET_NAME_LENGTH, "Subnet "
117 624f0d07 Dionysis Grigoropoulos
                            "name is too long")
118 9eb0710b Dionysis Grigoropoulos
    sub = Subnet.objects.create(name=name, network=network, cidr=cidr,
119 9eb0710b Dionysis Grigoropoulos
                                ipversion=ipversion, gateway=gateway,
120 bdedfd9d Christos Stavrakakis
                                userid=network.userid, public=network.public,
121 5d83d2ff Dionysis Grigoropoulos
                                dhcp=dhcp, host_routes=host_routes,
122 5d83d2ff Dionysis Grigoropoulos
                                dns_nameservers=dns_nameservers)
123 9eb0710b Dionysis Grigoropoulos
124 4e3789fd Christos Stavrakakis
    network.subnet_ids.append(sub.id)
125 4e3789fd Christos Stavrakakis
    network.save()
126 4e3789fd Christos Stavrakakis
127 b7311f3d Dionysis Grigoropoulos
    gateway_ip = ipaddr.IPAddress(gateway) if gateway else None
128 b7311f3d Dionysis Grigoropoulos
129 9eb0710b Dionysis Grigoropoulos
    if allocation_pools is not None:
130 9eb0710b Dionysis Grigoropoulos
        if ipversion == 6:
131 9eb0710b Dionysis Grigoropoulos
            raise api.faults.Conflict("Can't allocate an IP Pool in IPv6")
132 f23fbacf Christos Stavrakakis
    elif ipversion == 4:
133 eb5f7eb0 Dionysis Grigoropoulos
        # Check if the gateway is the first IP of the subnet, or the last. In
134 eb5f7eb0 Dionysis Grigoropoulos
        # that case create a single ip pool.
135 b7311f3d Dionysis Grigoropoulos
        if gateway_ip:
136 b7311f3d Dionysis Grigoropoulos
            if int(gateway_ip) - int(cidr_ip) == 1:
137 f23fbacf Christos Stavrakakis
                allocation_pools = [(gateway_ip + 1, cidr_ip.broadcast - 1)]
138 eb5f7eb0 Dionysis Grigoropoulos
            elif int(cidr_ip.broadcast) - int(gateway_ip) == 1:
139 eb5f7eb0 Dionysis Grigoropoulos
                allocation_pools = [(cidr_ip.network + 1, gateway_ip - 1)]
140 b7311f3d Dionysis Grigoropoulos
            else:
141 b7311f3d Dionysis Grigoropoulos
                # If the gateway isn't the first available ip, create two
142 b7311f3d Dionysis Grigoropoulos
                # different ip pools adjacent to said ip
143 f23fbacf Christos Stavrakakis
                allocation_pools = [(cidr_ip.network + 1, gateway_ip - 1),
144 f23fbacf Christos Stavrakakis
                                    (gateway_ip + 1, cidr_ip.broadcast - 1)]
145 9eb0710b Dionysis Grigoropoulos
        else:
146 f23fbacf Christos Stavrakakis
            allocation_pools = [(cidr_ip.network + 1, cidr_ip.broadcast - 1)]
147 9eb0710b Dionysis Grigoropoulos
148 5d83d2ff Dionysis Grigoropoulos
    if allocation_pools:
149 f23fbacf Christos Stavrakakis
        # Validate the allocation pools
150 f23fbacf Christos Stavrakakis
        validate_pools(allocation_pools, cidr_ip, gateway_ip)
151 5d83d2ff Dionysis Grigoropoulos
        create_ip_pools(allocation_pools, cidr_ip, sub)
152 9eb0710b Dionysis Grigoropoulos
153 9eb0710b Dionysis Grigoropoulos
    return sub
154 9eb0710b Dionysis Grigoropoulos
155 9eb0710b Dionysis Grigoropoulos
156 01def7a4 Dionysis Grigoropoulos
def get_subnet(subnet_id, user_id, for_update=False):
157 01def7a4 Dionysis Grigoropoulos
    """Return a Subnet instance or raise ItemNotFound."""
158 01def7a4 Dionysis Grigoropoulos
159 9eb0710b Dionysis Grigoropoulos
    try:
160 01def7a4 Dionysis Grigoropoulos
        objects = Subnet.objects
161 01def7a4 Dionysis Grigoropoulos
        subnet_id = int(subnet_id)
162 bdedfd9d Christos Stavrakakis
        return objects.get(Q(userid=user_id) | Q(public=True),
163 bdedfd9d Christos Stavrakakis
                           id=subnet_id)
164 01def7a4 Dionysis Grigoropoulos
    except (ValueError, TypeError):
165 01def7a4 Dionysis Grigoropoulos
        raise faults.BadRequest("Invalid subnet ID '%s'" % subnet_id)
166 9eb0710b Dionysis Grigoropoulos
    except Subnet.DoesNotExist:
167 01def7a4 Dionysis Grigoropoulos
        raise faults.ItemNotFound("Subnet '%s' not found." % subnet_id)
168 9eb0710b Dionysis Grigoropoulos
169 9eb0710b Dionysis Grigoropoulos
170 9eb0710b Dionysis Grigoropoulos
def delete_subnet():
171 316787ab Dionysis Grigoropoulos
    """Delete a subnet, raises BadRequest
172 9eb0710b Dionysis Grigoropoulos
    A subnet is deleted ONLY when the network that it belongs to is deleted
173 316787ab Dionysis Grigoropoulos

174 9eb0710b Dionysis Grigoropoulos
    """
175 9eb0710b Dionysis Grigoropoulos
    raise api.faults.BadRequest("Deletion of a subnet is not supported")
176 9eb0710b Dionysis Grigoropoulos
177 9eb0710b Dionysis Grigoropoulos
178 9eb0710b Dionysis Grigoropoulos
@transaction.commit_on_success
179 8646e606 Dionysis Grigoropoulos
def update_subnet(sub_id, name, user_id):
180 316787ab Dionysis Grigoropoulos
    """Update the fields of a subnet
181 9eb0710b Dionysis Grigoropoulos
    Only the name can be updated
182 316787ab Dionysis Grigoropoulos

183 9eb0710b Dionysis Grigoropoulos
    """
184 5d83d2ff Dionysis Grigoropoulos
    log.info('Update subnet %s, name %s' % (sub_id, name))
185 9eb0710b Dionysis Grigoropoulos
186 9eb0710b Dionysis Grigoropoulos
    try:
187 9eb0710b Dionysis Grigoropoulos
        subnet = Subnet.objects.get(id=sub_id)
188 9eb0710b Dionysis Grigoropoulos
    except:
189 9eb0710b Dionysis Grigoropoulos
        raise api.faults.ItemNotFound("Subnet not found")
190 9eb0710b Dionysis Grigoropoulos
191 8646e606 Dionysis Grigoropoulos
    if user_id != subnet.network.userid:
192 8646e606 Dionysis Grigoropoulos
        raise api.faults.Unauthorized("Unauthorized operation")
193 8646e606 Dionysis Grigoropoulos
194 ba6ad346 Dionysis Grigoropoulos
    utils.check_name_length(name, Subnet.SUBNET_NAME_LENGTH, "Subnet name is "
195 ba6ad346 Dionysis Grigoropoulos
                            " too long")
196 9eb0710b Dionysis Grigoropoulos
197 9eb0710b Dionysis Grigoropoulos
    subnet.name = name
198 9eb0710b Dionysis Grigoropoulos
    subnet.save()
199 9eb0710b Dionysis Grigoropoulos
200 9eb0710b Dionysis Grigoropoulos
    return subnet
201 9eb0710b Dionysis Grigoropoulos
202 9eb0710b Dionysis Grigoropoulos
203 9eb0710b Dionysis Grigoropoulos
#Utility functions
204 9eb0710b Dionysis Grigoropoulos
def create_ip_pools(pools, cidr, subnet):
205 9eb0710b Dionysis Grigoropoulos
    """Create IP Pools in the database"""
206 f23fbacf Christos Stavrakakis
    return [_create_ip_pool(pool, cidr, subnet) for pool in pools]
207 f23fbacf Christos Stavrakakis
208 f23fbacf Christos Stavrakakis
209 f23fbacf Christos Stavrakakis
def _create_ip_pool(pool, cidr, subnet):
210 f23fbacf Christos Stavrakakis
    size = int(pool[1]) - int(pool[0]) + 1
211 f23fbacf Christos Stavrakakis
    base = str(cidr)
212 f23fbacf Christos Stavrakakis
    offset = int(pool[0]) - int(cidr.network)
213 f23fbacf Christos Stavrakakis
    return IPPoolTable.objects.create(size=size, offset=offset,
214 f23fbacf Christos Stavrakakis
                                      base=base, subnet=subnet)
215 9eb0710b Dionysis Grigoropoulos
216 9eb0710b Dionysis Grigoropoulos
217 9eb0710b Dionysis Grigoropoulos
def check_number_of_subnets(network, version):
218 9eb0710b Dionysis Grigoropoulos
    """Check if a user can add a subnet in a network"""
219 9eb0710b Dionysis Grigoropoulos
    if network.subnets.filter(ipversion=version):
220 9eb0710b Dionysis Grigoropoulos
        raise api.faults.BadRequest("Only one subnet of IPv4/IPv6 per "
221 9eb0710b Dionysis Grigoropoulos
                                    "network is allowed")
222 9eb0710b Dionysis Grigoropoulos
223 9eb0710b Dionysis Grigoropoulos
224 f23fbacf Christos Stavrakakis
def validate_pools(pool_list, cidr, gateway):
225 316787ab Dionysis Grigoropoulos
    """Validate IP Pools
226 316787ab Dionysis Grigoropoulos

227 9eb0710b Dionysis Grigoropoulos
    Validate the given IP pools are inside the cidr range
228 9eb0710b Dionysis Grigoropoulos
    Validate there are no overlaps in the given pools
229 9eb0710b Dionysis Grigoropoulos
    Finally, validate the gateway isn't in the given ip pools
230 9eb0710b Dionysis Grigoropoulos
    Input must be a list containing a sublist with start/end ranges as
231 9eb0710b Dionysis Grigoropoulos
    ipaddr.IPAddress items eg.,
232 9eb0710b Dionysis Grigoropoulos
    [[IPv4Address('192.168.42.11'), IPv4Address('192.168.42.15')],
233 9eb0710b Dionysis Grigoropoulos
     [IPv4Address('192.168.42.30'), IPv4Address('192.168.42.60')]]
234 316787ab Dionysis Grigoropoulos

235 9eb0710b Dionysis Grigoropoulos
    """
236 9eb0710b Dionysis Grigoropoulos
    if pool_list[0][0] <= cidr.network:
237 9eb0710b Dionysis Grigoropoulos
        raise api.faults.Conflict("IP Pool out of bounds")
238 9eb0710b Dionysis Grigoropoulos
    elif pool_list[-1][1] >= cidr.broadcast:
239 9eb0710b Dionysis Grigoropoulos
        raise api.faults.Conflict("IP Pool out of bounds")
240 9eb0710b Dionysis Grigoropoulos
241 9eb0710b Dionysis Grigoropoulos
    for start, end in pool_list:
242 9eb0710b Dionysis Grigoropoulos
        if start > end:
243 9eb0710b Dionysis Grigoropoulos
            raise api.faults.Conflict("Invalid IP pool range")
244 9eb0710b Dionysis Grigoropoulos
        # Raise BadRequest if gateway is inside the pool range
245 b7311f3d Dionysis Grigoropoulos
        if gateway:
246 b7311f3d Dionysis Grigoropoulos
            if not (gateway < start or gateway > end):
247 b7311f3d Dionysis Grigoropoulos
                raise api.faults.Conflict("Gateway cannot be in pool range")
248 9eb0710b Dionysis Grigoropoulos
249 eb5f7eb0 Dionysis Grigoropoulos
    # Check if there is a conflict between the IP Pool ranges
250 9eb0710b Dionysis Grigoropoulos
    end = cidr.network
251 9eb0710b Dionysis Grigoropoulos
    for pool in pool_list:
252 9eb0710b Dionysis Grigoropoulos
        if end >= pool[0]:
253 9eb0710b Dionysis Grigoropoulos
            raise api.faults.Conflict("IP Pool range conflict")
254 9eb0710b Dionysis Grigoropoulos
        end = pool[1]
255 f82dfec6 Christos Stavrakakis
256 f82dfec6 Christos Stavrakakis
257 f82dfec6 Christos Stavrakakis
def validate_subnet_params(subnet=None, gateway=None, subnet6=None,
258 f82dfec6 Christos Stavrakakis
                           gateway6=None):
259 f82dfec6 Christos Stavrakakis
    if subnet:
260 f82dfec6 Christos Stavrakakis
        try:
261 f82dfec6 Christos Stavrakakis
            # Use strict option to not all subnets with host bits set
262 f82dfec6 Christos Stavrakakis
            network = ipaddr.IPv4Network(subnet, strict=True)
263 f82dfec6 Christos Stavrakakis
        except ValueError:
264 f82dfec6 Christos Stavrakakis
            raise faults.BadRequest("Invalid network IPv4 subnet")
265 f82dfec6 Christos Stavrakakis
266 f82dfec6 Christos Stavrakakis
        # Check that network size is allowed!
267 f82dfec6 Christos Stavrakakis
        prefixlen = network.prefixlen
268 f82dfec6 Christos Stavrakakis
        if prefixlen > 29 or prefixlen <= settings.MAX_CIDR_BLOCK:
269 f82dfec6 Christos Stavrakakis
            raise faults.OverLimit(
270 f82dfec6 Christos Stavrakakis
                message="Unsupported network size",
271 f82dfec6 Christos Stavrakakis
                details="Netmask must be in range: (%s, 29]" %
272 f82dfec6 Christos Stavrakakis
                settings.MAX_CIDR_BLOCK)
273 f82dfec6 Christos Stavrakakis
        if gateway:  # Check that gateway belongs to network
274 f82dfec6 Christos Stavrakakis
            try:
275 f82dfec6 Christos Stavrakakis
                gateway = ipaddr.IPv4Address(gateway)
276 f82dfec6 Christos Stavrakakis
            except ValueError:
277 f82dfec6 Christos Stavrakakis
                raise faults.BadRequest("Invalid network IPv4 gateway")
278 f82dfec6 Christos Stavrakakis
            if not gateway in network:
279 f82dfec6 Christos Stavrakakis
                raise faults.BadRequest("Invalid network IPv4 gateway")
280 f82dfec6 Christos Stavrakakis
281 f82dfec6 Christos Stavrakakis
    if subnet6:
282 f82dfec6 Christos Stavrakakis
        try:
283 f82dfec6 Christos Stavrakakis
            # Use strict option to not all subnets with host bits set
284 f82dfec6 Christos Stavrakakis
            network6 = ipaddr.IPv6Network(subnet6, strict=True)
285 f82dfec6 Christos Stavrakakis
        except ValueError:
286 f82dfec6 Christos Stavrakakis
            raise faults.BadRequest("Invalid network IPv6 subnet")
287 f82dfec6 Christos Stavrakakis
        # Check that network6 is an /64 subnet, because this is imposed by
288 f82dfec6 Christos Stavrakakis
        # 'mac2eui64' utiity.
289 f82dfec6 Christos Stavrakakis
        if network6.prefixlen != 64:
290 f82dfec6 Christos Stavrakakis
            msg = ("Unsupported IPv6 subnet size. Network netmask must be"
291 f82dfec6 Christos Stavrakakis
                   " /64")
292 f82dfec6 Christos Stavrakakis
            raise faults.BadRequest(msg)
293 f82dfec6 Christos Stavrakakis
        if gateway6:
294 f82dfec6 Christos Stavrakakis
            try:
295 f82dfec6 Christos Stavrakakis
                gateway6 = ipaddr.IPv6Address(gateway6)
296 f82dfec6 Christos Stavrakakis
            except ValueError:
297 f82dfec6 Christos Stavrakakis
                raise faults.BadRequest("Invalid network IPv6 gateway")
298 f82dfec6 Christos Stavrakakis
            if not gateway6 in network6:
299 f82dfec6 Christos Stavrakakis
                raise faults.BadRequest("Invalid network IPv6 gateway")
300 0d1f9117 Dionysis Grigoropoulos
301 0d1f9117 Dionysis Grigoropoulos
302 0d1f9117 Dionysis Grigoropoulos
def parse_allocation_pools(allocation_pools):
303 0d1f9117 Dionysis Grigoropoulos
    alloc = list()
304 0d1f9117 Dionysis Grigoropoulos
    for pool in allocation_pools:
305 0d1f9117 Dionysis Grigoropoulos
        try:
306 0d1f9117 Dionysis Grigoropoulos
            start, end = pool.split(',')
307 0d1f9117 Dionysis Grigoropoulos
            alloc.append([ipaddr.IPv4Address(start),
308 0d1f9117 Dionysis Grigoropoulos
                          ipaddr.IPv4Address(end)])
309 0d1f9117 Dionysis Grigoropoulos
        except ValueError:
310 44bd008a Dionysis Grigoropoulos
            raise faults.BadRequest("Malformed IPv4 address")
311 0d1f9117 Dionysis Grigoropoulos
312 0d1f9117 Dionysis Grigoropoulos
    return alloc