Revision 210e5933 snf-cyclades-app/synnefo/api/subnets.py
b/snf-cyclades-app/synnefo/api/subnets.py | ||
---|---|---|
39 | 39 |
from django.utils import simplejson as json |
40 | 40 |
|
41 | 41 |
from snf_django.lib.api import utils |
42 |
from synnefo.db.models import Subnet |
|
42 |
#from synnefo.db.models import Subnet
|
|
43 | 43 |
from synnefo.logic import subnets |
44 | 44 |
from synnefo.api import util |
45 | 45 |
|
... | ... | |
102 | 102 |
except KeyError: |
103 | 103 |
raise api.faults.BadRequest("Malformed request") |
104 | 104 |
|
105 |
allocation_pools = subnet.get('allocation_pools', None) |
|
106 |
if allocation_pools is not None: |
|
107 |
pool = parse_ip_pools(allocation_pools) |
|
108 |
allocation_pools = string_to_ipaddr(pool) |
|
109 |
|
|
110 | 105 |
name = subnet.get('name', None) |
111 | 106 |
ipversion = subnet.get('ip_version', 4) |
112 | 107 |
|
113 |
# If no gateway is specified, send an empty string, because None is used |
|
114 |
# if the user wants no gateway at all |
|
115 |
gateway = subnet.get('gateway_ip', "") |
|
108 |
allocation_pools = subnet.get('allocation_pools', None) |
|
109 |
if allocation_pools is not None: |
|
110 |
allocation_pools = parse_ip_pools(allocation_pools) |
|
111 |
|
|
116 | 112 |
try: |
117 | 113 |
cidr_ip = ipaddr.IPNetwork(cidr) |
118 | 114 |
except ValueError: |
119 |
raise api.faults.BadRequest("Malformed CIDR") |
|
120 |
potential_gateway = str(ipaddr.IPNetwork(cidr).network + 1) |
|
115 |
raise api.faults.BadRequest("Malformed CIDR '%s'" % cidr) |
|
121 | 116 |
|
117 |
# If no gateway is specified, send an empty string, because None is used |
|
118 |
# if the user wants no gateway at all |
|
119 |
gateway = subnet.get('gateway_ip', "") |
|
122 | 120 |
if gateway is "": |
123 |
gateway = potential_gateway
|
|
121 |
gateway = str(cidr_ip.network + 1)
|
|
124 | 122 |
|
125 | 123 |
dhcp = subnet.get('enable_dhcp', True) |
126 | 124 |
slaac = subnet.get('enable_slaac', None) |
... | ... | |
206 | 204 |
"""Returns a dictionary containing the info of a subnet""" |
207 | 205 |
dns = check_empty_lists(subnet.dns_nameservers) |
208 | 206 |
hosts = check_empty_lists(subnet.host_routes) |
209 |
allocation_pools = subnet.ip_pools.all() |
|
210 |
pools = list() |
|
211 |
|
|
212 |
if allocation_pools: |
|
213 |
for pool in allocation_pools: |
|
214 |
cidr = ipaddr.IPNetwork(pool.base) |
|
215 |
start = str(cidr.network + pool.offset) |
|
216 |
end = str(cidr.network + pool.offset + pool.size - 1) |
|
217 |
pools.append({"start": start, "end": end}) |
|
218 |
|
|
219 |
dictionary = dict({'id': str(subnet.id), |
|
220 |
'network_id': str(subnet.network.id), |
|
221 |
'name': subnet.name if subnet.name is not None else "", |
|
222 |
'tenant_id': subnet.network.userid, |
|
223 |
'user_id': subnet.network.userid, |
|
224 |
'gateway_ip': subnet.gateway, |
|
225 |
'ip_version': subnet.ipversion, |
|
226 |
'cidr': subnet.cidr, |
|
227 |
'enable_dhcp': subnet.dhcp, |
|
228 |
'dns_nameservers': dns, |
|
229 |
'host_routes': hosts, |
|
230 |
'allocation_pools': pools if pools is not None else []}) |
|
207 |
|
|
208 |
allocation_pools = [render_ip_pool(pool) |
|
209 |
for pool in subnet.ip_pools.all()] |
|
210 |
|
|
211 |
network = subnet.network |
|
212 |
d = {'id': str(subnet.id), |
|
213 |
'network_id': str(network.id), |
|
214 |
'name': subnet.name if subnet.name is not None else "", |
|
215 |
'tenant_id': network.userid, |
|
216 |
'user_id': network.userid, |
|
217 |
'gateway_ip': subnet.gateway, |
|
218 |
'ip_version': subnet.ipversion, |
|
219 |
'cidr': subnet.cidr, |
|
220 |
'enable_dhcp': subnet.dhcp, |
|
221 |
'dns_nameservers': dns, |
|
222 |
'host_routes': hosts, |
|
223 |
'allocation_pools': allocation_pools} |
|
231 | 224 |
|
232 | 225 |
if subnet.ipversion == 6: |
233 |
dictionary['enable_slaac'] = subnet.dhcp |
|
226 |
d['enable_slaac'] = subnet.dhcp |
|
227 |
|
|
228 |
d['links'] = util.subnet_to_links(subnet.id) |
|
234 | 229 |
|
235 |
dictionary['links'] = util.subnet_to_links(subnet.id) |
|
236 |
return dictionary |
|
230 |
return d |
|
237 | 231 |
|
238 | 232 |
|
239 |
def string_to_ipaddr(pools): |
|
240 |
"""Convert [["192.168.42.1", "192.168.42.15"], |
|
241 |
["192.168.42.30", "192.168.42.60"]] |
|
233 |
def render_ip_pool(pool): |
|
234 |
network = ipaddr.IPNetwork(pool.base).network |
|
235 |
start = str(network + pool.offset) |
|
236 |
end = str(network + pool.offset + pool.size - 1) |
|
237 |
return {"start": start, "end": end} |
|
238 |
|
|
239 |
|
|
240 |
def parse_ip_pools(pools): |
|
241 |
"""Convert [{'start': '192.168.42.1', 'end': '192.168.42.15'}, |
|
242 |
{'start': '192.168.42.30', 'end': '192.168.42.60'}] |
|
242 | 243 |
to |
243 |
[[IPv4Address('192.168.42.1'), IPv4Address('192.168.42.15')], |
|
244 |
[IPv4Address('192.168.42.30'), IPv4Address('192.168.42.60')]] |
|
245 |
and sort the output |
|
244 |
[(IPv4Address("192.168.42.1"), IPv4Address("192.168.42.15")), |
|
245 |
(IPv4Address("192.168.42.30"), IPv4Address("192.168.42.60"))] |
|
246 | 246 |
|
247 | 247 |
""" |
248 |
pool_list = [(map(lambda ip_str: ipaddr.IPAddress(ip_str), pool)) |
|
249 |
for pool in pools] |
|
250 |
pool_list.sort() |
|
251 |
return pool_list |
|
248 |
try: |
|
249 |
return sorted([(ipaddr.IPv4Address(p["start"]), |
|
250 |
ipaddr.IPv4Address(p["end"])) for p in pools]) |
|
251 |
except KeyError: |
|
252 |
raise api.faults.BadRequest("Malformed allocation pool.") |
|
253 |
except ipaddr.AddressValueError: |
|
254 |
raise api.faults.BadRequest("Allocation pools contain invalid IPv4" |
|
255 |
" address") |
|
252 | 256 |
|
253 | 257 |
|
254 | 258 |
def check_empty_lists(value): |
... | ... | |
258 | 262 |
return value |
259 | 263 |
|
260 | 264 |
|
261 |
def check_name_length(name): |
|
262 |
"""Check if the length of a name is within acceptable value""" |
|
263 |
if len(str(name)) > Subnet.SUBNET_NAME_LENGTH: |
|
264 |
raise api.faults.BadRequest("Subnet name too long") |
|
265 |
return name |
|
266 |
|
|
267 |
|
|
268 |
def get_subnet_fromdb(subnet_id, user_id, for_update=False): |
|
269 |
"""Return a Subnet instance or raise ItemNotFound. |
|
270 |
This is the same as util.get_network |
|
271 |
|
|
272 |
""" |
|
273 |
try: |
|
274 |
subnet_id = int(subnet_id) |
|
275 |
if for_update: |
|
276 |
return Subnet.objects.select_for_update().get(id=subnet_id, |
|
277 |
network__userid= |
|
278 |
user_id) |
|
279 |
return Subnet.objects.get(id=subnet_id, network__userid=user_id) |
|
280 |
except (ValueError, Subnet.DoesNotExist): |
|
281 |
raise api.faults.ItemNotFound('Subnet not found') |
|
282 |
|
|
283 |
|
|
284 |
def parse_ip_pools(pools): |
|
285 |
"""Convert [{'start': '192.168.42.1', 'end': '192.168.42.15'}, |
|
286 |
{'start': '192.168.42.30', 'end': '192.168.42.60'}] |
|
287 |
to |
|
288 |
[["192.168.42.1", "192.168.42.15"], |
|
289 |
["192.168.42.30", "192.168.42.60"]] |
|
290 |
|
|
291 |
""" |
|
292 |
pool_list = list() |
|
293 |
for pool in pools: |
|
294 |
parse = [pool["start"], pool["end"]] |
|
295 |
pool_list.append(parse) |
|
296 |
return pool_list |
|
297 |
|
|
298 |
|
|
299 | 265 |
def check_boolean_value(value, key): |
300 | 266 |
"""Check if dhcp value is in acceptable values""" |
301 | 267 |
if value not in [True, False]: |
Also available in: Unified diff