Create Networks based on release information on cluster create
This commit is contained in:
parent
c195bb5d68
commit
b368559018
@ -1,12 +1,12 @@
|
|||||||
# -*- coding: utf-8 -*-
|
# -*- coding: utf-8 -*-
|
||||||
|
|
||||||
import json
|
import json
|
||||||
|
|
||||||
import web
|
import web
|
||||||
import ipaddr
|
import ipaddr
|
||||||
from models import Release, Cluster, Node, Role, Network
|
import netaddr
|
||||||
|
|
||||||
|
from models import Release, Cluster, Node, Role, Network, Vlan
|
||||||
from settings import settings
|
from settings import settings
|
||||||
from helpers.vlan import VlanManager
|
|
||||||
|
|
||||||
|
|
||||||
def check_client_content_type(handler):
|
def check_client_content_type(handler):
|
||||||
@ -179,34 +179,36 @@ class ClusterCollectionHandler(JSONHandler):
|
|||||||
web.ctx.orm.add(cluster)
|
web.ctx.orm.add(cluster)
|
||||||
web.ctx.orm.commit()
|
web.ctx.orm.commit()
|
||||||
|
|
||||||
network_objects = web.ctx.orm.query(Network)
|
used_nets = [n.cidr for n in web.ctx.orm.query(Network).all()]
|
||||||
for network in release.networks_metadata:
|
used_vlans = [v.id for v in web.ctx.orm.query(Vlan).all()]
|
||||||
for nw_pool in settings.NETWORK_POOLS[network['access']]:
|
|
||||||
nw_ip = ipaddr.IPv4Network(nw_pool)
|
|
||||||
new_network = None
|
|
||||||
for net in nw_ip.iter_subnets(new_prefix=24):
|
|
||||||
nw_exist = network_objects.filter(
|
|
||||||
Network.network == str(net)
|
|
||||||
).first()
|
|
||||||
if not nw_exist:
|
|
||||||
new_network = net
|
|
||||||
break
|
|
||||||
if new_network:
|
|
||||||
break
|
|
||||||
|
|
||||||
nw = Network(
|
for network in release.networks_metadata:
|
||||||
|
new_vlan = sorted(list(set(settings.VLANS) - set(used_vlans)))[0]
|
||||||
|
vlan_db = Vlan(id=new_vlan)
|
||||||
|
web.ctx.orm.add(vlan_db)
|
||||||
|
|
||||||
|
pool = settings.NETWORK_POOLS[network['access']]
|
||||||
|
nets_free_set = netaddr.IPSet(pool) -\
|
||||||
|
netaddr.IPSet(settings.NET_EXCLUDE) -\
|
||||||
|
netaddr.IPSet(used_nets)
|
||||||
|
|
||||||
|
free_cidrs = sorted(list(nets_free_set._cidrs))
|
||||||
|
new_net = list(free_cidrs[0].subnet(24, count=1))[0]
|
||||||
|
|
||||||
|
nw_db = Network(
|
||||||
release=release.id,
|
release=release.id,
|
||||||
name=network['name'],
|
name=network['name'],
|
||||||
access=network['access'],
|
access=network['access'],
|
||||||
network=str(new_network),
|
cidr=str(new_net),
|
||||||
gateway=str(new_network[1]),
|
gateway=str(new_net[1]),
|
||||||
range_l=str(new_network[3]),
|
vlan=vlan_db.id
|
||||||
range_h=str(new_network[-1]),
|
|
||||||
vlan_id=VlanManager.generate_id(network['name'])
|
|
||||||
)
|
)
|
||||||
web.ctx.orm.add(nw)
|
web.ctx.orm.add(nw_db)
|
||||||
web.ctx.orm.commit()
|
web.ctx.orm.commit()
|
||||||
|
|
||||||
|
used_vlans.append(new_vlan)
|
||||||
|
used_nets.append(str(new_net))
|
||||||
|
|
||||||
raise web.webapi.created(json.dumps(
|
raise web.webapi.created(json.dumps(
|
||||||
ClusterHandler.render(cluster),
|
ClusterHandler.render(cluster),
|
||||||
indent=4
|
indent=4
|
||||||
|
@ -1,7 +1,6 @@
|
|||||||
# -*- coding: utf-8 -*-
|
# -*- coding: utf-8 -*-
|
||||||
|
|
||||||
import web
|
import web
|
||||||
import ipaddr
|
|
||||||
from sqlalchemy import Column, UniqueConstraint, Table
|
from sqlalchemy import Column, UniqueConstraint, Table
|
||||||
from sqlalchemy import Integer, String, Unicode, Boolean, ForeignKey, Enum
|
from sqlalchemy import Integer, String, Unicode, Boolean, ForeignKey, Enum
|
||||||
from sqlalchemy import create_engine
|
from sqlalchemy import create_engine
|
||||||
@ -196,26 +195,22 @@ class IPAddr(Base):
|
|||||||
ip_addr = Column(String(25))
|
ip_addr = Column(String(25))
|
||||||
|
|
||||||
|
|
||||||
|
class Vlan(Base, BasicValidator):
|
||||||
|
__tablename__ = 'vlan'
|
||||||
|
id = Column(Integer, primary_key=True)
|
||||||
|
network = relationship("Network")
|
||||||
|
|
||||||
|
|
||||||
class Network(Base, BasicValidator):
|
class Network(Base, BasicValidator):
|
||||||
__tablename__ = 'networks'
|
__tablename__ = 'networks'
|
||||||
id = Column(Integer, primary_key=True)
|
id = Column(Integer, primary_key=True)
|
||||||
release = Column(Integer, ForeignKey('releases.id'), nullable=False)
|
release = Column(Integer, ForeignKey('releases.id'), nullable=False)
|
||||||
name = Column(Unicode(20), nullable=False)
|
name = Column(Unicode(100), nullable=False)
|
||||||
access = Column(String(20), nullable=False)
|
access = Column(String(20), nullable=False)
|
||||||
vlan_id = Column(Integer)
|
vlan = Column(Integer, ForeignKey('vlan.id'))
|
||||||
network = Column(String(25), nullable=False)
|
cidr = Column(String(25), nullable=False)
|
||||||
range_l = Column(String(25))
|
|
||||||
range_h = Column(String(25))
|
|
||||||
gateway = Column(String(25))
|
gateway = Column(String(25))
|
||||||
nodes = relationship(
|
nodes = relationship(
|
||||||
"Node",
|
"Node",
|
||||||
secondary=IPAddr.__table__,
|
secondary=IPAddr.__table__,
|
||||||
backref="networks")
|
backref="networks")
|
||||||
|
|
||||||
@property
|
|
||||||
def netmask(self):
|
|
||||||
return str(ipaddr.IPv4Network(self.network).netmask)
|
|
||||||
|
|
||||||
@property
|
|
||||||
def broadcast(self):
|
|
||||||
return str(ipaddr.IPv4Network(self.network).broadcast)
|
|
||||||
|
@ -1,18 +0,0 @@
|
|||||||
# -*- coding: utf-8 -*-
|
|
||||||
|
|
||||||
|
|
||||||
class VlanManager(object):
|
|
||||||
"""
|
|
||||||
A stub for some real logic in the future
|
|
||||||
"""
|
|
||||||
vlan_ids = {
|
|
||||||
'storage': 200,
|
|
||||||
'public': 300,
|
|
||||||
'floating': 400,
|
|
||||||
'fixed': 500,
|
|
||||||
'admin': 100
|
|
||||||
}
|
|
||||||
|
|
||||||
@classmethod
|
|
||||||
def generate_id(cls, name):
|
|
||||||
return cls.vlan_ids[name]
|
|
@ -1,6 +1,8 @@
|
|||||||
# -*- coding: utf-8 -*-
|
# -*- coding: utf-8 -*-
|
||||||
import json
|
import json
|
||||||
from paste.fixture import TestApp
|
from paste.fixture import TestApp
|
||||||
|
|
||||||
|
from api.models import Release, Network
|
||||||
from base import BaseHandlers
|
from base import BaseHandlers
|
||||||
from base import reverse
|
from base import reverse
|
||||||
|
|
||||||
@ -38,5 +40,80 @@ class TestHandlers(BaseHandlers):
|
|||||||
)
|
)
|
||||||
self.assertEquals(201, resp.status)
|
self.assertEquals(201, resp.status)
|
||||||
|
|
||||||
#def test_if_cluster_creates_correct_networks(self):
|
def test_if_cluster_creates_correct_networks(self):
|
||||||
#pass
|
release = Release()
|
||||||
|
release.version = "1.1.1"
|
||||||
|
release.name = u"release_name_" + str(release.version)
|
||||||
|
release.description = u"release_desc" + str(release.version)
|
||||||
|
release.networks_metadata = [
|
||||||
|
{"name": "floating", "access": "public"},
|
||||||
|
{"name": "fixed", "access": "private10"},
|
||||||
|
{"name": "storage", "access": "private192"},
|
||||||
|
{"name": "management", "access": "private172"},
|
||||||
|
{"name": "other_172", "access": "private172"},
|
||||||
|
]
|
||||||
|
self.db.add(release)
|
||||||
|
self.db.commit()
|
||||||
|
resp = self.app.post(
|
||||||
|
reverse('ClusterCollectionHandler'),
|
||||||
|
json.dumps({
|
||||||
|
'name': 'cluster-name',
|
||||||
|
'release': release.id,
|
||||||
|
}),
|
||||||
|
headers=self.default_headers
|
||||||
|
)
|
||||||
|
self.assertEquals(201, resp.status)
|
||||||
|
nets = self.db.query(Network).all()
|
||||||
|
obtained = []
|
||||||
|
for net in nets:
|
||||||
|
obtained.append({
|
||||||
|
'release': net.release,
|
||||||
|
'name': net.name,
|
||||||
|
'access': net.access,
|
||||||
|
'vlan': net.vlan,
|
||||||
|
'cidr': net.cidr,
|
||||||
|
'gateway': net.gateway
|
||||||
|
})
|
||||||
|
expected = [
|
||||||
|
{
|
||||||
|
'release': release.id,
|
||||||
|
'name': u'floating',
|
||||||
|
'access': 'public',
|
||||||
|
'vlan': 100,
|
||||||
|
'cidr': '240.0.0.0/24',
|
||||||
|
'gateway': '240.0.0.1'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
'release': release.id,
|
||||||
|
'name': u'fixed',
|
||||||
|
'access': 'private10',
|
||||||
|
'vlan': 101,
|
||||||
|
'cidr': '10.0.0.0/24',
|
||||||
|
'gateway': '10.0.0.1'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
'release': release.id,
|
||||||
|
'name': u'storage',
|
||||||
|
'access': 'private192',
|
||||||
|
'vlan': 102,
|
||||||
|
'cidr': '192.168.0.0/24',
|
||||||
|
'gateway': '192.168.0.1'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
'release': release.id,
|
||||||
|
'name': u'management',
|
||||||
|
'access': 'private172',
|
||||||
|
'vlan': 103,
|
||||||
|
'cidr': '172.16.0.0/24',
|
||||||
|
'gateway': '172.16.0.1'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
'release': release.id,
|
||||||
|
'name': u'other_172',
|
||||||
|
'access': 'private172',
|
||||||
|
'vlan': 104,
|
||||||
|
'cidr': '172.16.1.0/24',
|
||||||
|
'gateway': '172.16.1.1'
|
||||||
|
},
|
||||||
|
]
|
||||||
|
self.assertEquals(expected, obtained)
|
||||||
|
Loading…
Reference in New Issue
Block a user