- '''insert a network into the database.'''
- my = config_dic['http_threads'][ threading.current_thread().name ]
- #parse input data
- http_content = format_in( network_new_schema )
- r = remove_extra_items(http_content, network_new_schema)
- if r is not None: print "http_post_networks: Warning: remove extra items ", r
- change_keys_http2db(http_content['network'], http2db_network)
- network=http_content['network']
- #check valid tenant_id
- tenant_id= network.get('tenant_id')
- if tenant_id!=None:
- result, _ = my.db.get_table(FROM='tenants', SELECT=('uuid',), WHERE={'uuid': tenant_id,"enabled":True})
- if result<=0:
- bottle.abort(HTTP_Not_Found, 'tenant %s not found or not enabled' % tenant_id)
- return
- bridge_net = None
- #check valid params
- net_provider = network.get('provider')
- net_type = network.get('type')
- net_vlan = network.get("vlan")
- net_bind_net = network.get("bind_net")
- net_bind_type= network.get("bind_type")
- name = network["name"]
-
- #check if network name ends with :<vlan_tag> and network exist in order to make and automated bindning
- vlan_index =name.rfind(":")
- if net_bind_net==None and net_bind_type==None and vlan_index > 1:
- try:
- vlan_tag = int(name[vlan_index+1:])
- if vlan_tag >0 and vlan_tag < 4096:
- net_bind_net = name[:vlan_index]
- net_bind_type = "vlan:" + name[vlan_index+1:]
- except:
- pass
-
- if net_bind_net != None:
- #look for a valid net
- if check_valid_uuid(net_bind_net):
- net_bind_key = "uuid"
- else:
- net_bind_key = "name"
- result, content = my.db.get_table(FROM='nets', WHERE={net_bind_key: net_bind_net} )
- if result<0:
- bottle.abort(HTTP_Internal_Server_Error, 'getting nets from db ' + content)
- return
- elif result==0:
- bottle.abort(HTTP_Bad_Request, "bind_net %s '%s'not found" % (net_bind_key, net_bind_net) )
- return
- elif result>1:
- bottle.abort(HTTP_Bad_Request, "more than one bind_net %s '%s' found, use uuid" % (net_bind_key, net_bind_net) )
- return
- network["bind_net"] = content[0]["uuid"]
- if net_bind_type != None:
- if net_bind_type[0:5] != "vlan:":
- bottle.abort(HTTP_Bad_Request, "bad format for 'bind_type', must be 'vlan:<tag>'")
- return
- if int(net_bind_type[5:]) > 4095 or int(net_bind_type[5:])<=0 :
- bottle.abort(HTTP_Bad_Request, "bad format for 'bind_type', must be 'vlan:<tag>' with a tag between 1 and 4095")
- return
- network["bind_type"] = net_bind_type
-
- if net_provider!=None:
- if net_provider[:9]=="openflow:":
- if net_type!=None:
- if net_type!="ptp" and net_type!="data":
- bottle.abort(HTTP_Bad_Request, "Only 'ptp' or 'data' net types can be bound to 'openflow'")
- else:
- net_type='data'
- else:
- if net_type!=None:
- if net_type!="bridge_man" and net_type!="bridge_data":
- bottle.abort(HTTP_Bad_Request, "Only 'bridge_man' or 'bridge_data' net types can be bound to 'bridge', 'macvtap' or 'default")
- else:
- net_type='bridge_man'
-
- if net_type==None:
- net_type='bridge_man'
-
- if net_provider != None:
- if net_provider[:7]=='bridge:':
- #check it is one of the pre-provisioned bridges
- bridge_net_name = net_provider[7:]
- for brnet in config_dic['bridge_nets']:
- if brnet[0]==bridge_net_name: # free
- if brnet[3] != None:
- bottle.abort(HTTP_Conflict, "invalid 'provider:physical', bridge '%s' is already used" % bridge_net_name)
- return
- bridge_net=brnet
- net_vlan = brnet[1]
- break
-# 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':
- #look for a free precreated nets
- for brnet in config_dic['bridge_nets']:
- if brnet[3]==None: # free
- if bridge_net != None:
- if net_type=='bridge_man': #look for the smaller speed
- if brnet[2] < bridge_net[2]: bridge_net = brnet
- else: #look for the larger speed
- if brnet[2] > bridge_net[2]: bridge_net = brnet
- else:
- bridge_net = brnet
- net_vlan = brnet[1]
- if bridge_net==None:
- bottle.abort(HTTP_Bad_Request, "Max limits of bridge networks reached. Future versions of VIM will overcome this limit")
- return
- else:
- 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"):
- net_vlan = my.db.get_free_net_vlan()
- if net_vlan < 0:
- bottle.abort(HTTP_Internal_Server_Error, "Error getting an available vlan")
- return
-
- network['provider'] = net_provider
- network['type'] = net_type
- network['vlan'] = net_vlan
- 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 network["name"] in config_dic["dhcp_server"].get("nets", () ):
- config_dic["dhcp_nets"].append(content)
- print "dhcp_server: add new net", content
- elif bridge_net != None and bridge_net[0] in config_dic["dhcp_server"].get("bridge_ifaces", () ):
- config_dic["dhcp_nets"].append(content)
- print "dhcp_server: add new net", content
- return http_get_network_id(content)
- else:
- print "http_post_networks error %d %s" % (result, content)
- bottle.abort(-result, content)
- return