Skip to content
GitLab
Menu
Projects
Groups
Snippets
Loading...
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
Menu
Open sidebar
itminedu
synnefo
Commits
1461fb74
Commit
1461fb74
authored
Oct 15, 2013
by
Dionysis Grigoropoulos
Browse files
cyclades: Fully support ip pools in subnets
parent
99bb30d5
Changes
3
Hide whitespace changes
Inline
Side-by-side
snf-cyclades-app/synnefo/api/subnets.py
View file @
1461fb74
...
...
@@ -40,7 +40,7 @@ from django.http import HttpResponse
from
django.utils
import
simplejson
as
json
from
snf_django.lib.api
import
utils
from
synnefo.db.models
import
Subnet
,
Network
from
synnefo.db.models
import
Subnet
,
Network
,
IPPoolTable
from
synnefo.logic
import
networks
from
ipaddr
import
IPv4Network
,
IPv6Network
,
IPv4Address
,
IPAddress
,
IPNetwork
...
...
@@ -148,24 +148,33 @@ def create_subnet(request):
allocation_pools
=
subnet
.
get
(
'allocation_pools'
,
None
)
if
allocation_pools
:
# FIX ME
sub
=
Subnet
.
objects
.
create
(
name
=
name
,
network
=
network
,
cidr
=
cidr
,
ipversion
=
ipversion
,
gateway
=
gateway
,
dhcp
=
dhcp
,
host_routes
=
hosts
,
dns_nameservers
=
dns
)
pool_list
=
list
()
if
allocation_pools
is
not
None
:
# If the user specified IP allocation pools, validate them and use them
if
ipversion
==
6
:
raise
api
.
faults
.
Conflict
(
"Can't allocate an IP Pool in IPv6"
)
pools
=
parse_ip_pools
(
allocation_pools
)
validate_subpools
(
pools
,
cidr_ip
,
gateway_ip
)
else
:
# FIX ME
pass
pool_list
=
string_to_ipaddr
(
pools
)
validate_subpools
(
pool_list
,
cidr_ip
,
gateway_ip
)
if
allocation_pools
is
None
and
ipversion
==
4
:
# Check if the gateway is the first IP of the subnet, in this case
# create a single ip pool
if
int
(
gateway_ip
)
-
int
(
cidr_ip
)
==
1
:
pool_list
=
[[
gateway_ip
+
1
,
cidr_ip
.
broadcast
-
1
]]
else
:
# If the gateway isn't the first available ip, create two different
# ip pools adjacent to said ip
pool_list
.
append
([
cidr_ip
.
network
+
1
,
gateway_ip
-
1
])
pool_list
.
append
([
gateway_ip
+
1
,
cidr_ip
.
broadcast
-
1
])
# FIX ME
try
:
sub
=
Subnet
.
objects
.
create
(
name
=
name
,
network
=
network
,
cidr
=
cidr
,
ipversion
=
ipversion
,
gateway
=
gateway
,
dhcp
=
dhcp
,
host_routes
=
hosts
,
dns_nameservers
=
dns
)
except
:
raise
return
"Error"
if
pool_list
:
create_ip_pools
(
pool_list
,
cidr_ip
,
sub
)
subnet_dict
=
subnet_to_dict
(
sub
)
data
=
json
.
dumps
({
'subnet'
:
subnet_dict
})
...
...
@@ -246,7 +255,15 @@ def subnet_to_dict(subnet):
"""Returns a dictionary containing the info of a subnet"""
dns
=
check_empty_lists
(
subnet
.
dns_nameservers
)
hosts
=
check_empty_lists
(
subnet
.
host_routes
)
#allocation_pools =
allocation_pools
=
subnet
.
ip_pools
.
all
()
pools
=
list
()
if
allocation_pools
:
for
pool
in
allocation_pools
:
cidr
=
IPNetwork
(
pool
.
base
)
start
=
str
(
cidr
.
network
+
pool
.
offset
)
end
=
str
(
cidr
.
network
+
pool
.
offset
+
pool
.
size
-
1
)
pools
.
append
([{
"start"
:
start
,
"end"
:
end
}])
dictionary
=
dict
({
'id'
:
str
(
subnet
.
id
),
'network_id'
:
str
(
subnet
.
network
.
id
),
...
...
@@ -259,7 +276,7 @@ def subnet_to_dict(subnet):
'enable_dhcp'
:
subnet
.
dhcp
,
'dns_nameservers'
:
dns
,
'host_routes'
:
hosts
,
'allocation_pools'
:
[]})
'allocation_pools'
:
pools
if
pools
is
not
None
else
[]})
if
subnet
.
ipversion
==
6
:
dictionary
[
'slac'
]
=
subnet
.
dhcp
...
...
@@ -267,6 +284,31 @@ def subnet_to_dict(subnet):
return
dictionary
def
string_to_ipaddr
(
pools
):
"""
Convert [["192.168.42.1", "192.168.42.15"],
["192.168.42.30", "192.168.42.60"]]
to
[[IPv4Address('192.168.42.1'), IPv4Address('192.168.42.15')],
[IPv4Address('192.168.42.30'), IPv4Address('192.168.42.60')]]
and sort the output
"""
pool_list
=
[(
map
(
lambda
ip_str
:
IPAddress
(
ip_str
),
pool
))
for
pool
in
pools
]
pool_list
.
sort
()
return
pool_list
def
create_ip_pools
(
pools
,
cidr
,
subnet
):
"""Placeholder"""
for
pool
in
pools
:
size
=
int
(
pool
[
1
])
-
int
(
pool
[
0
])
+
1
base
=
str
(
cidr
)
offset
=
int
(
pool
[
0
])
-
int
(
cidr
.
network
)
ip_pool
=
IPPoolTable
.
objects
.
create
(
size
=
size
,
offset
=
offset
,
base
=
base
,
subnet
=
subnet
)
def
check_empty_lists
(
value
):
"""Check if value is Null/None, in which case we return an empty list"""
if
value
is
None
:
...
...
@@ -338,18 +380,16 @@ def parse_ip_pools(pools):
return
pool_list
def
validate_subpools
(
pool
s
,
cidr
,
gateway
):
def
validate_subpools
(
pool
_list
,
cidr
,
gateway
):
"""
Validate the given IP pools are inside the cidr range
Validate there are no overlaps in the given pools
Finally, validate the gateway isn't in the given ip pools
Input must be a list containing a sublist with start/end ranges as strings
[["192.168.42.1", "192.168.42.15"], ["192.168.42.30", "192.168.42.60"]]
Input must be a list containing a sublist with start/end ranges as
ipaddr.IPAddress items eg.,
[[IPv4Address('192.168.42.11'), IPv4Address('192.168.42.15')],
[IPv4Address('192.168.42.30'), IPv4Address('192.168.42.60')]]
"""
pool_list
=
[(
map
(
lambda
ip_str
:
IPAddress
(
ip_str
),
pool
))
for
pool
in
pools
]
pool_list
.
sort
()
if
pool_list
[
0
][
0
]
<=
cidr
.
network
:
raise
api
.
faults
.
Conflict
(
"IP Pool out of bounds"
)
elif
pool_list
[
-
1
][
1
]
>=
cidr
.
broadcast
:
...
...
snf-cyclades-app/synnefo/db/models_factory.py
View file @
1461fb74
...
...
@@ -188,7 +188,6 @@ class NetworkInterfaceFactory(factory.DjangoModelFactory):
class
IPPoolTableFactory
(
factory
.
DjangoModelFactory
):
FACTORY_FOR
=
models
.
IPPoolTable
size
=
0
class
SubnetFactory
(
factory
.
DjangoModelFactory
):
...
...
@@ -204,7 +203,8 @@ class IPv4SubnetFactory(SubnetFactory):
ipversion
=
4
cidr
=
factory
.
Sequence
(
lambda
n
:
'192.168.{0}.0/24'
.
format
(
n
))
gateway
=
factory
.
LazyAttribute
(
lambda
a
:
a
.
cidr
[:
-
4
]
+
'1'
)
pool
=
factory
.
RelatedFactory
(
IPPoolTableFactory
,
'subnet'
)
pool
=
factory
.
RelatedFactory
(
IPPoolTableFactory
,
'subnet'
,
base
=
cidr
,
offset
=
10
,
size
=
5
)
class
IPv6SubnetFactory
(
SubnetFactory
):
...
...
snf-cyclades-app/synnefo/db/pools/__init__.py
View file @
1461fb74
...
...
@@ -271,11 +271,7 @@ class IPPool(PoolManager):
do_init
=
False
if
pool_table
.
available_map
else
True
subnet
=
pool_table
.
subnet
self
.
net
=
ipaddr
.
IPNetwork
(
subnet
.
cidr
)
if
not
pool_table
.
size
:
pool_table
.
size
=
self
.
net
.
numhosts
super
(
IPPool
,
self
).
__init__
(
pool_table
)
gateway
=
subnet
.
gateway
self
.
gateway
=
gateway
and
ipaddr
.
IPAddress
(
gateway
)
or
None
if
do_init
:
self
.
_reserve
(
0
,
external
=
True
)
if
gateway
:
...
...
@@ -292,3 +288,9 @@ class IPPool(PoolManager):
def
contains
(
self
,
address
):
addr
=
ipaddr
.
IPAddress
(
address
)
return
addr
in
self
.
net
def
return_start
(
self
):
return
str
(
ipaddr
.
IPAddress
(
self
.
base
)
+
self
.
offset
)
def
return_end
(
self
):
return
str
(
ipaddr
.
IPAddress
(
self
.
base
)
+
self
.
offset
+
self
.
size
-
1
)
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment