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 -*-
|
||||
|
||||
import json
|
||||
|
||||
import web
|
||||
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 helpers.vlan import VlanManager
|
||||
|
||||
|
||||
def check_client_content_type(handler):
|
||||
@ -179,34 +179,36 @@ class ClusterCollectionHandler(JSONHandler):
|
||||
web.ctx.orm.add(cluster)
|
||||
web.ctx.orm.commit()
|
||||
|
||||
network_objects = web.ctx.orm.query(Network)
|
||||
for network in release.networks_metadata:
|
||||
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
|
||||
used_nets = [n.cidr for n in web.ctx.orm.query(Network).all()]
|
||||
used_vlans = [v.id for v in web.ctx.orm.query(Vlan).all()]
|
||||
|
||||
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,
|
||||
name=network['name'],
|
||||
access=network['access'],
|
||||
network=str(new_network),
|
||||
gateway=str(new_network[1]),
|
||||
range_l=str(new_network[3]),
|
||||
range_h=str(new_network[-1]),
|
||||
vlan_id=VlanManager.generate_id(network['name'])
|
||||
cidr=str(new_net),
|
||||
gateway=str(new_net[1]),
|
||||
vlan=vlan_db.id
|
||||
)
|
||||
web.ctx.orm.add(nw)
|
||||
web.ctx.orm.add(nw_db)
|
||||
web.ctx.orm.commit()
|
||||
|
||||
used_vlans.append(new_vlan)
|
||||
used_nets.append(str(new_net))
|
||||
|
||||
raise web.webapi.created(json.dumps(
|
||||
ClusterHandler.render(cluster),
|
||||
indent=4
|
||||
|
@ -1,7 +1,6 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
import web
|
||||
import ipaddr
|
||||
from sqlalchemy import Column, UniqueConstraint, Table
|
||||
from sqlalchemy import Integer, String, Unicode, Boolean, ForeignKey, Enum
|
||||
from sqlalchemy import create_engine
|
||||
@ -196,26 +195,22 @@ class IPAddr(Base):
|
||||
ip_addr = Column(String(25))
|
||||
|
||||
|
||||
class Vlan(Base, BasicValidator):
|
||||
__tablename__ = 'vlan'
|
||||
id = Column(Integer, primary_key=True)
|
||||
network = relationship("Network")
|
||||
|
||||
|
||||
class Network(Base, BasicValidator):
|
||||
__tablename__ = 'networks'
|
||||
id = Column(Integer, primary_key=True)
|
||||
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)
|
||||
vlan_id = Column(Integer)
|
||||
network = Column(String(25), nullable=False)
|
||||
range_l = Column(String(25))
|
||||
range_h = Column(String(25))
|
||||
vlan = Column(Integer, ForeignKey('vlan.id'))
|
||||
cidr = Column(String(25), nullable=False)
|
||||
gateway = Column(String(25))
|
||||
nodes = relationship(
|
||||
"Node",
|
||||
secondary=IPAddr.__table__,
|
||||
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 -*-
|
||||
import json
|
||||
from paste.fixture import TestApp
|
||||
|
||||
from api.models import Release, Network
|
||||
from base import BaseHandlers
|
||||
from base import reverse
|
||||
|
||||
@ -38,5 +40,80 @@ class TestHandlers(BaseHandlers):
|
||||
)
|
||||
self.assertEquals(201, resp.status)
|
||||
|
||||
#def test_if_cluster_creates_correct_networks(self):
|
||||
#pass
|
||||
def test_if_cluster_creates_correct_networks(self):
|
||||
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