Two thread will be launched, with normal and administrative permissions.
'''
-__author__="Alfonso Tierno"
+__author__="Alfonso Tierno, Gerardo Garcia, Leonardo Mirabal"
__date__ ="$10-jul-2014 12:07:15$"
import bottle
import hashlib
import os
import imp
+from netaddr import IPNetwork, IPAddress, all_matching_cidrs
#import only if needed because not needed in test mode. To allow an easier installation import RADclass
from jsonschema import validate as js_v, exceptions as js_e
import host_thread as ht
hash_md5.update(chunk)
return hash_md5.hexdigest()
+def md5_string(fname):
+ hash_md5 = hashlib.md5()
+ hash_md5.update(fname)
+ return hash_md5.hexdigest()
+
def check_extended(extended, allow_net_attach=False):
'''Makes and extra checking of extended input that cannot be done using jsonschema
Attributes:
@bottle.route(url_base + '/hosts', method='GET')
def http_get_hosts():
- select_,where_,limit_ = filter_query_string(bottle.request.query, http2db_host,
- ('id','name','description','status','admin_state_up') )
+ return format_out(get_hosts())
+
+
+def get_hosts():
+ select_, where_, limit_ = filter_query_string(bottle.request.query, http2db_host,
+ ('id', 'name', 'description', 'status', 'admin_state_up', 'ip_name'))
myself = config_dic['http_threads'][ threading.current_thread().name ]
result, content = myself.db.get_table(FROM='hosts', SELECT=select_, WHERE=where_, LIMIT=limit_)
for row in content:
row['links'] = ( {'href': myself.url_preffix + '/hosts/' + str(row['id']), 'rel': 'bookmark'}, )
data={'hosts' : content}
- return format_out(data)
+ return data
@bottle.route(url_base + '/hosts/<host_id>', method='GET')
def http_get_host_id(host_id):
thread.start()
config_dic['host_threads'][ content['uuid'] ] = thread
+ if config_dic['network_type'] == 'ovs':
+ # create bridge
+ create_dhcp_ovs_bridge()
+ config_dic['host_threads'][content['uuid']].insert_task("new-ovsbridge")
+ # check if more host exist
+ create_vxlan_mesh(content['uuid'])
+
#return host data
change_keys_http2db(content, http2db_host, reverse=True)
if len(warning_text)>0:
bottle.abort(HTTP_Bad_Request, content)
return
+
+def get_dhcp_controller():
+ """
+ Create an host_thread object for manage openvim controller and not create a thread for itself
+ :return: dhcp_host openvim controller object
+ """
+
+ if 'openvim_controller' in config_dic['host_threads']:
+ return config_dic['host_threads']['openvim_controller']
+
+ bridge_ifaces = []
+ controller_ip = config_dic['ovs_controller_ip']
+ ovs_controller_user = config_dic['ovs_controller_user']
+
+ host_test_mode = True if config_dic['mode'] == 'test' or config_dic['mode'] == "OF only" else False
+ host_develop_mode = True if config_dic['mode'] == 'development' else False
+
+ dhcp_host = ht.host_thread(name='openvim_controller', user=ovs_controller_user, host=controller_ip, db=config_dic['db'],
+ db_lock=config_dic['db_lock'], test=host_test_mode,
+ image_path=config_dic['image_path'], version=config_dic['version'],
+ host_id='openvim_controller', develop_mode=host_develop_mode,
+ develop_bridge_iface=bridge_ifaces)
+
+ config_dic['host_threads']['openvim_controller'] = dhcp_host
+ dhcp_host.ssh_connect()
+ return dhcp_host
+
+
+def delete_dhcp_ovs_bridge(vlan, net_uuid):
+ """
+ Delete bridges and port created during dhcp launching at openvim controller
+ :param vlan: net vlan id
+ :param net_uuid: network identifier
+ :return:
+ """
+ dhcp_path = config_dic['ovs_controller_file_path']
+
+ controller_host = get_dhcp_controller()
+ controller_host.delete_dhcp_port(vlan, net_uuid)
+ controller_host.delete_dhcp_server(vlan, net_uuid, dhcp_path)
+
+
+def create_dhcp_ovs_bridge():
+ """
+ Initialize bridge to allocate the dhcp server at openvim controller
+ :return:
+ """
+ controller_host = get_dhcp_controller()
+ controller_host.create_ovs_bridge()
+
+
+def set_mac_dhcp(vm_ip, vlan, first_ip, last_ip, cidr, mac):
+ """"
+ Launch a dhcpserver base on dnsmasq attached to the net base on vlan id across the the openvim computes
+ :param vm_ip: IP address asigned to a VM
+ :param vlan: Segmentation id
+ :param first_ip: First dhcp range ip
+ :param last_ip: Last dhcp range ip
+ :param cidr: net cidr
+ :param mac: VM vnic mac to be macthed with the IP received
+ """
+ if not vm_ip:
+ return
+ ip_tools = IPNetwork(cidr)
+ cidr_len = ip_tools.prefixlen
+ dhcp_netmask = str(ip_tools.netmask)
+ dhcp_path = config_dic['ovs_controller_file_path']
+
+ new_cidr = [first_ip + '/' + str(cidr_len)]
+ if not len(all_matching_cidrs(vm_ip, new_cidr)):
+ vm_ip = None
+
+ controller_host = get_dhcp_controller()
+ controller_host.set_mac_dhcp_server(vm_ip, mac, vlan, dhcp_netmask, dhcp_path)
+
+
+def delete_mac_dhcp(vm_ip, vlan, mac):
+ """
+ Delete into dhcp conf file the ip assigned to a specific MAC address
+ :param vm_ip: IP address asigned to a VM
+ :param vlan: Segmentation id
+ :param mac: VM vnic mac to be macthed with the IP received
+ :return:
+ """
+
+ dhcp_path = config_dic['ovs_controller_file_path']
+
+ controller_host = get_dhcp_controller()
+ controller_host.delete_mac_dhcp_server(vm_ip, mac, vlan, dhcp_path)
+
+
+def launch_dhcp_server(vlan, first_ip, last_ip, cidr):
+ """
+ Launch a dhcpserver base on dnsmasq attached to the net base on vlan id across the the openvim computes
+ :param vlan: vlan identifier
+ :param first_ip: First dhcp range ip
+ :param last_ip: Last dhcp range ip
+ :param cidr: net cidr
+ :return:
+ """
+ ip_tools = IPNetwork(cidr)
+ dhcp_netmask = str(ip_tools.netmask)
+ ip_range = [first_ip, last_ip]
+ dhcp_path = config_dic['ovs_controller_file_path']
+
+ controller_host = get_dhcp_controller()
+ controller_host.create_linux_bridge(vlan)
+ controller_host.create_dhcp_interfaces(vlan, first_ip, dhcp_netmask)
+ controller_host.launch_dhcp_server(vlan, ip_range, dhcp_netmask, dhcp_path)
+
+
+def create_vxlan_mesh(host_id):
+ """
+ Create vxlan mesh across all openvimc controller and computes.
+ :param host_id: host identifier
+ :param host_id: host identifier
+ :return:
+ """
+ dhcp_compute_name = get_vxlan_interface("dhcp")
+ existing_hosts = get_hosts()
+ if len(existing_hosts['hosts']) > 0:
+ # vlxan mesh creation between openvim controller and computes
+ computes_available = existing_hosts['hosts']
+ controller_host = get_dhcp_controller()
+ for compute in computes_available:
+ vxlan_interface_name = get_vxlan_interface(compute['id'][:8])
+ config_dic['host_threads'][compute['id']].insert_task("new-vxlan", dhcp_compute_name, controller_host.host)
+ controller_host.create_ovs_vxlan_tunnel(vxlan_interface_name, compute['ip_name'])
+
+ # vlxan mesh creation between openvim computes
+ for count, compute_owner in enumerate(computes_available):
+ for compute in computes_available:
+ if compute_owner['id'] == compute['id']:
+ pass
+ else:
+ vxlan_interface_name = get_vxlan_interface(compute_owner['id'][:8])
+ controller_host.create_ovs_vxlan_tunnel(vxlan_interface_name, compute_owner['ip_name'])
+ config_dic['host_threads'][compute['id']].insert_task("new-vxlan",
+ vxlan_interface_name,
+ compute_owner['ip_name'])
+
+
+def delete_vxlan_mesh(host_id):
+ """
+ Create a task for remove a specific compute of the vlxan mesh
+ :param host_id: host id to be deleted.
+ """
+ existing_hosts = get_hosts()
+ computes_available = existing_hosts['hosts']
+ #
+ vxlan_interface_name = get_vxlan_interface(host_id[:8])
+ controller_host = get_dhcp_controller()
+ controller_host.delete_ovs_vxlan_tunnel(vxlan_interface_name)
+ # remove bridge from openvim controller if no more computes exist
+ if len(existing_hosts):
+ controller_host.delete_ovs_bridge()
+ # Remove vxlan mesh
+ for compute in computes_available:
+ if host_id == compute['id']:
+ pass
+ else:
+ controller_host.delete_ovs_vxlan_tunnel(vxlan_interface_name)
+ config_dic['host_threads'][compute['id']].insert_task("del-vxlan", vxlan_interface_name)
+
+
+def get_vxlan_interface(local_uuid):
+ """
+ Genearte a vxlan interface name
+ :param local_uuid: host id
+ :return: vlxan-8digits
+ """
+ return 'vxlan-' + local_uuid[:8]
+
+
@bottle.route(url_base + '/hosts/<host_id>', method='PUT')
def http_put_host_id(host_id):
'''modify a host into the database. All resources are got and inserted'''
change_keys_http2db(content, http2db_host, reverse=True)
data={'host' : content}
+ if config_dic['network_type'] == 'ovs':
+ delete_vxlan_mesh(host_id)
+ config_dic['host_threads'][host_id].insert_task("del-ovsbridge")
+
#reload thread
config_dic['host_threads'][host_id].name = content.get('name',content['ip_name'])
config_dic['host_threads'][host_id].user = content['user']
config_dic['host_threads'][host_id].host = content['ip_name']
config_dic['host_threads'][host_id].insert_task("reload")
+ if config_dic['network_type'] == 'ovs':
+ # create mesh with new host data
+ config_dic['host_threads'][host_id].insert_task("new-ovsbridge")
+ create_vxlan_mesh(host_id)
+
#print data
return format_out(data)
else:
result, content = my.db.delete_row('hosts', host_id)
if result == 0:
bottle.abort(HTTP_Not_Found, content)
- elif result >0:
- #terminate thread
+ elif result > 0:
+ if config_dic['network_type'] == 'ovs':
+ delete_vxlan_mesh(host_id)
+ # terminate thread
if host_id in config_dic['host_threads']:
+ if config_dic['network_type'] == 'ovs':
+ config_dic['host_threads'][host_id].insert_task("del-ovsbridge")
config_dic['host_threads'][host_id].insert_task("exit")
#return data
data={'result' : content}
bottle.abort(result, content)
#obtain data
select_,where_,limit_ = filter_query_string(bottle.request.query, http2db_image,
- ('id','name','description','path','public') )
+ ('id','name','checksum','description','path','public') )
if tenant_id=='any':
from_ ='images'
+ where_or_ = None
else:
- from_ ='tenants_images inner join images on tenants_images.image_id=images.uuid'
- where_['tenant_id'] = tenant_id
- result, content = my.db.get_table(SELECT=select_, FROM=from_, WHERE=where_, LIMIT=limit_)
+ from_ ='tenants_images right join images on tenants_images.image_id=images.uuid'
+ where_or_ = {'tenant_id': tenant_id, 'public': 'yes'}
+ result, content = my.db.get_table(SELECT=select_, DISTINCT=True, FROM=from_, WHERE=where_, WHERE_OR=where_or_, WHERE_AND_OR="AND", LIMIT=limit_)
if result < 0:
print "http_get_images Error", content
bottle.abort(-result, content)
bottle.abort(result, content)
#obtain data
select_,where_,limit_ = filter_query_string(bottle.request.query, http2db_image,
- ('id','name','description','progress', 'status','path', 'created', 'updated','public') )
+ ('id','name','checksum','description','progress', 'status','path', 'created', 'updated','public') )
if tenant_id=='any':
from_ ='images'
+ where_or_ = None
else:
- from_ ='tenants_images as ti inner join images as i on ti.image_id=i.uuid'
- where_['tenant_id'] = tenant_id
+ from_ ='tenants_images as ti right join images as i on ti.image_id=i.uuid'
+ where_or_ = {'tenant_id': tenant_id, 'public': "yes"}
where_['uuid'] = image_id
- result, content = my.db.get_table(SELECT=select_, FROM=from_, WHERE=where_, LIMIT=limit_)
+ result, content = my.db.get_table(SELECT=select_, DISTINCT=True, FROM=from_, WHERE=where_, WHERE_OR=where_or_, WHERE_AND_OR="AND", LIMIT=limit_)
if result < 0:
print "http_get_images error %d %s" % (result, content)
if metadata_dict is not None:
http_content['image']['metadata'] = json.dumps(metadata_dict)
#calculate checksum
- host_test_mode = True if config_dic['mode']=='test' or config_dic['mode']=="OF only" else False
try:
image_file = http_content['image'].get('path',None)
- if os.path.exists(image_file):
- http_content['image']['checksum'] = md5(image_file)
- elif is_url(image_file):
+ parsed_url = urlparse.urlparse(image_file)
+ if parsed_url.scheme == "" and parsed_url.netloc == "":
+ # The path is a local file
+ if os.path.exists(image_file):
+ http_content['image']['checksum'] = md5(image_file)
+ else:
+ # The path is a URL. Code should be added to download the image and calculate the checksum
+ #http_content['image']['checksum'] = md5(downloaded_image)
pass
+ # Finally, only if we are in test mode and checksum has not been calculated, we calculate it from the path
+ host_test_mode = True if config_dic['mode']=='test' or config_dic['mode']=="OF only" else False
+ if host_test_mode:
+ if 'checksum' not in http_content['image']:
+ http_content['image']['checksum'] = md5_string(image_file)
else:
- if not host_test_mode:
+ # At this point, if the path is a local file and no chechsum has been obtained yet, an error is sent back.
+ # If it is a URL, no error is sent. Checksum will be an empty string
+ if parsed_url.scheme == "" and parsed_url.netloc == "" and 'checksum' not in http_content['image']:
content = "Image file not found"
print "http_post_images error: %d %s" % (HTTP_Bad_Request, content)
bottle.abort(HTTP_Bad_Request, content)
where_={'uuid': image_id}
if tenant_id=='any':
from_ ='images'
+ where_or_ = None
else:
- from_ ='tenants_images as ti inner join images as i on ti.image_id=i.uuid'
- where_['tenant_id'] = tenant_id
- result, content = my.db.get_table(SELECT=('public',), FROM=from_, WHERE=where_)
+ from_ ='tenants_images as ti right join images as i on ti.image_id=i.uuid'
+ where_or_ = {'tenant_id': tenant_id, 'public': 'yes'}
+ result, content = my.db.get_table(SELECT=('public',), DISTINCT=True, FROM=from_, WHERE=where_, WHERE_OR=where_or_, WHERE_AND_OR="AND")
if result==0:
text_error="Image '%s' not found" % image_id
if tenant_id!='any':
return
server['flavor']=content[0]
#check image valid and take info
- result, content = my.db.get_table(FROM='tenants_images as ti join images as i on ti.image_id=i.uuid',
- SELECT=('path','metadata'), WHERE={'uuid':server['image_id'], 'tenant_id':tenant_id, "status":"ACTIVE"})
+ result, content = my.db.get_table(FROM='tenants_images as ti right join images as i on ti.image_id=i.uuid',
+ SELECT=('path', 'metadata', 'image_id'),
+ WHERE={'uuid':server['image_id'], "status":"ACTIVE"},
+ WHERE_OR={'tenant_id':tenant_id, 'public': 'yes'},
+ WHERE_AND_OR="AND",
+ DISTINCT=True)
if result<=0:
bottle.abort(HTTP_Not_Found, 'image_id %s not found or not ACTIVE' % server['image_id'])
return
- server['image']=content[0]
+ for image_dict in content:
+ if image_dict.get("image_id"):
+ break
+ else:
+ # insert in data base tenants_images
+ r2, c2 = my.db.new_row('tenants_images', {'image_id': server['image_id'], 'tenant_id': tenant_id})
+ if r2<=0:
+ bottle.abort(HTTP_Not_Found, 'image_id %s cannot be used. Error %s' % (server['image_id'], c2))
+ return
+ server['image']={"path": content[0]["path"], "metadata": content[0]["metadata"]}
if "hosts_id" in server:
result, content = my.db.get_table(FROM='hosts', SELECT=('uuid',), WHERE={'uuid': server['host_id']})
if result<=0:
print
if server_start == 'no':
content['status'] = 'INACTIVE'
+ dhcp_nets_id = []
+ for net in http_content['server']['networks']:
+ if net['type'] == 'instance:ovs':
+ dhcp_nets_id.append(get_network_id(net['net_id']))
+
ports_to_free=[]
new_instance_result, new_instance = my.db.new_instance(content, nets, ports_to_free)
if new_instance_result < 0:
print ':http_post_servers ERROR UPDATING NETS !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!' + c
-
- #look for dhcp ip address
- r2, c2 = my.db.get_table(FROM="ports", SELECT=["mac", "net_id"], WHERE={"instance_id": new_instance})
- if r2 >0 and config_dic.get("dhcp_server"):
+ #look for dhcp ip address
+ r2, c2 = my.db.get_table(FROM="ports", SELECT=["mac", "ip_address", "net_id"], WHERE={"instance_id": new_instance})
+ if r2 >0:
for iface in c2:
- if iface["net_id"] in config_dic["dhcp_nets"]:
+ if config_dic.get("dhcp_server") and iface["net_id"] in config_dic["dhcp_nets"]:
#print "dhcp insert add task"
r,c = config_dic['dhcp_thread'].insert_task("add", iface["mac"])
if r < 0:
- print ':http_post_servers ERROR UPDATING dhcp_server !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!' + c
-
- #Start server
-
+ print ':http_post_servers ERROR UPDATING dhcp_server !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!' + c
+
+ #ensure compute contain the bridge for ovs networks:
+ server_net = get_network_id(iface['net_id'])
+ if server_net["network"].get('provider:physical', "")[:3] == 'OVS':
+ vlan = str(server_net['network']['provider:vlan'])
+ dhcp_enable = bool(server_net['network']['enable_dhcp'])
+ if dhcp_enable:
+ dhcp_firt_ip = str(server_net['network']['dhcp_first_ip'])
+ dhcp_last_ip = str(server_net['network']['dhcp_last_ip'])
+ dhcp_cidr = str(server_net['network']['cidr'])
+ vm_dhcp_ip = c2[0]["ip_address"]
+ config_dic['host_threads'][server['host_id']].insert_task("create-ovs-bridge-port", vlan)
+
+ set_mac_dhcp(vm_dhcp_ip, vlan, dhcp_firt_ip, dhcp_last_ip, dhcp_cidr, c2[0]['mac'])
+ launch_dhcp_server(vlan, dhcp_firt_ip, dhcp_last_ip, dhcp_cidr)
+
+ #Start server
server['uuid'] = new_instance
- #server_start = server.get('start', 'yes')
+ server_start = server.get('start', 'yes')
+
if server_start != 'no':
- server['paused'] = True if server_start == 'paused' else False
+ server['paused'] = True if server_start == 'paused' else False
server['action'] = {"start":None}
server['status'] = "CREATING"
#Program task
else: #result==1
image_id = content[0]['image_id']
- result, content = my.db.get_table(FROM='tenants_images as ti join images as i on ti.image_id=i.uuid',
- SELECT=('path','metadata'), WHERE={'uuid':image_id, 'tenant_id':tenant_id, "status":"ACTIVE"})
+ result, content = my.db.get_table(FROM='tenants_images as ti right join images as i on ti.image_id=i.uuid',
+ SELECT=('path','metadata'), WHERE={'uuid':image_id, "status":"ACTIVE"},
+ WHERE_OR={'tenant_id':tenant_id, 'public': 'yes'}, WHERE_AND_OR="AND", DISTINCT=True)
if result<=0:
bottle.abort(HTTP_Not_Found, 'image_id %s not found or not ACTIVE' % image_id)
return
if new_status != None and new_status == 'DELETING':
nets=[]
ports_to_free=[]
- #look for dhcp ip address
+
+ net_ovs_list = []
+ #look for dhcp ip address
r2, c2 = my.db.get_table(FROM="ports", SELECT=["mac", "net_id"], WHERE={"instance_id": server_id})
- r,c = my.db.delete_instance(server_id, tenant_id, nets, ports_to_free, "requested by http")
+ r, c = my.db.delete_instance(server_id, tenant_id, nets, ports_to_free, net_ovs_list, "requested by http")
for port in ports_to_free:
r1,c1 = config_dic['host_threads'][ server['host_id'] ].insert_task( 'restore-iface',*port )
if r1 < 0:
#print "dhcp insert del task"
if r < 0:
print ':http_post_servers ERROR UPDATING dhcp_server !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!' + c
-
+ # delete ovs-port and linux bridge, contains a list of tuple (net_id,vlan)
+ for net in net_ovs_list:
+ mac = str(net[3])
+ vm_ip = str(net[2])
+ vlan = str(net[1])
+ net_id = net[0]
+ delete_dhcp_ovs_bridge(vlan, net_id)
+ delete_mac_dhcp(vm_ip, vlan, mac)
+ config_dic['host_threads'][server['host_id']].insert_task('del-ovs-port', vlan, net_id)
return format_out(data)
print "http_get_networks error %d %s" % (result, content)
bottle.abort(-result, content)
else:
- convert_boolean(content, ('shared', 'admin_state_up', 'enable_dhcp') )
+ convert_boolean(content, ('shared', 'admin_state_up', 'enable_dhcp'))
delete_nulls(content)
change_keys_http2db(content, http2db_network, reverse=True)
data={'networks' : content}
@bottle.route(url_base + '/networks/<network_id>', method='GET')
def http_get_network_id(network_id):
- my = config_dic['http_threads'][ threading.current_thread().name ]
- #obtain data
+ data = get_network_id(network_id)
+ return format_out(data)
+
+def get_network_id(network_id):
+ my = config_dic['http_threads'][threading.current_thread().name]
+ # obtain data
where_ = bottle.request.query
where_['uuid'] = network_id
result, content = my.db.get_table(FROM='nets', WHERE=where_, LIMIT=100)
print "http_get_networks_id network '%s' not found" % network_id
bottle.abort(HTTP_Not_Found, 'network %s not found' % network_id)
else:
- convert_boolean(content, ('shared', 'admin_state_up', 'enale_dhcp') )
+ convert_boolean(content, ('shared', 'admin_state_up', 'enable_dhcp'))
change_keys_http2db(content, http2db_network, reverse=True)
#get ports
result, ports = my.db.get_table(FROM='ports', SELECT=('uuid as port_id',),
content[0]['ports'] = ports
delete_nulls(content[0])
data={'network' : content[0]}
- return format_out(data)
+ return data
@bottle.route(url_base + '/networks', method='POST')
def http_post_networks():
#check valid params
net_provider = network.get('provider')
net_type = network.get('type')
+ net_enable_dhcp = network.get('enable_dhcp')
+ if net_enable_dhcp:
+ net_cidr = network.get('cidr')
+
net_vlan = network.get("vlan")
net_bind_net = network.get("bind_net")
net_bind_type= network.get("bind_type")
# if bridge_net==None:
# bottle.abort(HTTP_Bad_Request, "invalid 'provider:physical', bridge '%s' is not one of the provisioned 'bridge_ifaces' in the configuration file" % bridge_net_name)
# return
- elif net_type=='bridge_data' or net_type=='bridge_man':
+ elif config_dic['network_type'] == 'bridge' and ( net_type =='bridge_data' or net_type == 'bridge_man' ):
#look for a free precreated nets
for brnet in config_dic['bridge_nets']:
if brnet[3]==None: # free
print "using net", bridge_net
net_provider = "bridge:"+bridge_net[0]
net_vlan = bridge_net[1]
- if net_vlan==None and (net_type=="data" or net_type=="ptp"):
+ elif net_type == 'bridge_data' or net_type == 'bridge_man' and config_dic['network_type'] == 'ovs':
+ net_provider = 'OVS'
+ if not net_vlan and (net_type == "data" or net_type == "ptp" or net_provider == "OVS"):
net_vlan = my.db.get_free_net_vlan()
if net_vlan < 0:
bottle.abort(HTTP_Internal_Server_Error, "Error getting an available vlan")
return
-
+ if net_provider == 'OVS':
+ net_provider = 'OVS' + ":" + str(net_vlan)
+
network['provider'] = net_provider
network['type'] = net_type
network['vlan'] = net_vlan
+
+ if 'enable_dhcp' in network and network['enable_dhcp']:
+ check_dhcp_data_integrity(network)
+
result, content = my.db.new_row('nets', network, True, True)
if result >= 0:
if bridge_net!=None:
bridge_net[3] = content
-
- if config_dic.get("dhcp_server"):
+ if config_dic.get("dhcp_server") and config_dic['network_type'] == 'bridge':
if network["name"] in config_dic["dhcp_server"].get("nets", () ):
config_dic["dhcp_nets"].append(content)
print "dhcp_server: add new net", content
return
+def check_dhcp_data_integrity(network):
+ """
+ Check if all dhcp parameter for anet are valid, if not will be calculated from cidr value
+ :param network: list with user nets paramters
+ :return:
+ """
+ control_iface = []
+
+ if "cidr" in network:
+ cidr = network["cidr"]
+
+ ips = IPNetwork(cidr)
+ if "dhcp_first_ip" not in network:
+ network["dhcp_first_ip"] = str(ips[2])
+ if "dhcp_last_ip" not in network:
+ network["dhcp_last_ip"] = str(ips[-2])
+
+
@bottle.route(url_base + '/networks/<network_id>', method='PUT')
def http_put_network_id(network_id):
'''update a network_id into the database.'''
if new_net is not None: nets.append(new_net) #put first the new net, so that new openflow rules are created before removing the old ones
if old_net is not None: nets.append(old_net)
- if port['type'] == 'instance:bridge':
+ if port['type'] == 'instance:bridge' or port['type'] == 'instance:ovs':
bottle.abort(HTTP_Forbidden, "bridge interfaces cannot be attached to a different net")
return
elif port['type'] == 'external':