DBNAME="mano_db"
QUIET_MODE=""
#TODO update it with the last database version
-LAST_DB_VERSION=20
+LAST_DB_VERSION=21
# Detect paths
MYSQL=$(which mysql)
#[ $OPENMANO_VER_NUM -ge 5004 ] && DB_VERSION=18 #0.5.4 => 18
#[ $OPENMANO_VER_NUM -ge 5005 ] && DB_VERSION=19 #0.5.5 => 19
#[ $OPENMANO_VER_NUM -ge 5009 ] && DB_VERSION=20 #0.5.9 => 20
+#[ $OPENMANO_VER_NUM -ge 5015 ] && DB_VERSION=21 #0.5.15 => 21
#TODO ... put next versions here
function upgrade_to_1(){
echo "DELETE FROM schema_version WHERE version_int='20';" | $DBCMD || ! echo "ERROR. Aborted!" || exit -1
}
+function upgrade_to_21(){
+ # echo " upgrade database from version 0.20 to version 0.21"
+ echo " edit 'instance_nets' to allow instance_scenario_id=None"
+ echo "ALTER TABLE instance_nets MODIFY COLUMN instance_scenario_id varchar(36) NULL;" | $DBCMD || ! echo "ERROR. Aborted!" || exit -1
+ echo " enlarge column 'dns_address' at table 'ip_profiles'"
+ echo "ALTER TABLE ip_profiles MODIFY dns_address varchar(255) DEFAULT NULL NULL "\
+ "comment 'dns ip list separated by semicolon';" | $DBCMD || ! echo "ERROR. Aborted!" || exit -1
+ echo "INSERT INTO schema_version (version_int, version, openmano_ver, comments, date) VALUES (21, '0.21', '0.5.15', 'Edit instance_nets to allow instance_scenario_id=None and enlarge column dns_address at table ip_profiles', '2017-06-02');" | $DBCMD || ! echo "ERROR. Aborted!" || exit -1
+}
+function downgrade_from_21(){
+ # echo " downgrade database from version 0.21 to version 0.20"
+ echo " edit 'instance_nets' to disallow instance_scenario_id=None"
+ #Delete all lines with a instance_scenario_id=NULL in order to disable this option
+ echo "DELETE FROM instance_nets WHERE instance_scenario_id IS NULL;" | $DBCMD || ! echo "ERROR. Aborted!" || exit -1
+ echo "ALTER TABLE instance_nets MODIFY COLUMN instance_scenario_id varchar(36) NOT NULL;" | $DBCMD || ! echo "ERROR. Aborted!" || exit -1
+ echo " shorten column 'dns_address' at table 'ip_profiles'"
+ echo "ALTER TABLE ip_profiles MODIFY dns_address varchar(64) DEFAULT NULL NULL;" | $DBCMD || ! echo "ERROR. Aborted!" || exit -1
+ echo "DELETE FROM schema_version WHERE version_int='21';" | $DBCMD || ! echo "ERROR. Aborted!" || exit -1
+}
+
function upgrade_to_X(){
echo " change 'datacenter_nets'"
echo "ALTER TABLE datacenter_nets ADD COLUMN vim_tenant_id VARCHAR(36) NOT NULL AFTER datacenter_id, DROP INDEX name_datacenter_id, ADD UNIQUE INDEX name_datacenter_id (name, datacenter_id, vim_tenant_id);" | $DBCMD || ! echo "ERROR. Aborted!" || exit -1
if verbose_level >=1:
if content.get('created_at'):
myoutput += " " + content['created_at'].ljust(20)
+ if content.get('sdn_attached_ports'):
+ #myoutput += " " + str(content['sdn_attached_ports']).ljust(20)
+ myoutput += "\nsdn_attached_ports:\n" + yaml.safe_dump(content['sdn_attached_ports'], indent=4, default_flow_style=False)
if verbose_level >=2:
new_line='\n'
if content.get('type'):
"No yaml/json has been provided specifying the SDN port mapping")
port_mapping = yaml.load(datacenter_sdn_port_mapping_list(args))
+ if 'error' in port_mapping:
+ raise OpenmanoCLIError("openmano client error: {}".format(port_mapping['error']['description']))
if len(port_mapping["sdn_port_mapping"]["ports_mapping"]) > 0:
if not args.force:
r = raw_input("Datacenter %s already contains a port mapping. Overwrite? (y/N)? " % (datacenter))
args.verbose=0
return _print_verbose(mano_response, args.verbose)
+def _get_items(item, item_name_id=None, datacenter=None, tenant=None):
+ URLrequest = "http://%s:%s/openmano" %(mano_host, mano_port)
+ if tenant:
+ URLrequest += "/" + tenant
+ if datacenter:
+ URLrequest += "/vim/" + datacenter
+ if item:
+ URLrequest += "/" + item +"s"
+ if item_name_id:
+ URLrequest += "/" + item_name_id
+ mano_response = requests.get(URLrequest)
+ logger.debug("openmano response: %s", mano_response.text )
+
+ return mano_response
+
+def vim_net_sdn_attach(args):
+ #Verify the network exists in the vim
+ tenant = _get_tenant()
+ datacenter = _get_datacenter(args.datacenter, tenant)
+ result = _get_items('network', item_name_id=args.vim_net, datacenter=datacenter, tenant=tenant)
+ content = yaml.load(result.content)
+ if 'networks' in content:
+ raise OpenmanoCLIError('More than one network in the vim named ' + args.vim_net + '. Use uuid instead')
+ if 'error' in content:
+ raise OpenmanoCLIError(yaml.safe_dump(content))
+ network_uuid = content['network']['id']
+
+ #Make call to attach the dataplane port to the SND network associated to the vim network
+ headers_req = {'content-type': 'application/yaml'}
+ payload_req = {'port': args.port}
+ if args.vlan:
+ payload_req['vlan'] = int(args.vlan)
+ if args.mac:
+ payload_req['mac'] = args.mac
+
+ URLrequest = "http://%s:%s/openmano/%s/vim/%s/network/%s/attach" % (mano_host, mano_port, tenant, datacenter, network_uuid)
+ logger.debug("openmano request: %s", payload_req)
+ mano_response = requests.post(URLrequest, headers=headers_req, data=json.dumps(payload_req))
+ logger.debug("openmano response: %s", mano_response.text)
+ result = _print_verbose(mano_response, args.verbose)
+
+ return
+
+
+def vim_net_sdn_detach(args):
+ if not args.all and not args.id:
+ print "--all or --id must be used"
+ return 1
+
+ # Verify the network exists in the vim
+ tenant = _get_tenant()
+ datacenter = _get_datacenter(args.datacenter, tenant)
+ result = _get_items('network', item_name_id=args.vim_net, datacenter=datacenter, tenant=tenant)
+ content = yaml.load(result.content)
+ if 'networks' in content:
+ raise OpenmanoCLIError('More than one network in the vim named ' + args.vim_net + '. Use uuid instead')
+ if 'error' in content:
+ raise OpenmanoCLIError(yaml.safe_dump(content))
+ network_uuid = content['network']['id']
+
+ if not args.force:
+ r = raw_input("Confirm action' (y/N)? ")
+ if len(r) == 0 or r[0].lower() != "y":
+ return 0
+
+ if args.id:
+ URLrequest = "http://%s:%s/openmano/%s/vim/%s/network/%s/detach/%s" % (
+ mano_host, mano_port, tenant, datacenter, network_uuid, args.id)
+ else:
+ URLrequest = "http://%s:%s/openmano/%s/vim/%s/network/%s/detach" % (
+ mano_host, mano_port, tenant, datacenter, network_uuid)
+ mano_response = requests.delete(URLrequest)
+ logger.debug("openmano response: %s", mano_response.text)
+ result = _print_verbose(mano_response, args.verbose)
+
+ return
def datacenter_net_action(args):
if args.action == "net-update":
if item=='netmap-import':
datacenter_action_parser.add_argument("-f","--force", action="store_true", help="do not prompt for confirmation")
datacenter_action_parser.set_defaults(func=datacenter_netmap_action, action=item)
-
+
+ # =======================vim_net_sdn_xxx section=======================
+ # vim_net_sdn_attach
+ vim_net_sdn_attach_parser = subparsers.add_parser('vim-net-sdn-attach',
+ parents=[parent_parser],
+ help="Specify the port to access to an external network using SDN")
+ vim_net_sdn_attach_parser.add_argument("vim_net", action="store",
+ help="Name/id of the network in the vim that will be used to connect to the external network")
+ vim_net_sdn_attach_parser.add_argument("port", action="store", help="Specifies the port in the dataplane switch to access to the external network")
+ vim_net_sdn_attach_parser.add_argument("--vlan", action="store", help="Specifies the vlan (if any) to use in the defined port")
+ vim_net_sdn_attach_parser.add_argument("--mac", action="store", help="Specifies the MAC (if known) of the physical device that will be reachable by this external port")
+ vim_net_sdn_attach_parser.add_argument("--datacenter", action="store", help="specifies the datacenter")
+ vim_net_sdn_attach_parser.set_defaults(func=vim_net_sdn_attach)
+
+ # vim_net_sdn_detach
+ vim_net_sdn_detach_parser = subparsers.add_parser('vim-net-sdn-detach',
+ parents=[parent_parser],
+ help="Remove the port information to access to an external network using SDN")
+
+ vim_net_sdn_detach_parser.add_argument("vim_net", action="store", help="Name/id of the vim network")
+ vim_net_sdn_detach_parser.add_argument("--id", action="store",help="Specify the uuid of the external ports from this network to be detached")
+ vim_net_sdn_detach_parser.add_argument("--all", action="store_true", help="Detach all external ports from this network")
+ vim_net_sdn_detach_parser.add_argument("-f", "--force", action="store_true", help="forces clearing without asking")
+ vim_net_sdn_detach_parser.add_argument("--datacenter", action="store", help="specifies the datacenter")
+ vim_net_sdn_detach_parser.set_defaults(func=vim_net_sdn_detach)
+ # =======================
+
for item in ("network", "tenant", "image"):
if item=="network":
- commnad_name = 'vim-net'
+ command_name = 'vim-net'
else:
- commnad_name = 'vim-'+item
- vim_item_list_parser = subparsers.add_parser(commnad_name + '-list', parents=[parent_parser], help="list the vim " + item + "s")
+ command_name = 'vim-'+item
+ vim_item_list_parser = subparsers.add_parser(command_name + '-list', parents=[parent_parser], help="list the vim " + item + "s")
vim_item_list_parser.add_argument("name", nargs='?', help="name or uuid of the " + item + "s")
vim_item_list_parser.add_argument("--datacenter", action="store", help="specifies the datacenter")
vim_item_list_parser.set_defaults(func=vim_action, item=item, action="list")
- vim_item_del_parser = subparsers.add_parser(commnad_name + '-delete', parents=[parent_parser], help="list the vim " + item + "s")
+ vim_item_del_parser = subparsers.add_parser(command_name + '-delete', parents=[parent_parser], help="list the vim " + item + "s")
vim_item_del_parser.add_argument("name", help="name or uuid of the " + item + "s")
vim_item_del_parser.add_argument("--datacenter", action="store", help="specifies the datacenter")
vim_item_del_parser.set_defaults(func=vim_action, item=item, action="delete")
if item == "network" or item == "tenant":
- vim_item_create_parser = subparsers.add_parser(commnad_name + '-create', parents=[parent_parser], help="create a "+item+" at vim")
+ vim_item_create_parser = subparsers.add_parser(command_name + '-create', parents=[parent_parser], help="create a "+item+" at vim")
vim_item_create_parser.add_argument("file", nargs='?', help="descriptor of the %s. Must be a file or yaml/json text" % item).completer = FilesCompleter
vim_item_create_parser.add_argument("--name", action="store", help="name of the %s" % item )
vim_item_create_parser.add_argument("--datacenter", action="store", help="specifies the datacenter")
__author__ = "Alfonso Tierno, Gerardo Garcia, Pablo Montes"
__date__ = "$26-aug-2014 11:09:29$"
-__version__ = "0.5.14-r523"
-version_date = "May 2017"
-database_version = 20 #expected database schema version
+__version__ = "0.5.15-r524"
+version_date = "Jun 2017"
+database_version = 21 #expected database schema version
global global_config
global logger
tenant_schema, tenant_edit_schema,\
datacenter_schema, datacenter_edit_schema, datacenter_action_schema, datacenter_associate_schema,\
object_schema, netmap_new_schema, netmap_edit_schema, sdn_controller_schema, sdn_controller_edit_schema, \
- sdn_port_mapping_schema
+ sdn_port_mapping_schema, sdn_external_port_schema
import nfvo
import utils
logger.error("Unexpected exception: ", exc_info=True)
bottle.abort(HTTP_Internal_Server_Error, type(e).__name__ + ": " + str(e))
+@bottle.route(url_base + '/<tenant_id>/vim/<datacenter_id>/network/<network_id>/attach', method='POST')
+def http_post_vim_net_sdn_attach(tenant_id, datacenter_id, network_id):
+ logger.debug('FROM %s %s %s', bottle.request.remote_addr, bottle.request.method, bottle.request.url)
+ http_content, _ = format_in(sdn_external_port_schema)
+ try:
+ data = nfvo.vim_net_sdn_attach(mydb, tenant_id, datacenter_id, network_id, http_content)
+ return format_out(data)
+ except (nfvo.NfvoException, db_base_Exception) as e:
+ logger.error("http_post_vim_net_sdn_attach error {}: {}".format(e.http_code, str(e)))
+ bottle.abort(e.http_code, str(e))
+ except Exception as e:
+ logger.error("Unexpected exception: ", exc_info=True)
+ bottle.abort(HTTP_Internal_Server_Error, type(e).__name__ + ": " + str(e))
+
+@bottle.route(url_base + '/<tenant_id>/vim/<datacenter_id>/network/<network_id>/detach', method='DELETE')
+@bottle.route(url_base + '/<tenant_id>/vim/<datacenter_id>/network/<network_id>/detach/<port_id>', method='DELETE')
+def http_delete_vim_net_sdn_detach(tenant_id, datacenter_id, network_id, port_id=None):
+ logger.debug('FROM %s %s %s', bottle.request.remote_addr, bottle.request.method, bottle.request.url)
+ try:
+ data = nfvo.vim_net_sdn_detach(mydb, tenant_id, datacenter_id, network_id, port_id)
+ return format_out(data)
+ except (nfvo.NfvoException, db_base_Exception) as e:
+ logger.error("http_delete_vim_net_sdn_detach error {}: {}".format(e.http_code, str(e)))
+ bottle.abort(e.http_code, str(e))
+ except Exception as e:
+ logger.error("Unexpected exception: ", exc_info=True)
+ bottle.abort(HTTP_Internal_Server_Error, type(e).__name__ + ": " + str(e))
@bottle.route(url_base + '/<tenant_id>/vim/<datacenter_id>/<item>', method='GET')
@bottle.route(url_base + '/<tenant_id>/vim/<datacenter_id>/<item>/<name>', method='GET')
from threading import Lock
from time import time
from lib_osm_openvim import ovim as ovim_module
+from lib_osm_openvim.ovim import ovimException
global global_config
global vimconn_imported
net_list.append(net_nfvo)
return net_list
+def get_sdn_net_id(mydb, tenant_id, datacenter, network_id):
+ # obtain all network data
+ try:
+ if utils.check_valid_uuid(network_id):
+ filter_dict = {"id": network_id}
+ else:
+ filter_dict = {"name": network_id}
+
+ datacenter_id, myvim = get_datacenter_by_name_uuid(mydb, tenant_id, datacenter)
+ network = myvim.get_network_list(filter_dict=filter_dict)
+ except vimconn.vimconnException as e:
+ print "vim_action Not possible to get_%s_list from VIM: %s " % (item, str(e))
+ raise NfvoException("Not possible to get_{}_list from VIM: {}".format(item, str(e)), e.http_code)
+
+ # ensure the network is defined
+ if len(network) == 0:
+ raise NfvoException("Network {} is not present in the system".format(network_id),
+ HTTP_Bad_Request)
+
+ # ensure there is only one network with the provided name
+ if len(network) > 1:
+ raise NfvoException("Multiple networks present in vim identified by {}".format(network_id), HTTP_Bad_Request)
+
+ # ensure it is a dataplane network
+ if network[0]['type'] != 'data':
+ return None
+
+ # ensure we use the id
+ network_id = network[0]['id']
+
+ # search in dabase mano_db in table instance nets for the sdn_net_id that corresponds to the vim_net_id==network_id
+ # and with instance_scenario_id==NULL
+ #search_dict = {'vim_net_id': network_id, 'instance_scenario_id': None}
+ search_dict = {'vim_net_id': network_id}
+
+ try:
+ #sdn_network_id = mydb.get_rows(SELECT=('sdn_net_id',), FROM='instance_nets', WHERE=search_dict)[0]['sdn_net_id']
+ result = mydb.get_rows(SELECT=('sdn_net_id',), FROM='instance_nets', WHERE=search_dict)
+ except db_base_Exception as e:
+ raise NfvoException("db_base_Exception obtaining SDN network to associated to vim network {}".format(
+ network_id) + str(e), HTTP_Internal_Server_Error)
+
+ sdn_net_counter = 0
+ for net in result:
+ if net['sdn_net_id'] != None:
+ sdn_net_counter+=1
+ sdn_net_id = net['sdn_net_id']
+
+ if sdn_net_counter == 0:
+ return None
+ elif sdn_net_counter == 1:
+ return sdn_net_id
+ else:
+ raise NfvoException("More than one SDN network is associated to vim network {}".format(
+ network_id), HTTP_Internal_Server_Error)
+
+def get_sdn_controller_id(mydb, datacenter):
+ # Obtain sdn controller id
+ config = mydb.get_rows(SELECT=('config',), FROM='datacenters', WHERE={'uuid': datacenter})[0].get('config', '{}')
+ if not config:
+ return None
+
+ return yaml.load(config).get('sdn-controller')
+
+def vim_net_sdn_attach(mydb, tenant_id, datacenter, network_id, descriptor):
+ try:
+ sdn_network_id = get_sdn_net_id(mydb, tenant_id, datacenter, network_id)
+ if not sdn_network_id:
+ raise NfvoException("No SDN network is associated to vim-network {}".format(network_id), HTTP_Internal_Server_Error)
+
+ #Obtain sdn controller id
+ controller_id = get_sdn_controller_id(mydb, datacenter)
+ if not controller_id:
+ raise NfvoException("No SDN controller is set for datacenter {}".format(datacenter), HTTP_Internal_Server_Error)
+
+ #Obtain sdn controller info
+ sdn_controller = ovim.show_of_controller(controller_id)
+
+ port_data = {
+ 'name': 'external_port',
+ 'net_id': sdn_network_id,
+ 'ofc_id': controller_id,
+ 'switch_dpid': sdn_controller['dpid'],
+ 'switch_port': descriptor['port']
+ }
+
+ if 'vlan' in descriptor:
+ port_data['vlan'] = descriptor['vlan']
+ if 'mac' in descriptor:
+ port_data['mac'] = descriptor['mac']
+
+ result = ovim.new_port(port_data)
+ except ovimException as e:
+ raise NfvoException("ovimException attaching SDN network {} to vim network {}".format(
+ sdn_network_id, network_id) + str(e), HTTP_Internal_Server_Error)
+ except db_base_Exception as e:
+ raise NfvoException("db_base_Exception attaching SDN network to vim network {}".format(
+ network_id) + str(e), HTTP_Internal_Server_Error)
+
+ return 'Port uuid: '+ result
+
+def vim_net_sdn_detach(mydb, tenant_id, datacenter, network_id, port_id=None):
+ if port_id:
+ filter = {'uuid': port_id}
+ else:
+ sdn_network_id = get_sdn_net_id(mydb, tenant_id, datacenter, network_id)
+ if not sdn_network_id:
+ raise NfvoException("No SDN network is associated to vim-network {}".format(network_id),
+ HTTP_Internal_Server_Error)
+ #in case no port_id is specified only ports marked as 'external_port' will be detached
+ filter = {'name': 'external_port', 'net_id': sdn_network_id}
+
+ try:
+ port_list = ovim.get_ports(columns={'uuid'}, filter=filter)
+ except ovimException as e:
+ raise NfvoException("ovimException obtaining external ports for net {}. ".format(network_id) + str(e),
+ HTTP_Internal_Server_Error)
+
+ if len(port_list) == 0:
+ raise NfvoException("No ports attached to the network {} were found with the requested criteria".format(network_id),
+ HTTP_Bad_Request)
+
+ port_uuid_list = []
+ for port in port_list:
+ try:
+ port_uuid_list.append(port['uuid'])
+ ovim.delete_port(port['uuid'])
+ except ovimException as e:
+ raise NfvoException("ovimException deleting port {} for net {}. ".format(port['uuid'], network_id) + str(e), HTTP_Internal_Server_Error)
+
+ return 'Detached ports uuid: {}'.format(','.join(port_uuid_list))
def vim_action_get(mydb, tenant_id, datacenter, item, name):
#get datacenter info
if item=="networks":
#filter_dict['tenant_id'] = myvim['tenant_id']
content = myvim.get_network_list(filter_dict=filter_dict)
+
+ if len(content) == 0:
+ raise NfvoException("Network {} is not present in the system. ".format(name),
+ HTTP_Bad_Request)
+
+ #Update the networks with the attached ports
+ for net in content:
+ sdn_network_id = get_sdn_net_id(mydb, tenant_id, datacenter, net['id'])
+ if sdn_network_id != None:
+ try:
+ #port_list = ovim.get_ports(columns={'uuid', 'switch_port', 'vlan'}, filter={'name': 'external_port', 'net_id': sdn_network_id})
+ port_list = ovim.get_ports(columns={'uuid', 'switch_port', 'vlan','name'}, filter={'net_id': sdn_network_id})
+ except ovimException as e:
+ raise NfvoException("ovimException obtaining external ports for net {}. ".format(network_id) + str(e), HTTP_Internal_Server_Error)
+ #Remove field name and if port name is external_port save it as 'type'
+ for port in port_list:
+ if port['name'] == 'external_port':
+ port['type'] = "External"
+ del port['name']
+ net['sdn_network_id'] = sdn_network_id
+ net['sdn_attached_ports'] = port_list
+
elif item=="tenants":
content = myvim.get_tenant_list(filter_dict=filter_dict)
elif item == "images":
+
content = myvim.get_image_list(filter_dict=filter_dict)
else:
raise NfvoException(item + "?", HTTP_Method_Not_Allowed)
try:
if item=="networks":
+ # If there is a SDN network associated to the vim-network, proceed to clear the relationship and delete it
+ sdn_network_id = get_sdn_net_id(mydb, tenant_id, datacenter, item_id)
+ if sdn_network_id != None:
+ #Delete any port attachment to this network
+ try:
+ port_list = ovim.get_ports(columns={'uuid'}, filter={'net_id': sdn_network_id})
+ except ovimException as e:
+ raise NfvoException(
+ "ovimException obtaining external ports for net {}. ".format(network_id) + str(e),
+ HTTP_Internal_Server_Error)
+
+ # By calling one by one all ports to be detached we ensure that not only the external_ports get detached
+ for port in port_list:
+ vim_net_sdn_detach(mydb, tenant_id, datacenter, item_id, port['uuid'])
+
+ #Delete from 'instance_nets' the correspondence between the vim-net-id and the sdn-net-id
+ try:
+ mydb.delete_row(FROM='instance_nets', WHERE={'instance_scenario_id': None, 'sdn_net_id': sdn_network_id, 'vim_net_id': item_id})
+ except db_base_Exception as e:
+ raise NfvoException("Error deleting correspondence for VIM/SDN dataplane networks{}: ".format(correspondence) +
+ str(e), HTTP_Internal_Server_Error)
+
+ #Delete the SDN network
+ try:
+ ovim.delete_network(sdn_network_id)
+ except ovimException as e:
+ logger.error("ovimException deleting SDN network={} ".format(sdn_network_id) + str(e), exc_info=True)
+ raise NfvoException("ovimException deleting SDN network={} ".format(sdn_network_id) + str(e),
+ HTTP_Internal_Server_Error)
+
content = myvim.delete_network(item_id)
elif item=="tenants":
content = myvim.delete_tenant(item_id)
net_ipprofile = net.pop("ip_profile", None)
net_vlan = net.pop("vlan", None)
content = myvim.new_network(net_name, net_type, net_ipprofile, shared=net_public, vlan=net_vlan) #, **net)
+
+ #If the datacenter has a SDN controller defined and the network is of dataplane type, then create the sdn network
+ if get_sdn_controller_id(mydb, datacenter) != None and (net_type == 'data' or net_type == 'ptp'):
+ try:
+ sdn_network = {}
+ sdn_network['vlan'] = net_vlan
+ sdn_network['type'] = net_type
+ sdn_network['name'] = net_name
+ ovim_content = ovim.new_network(sdn_network)
+ except ovimException as e:
+ self.logger.error("ovimException creating SDN network={} ".format(
+ sdn_network) + str(e), exc_info=True)
+ raise NfvoException("ovimException creating SDN network={} ".format(sdn_network) + str(e),
+ HTTP_Internal_Server_Error)
+
+ # Save entry in in dabase mano_db in table instance_nets to stablish a dictionary vim_net_id <->sdn_net_id
+ # use instance_scenario_id=None to distinguish from real instaces of nets
+ correspondence = {'instance_scenario_id': None, 'sdn_net_id': ovim_content, 'vim_net_id': content}
+ #obtain datacenter_tenant_id
+ correspondence['datacenter_tenant_id'] = mydb.get_rows(SELECT=('uuid',), FROM='datacenter_tenants', WHERE={'datacenter_id': datacenter})[0]['uuid']
+
+ try:
+ mydb.new_row('instance_nets', correspondence, add_uuid=True)
+ except db_base_Exception as e:
+ raise NfvoException("Error saving correspondence for VIM/SDN dataplane networks{}: ".format(correspondence) +
+ str(e), HTTP_Internal_Server_Error)
elif item=="tenants":
tenant = descriptor["tenant"]
content = myvim.new_tenant(tenant["name"], tenant.get("description"))
result["sdn-controller"] = controller_id
result["dpid"] = sdn_controller["dpid"]
- if result["sdn-controller"] == None or result["dpid"] == None:
- raise NfvoException("Not all SDN controller information for datacenter {} could be found: {}".format(datacenter_id, result),
- HTTP_Internal_Server_Error)
+ if result["sdn-controller"] == None:
+ raise NfvoException("SDN controller is not defined for datacenter {}".format(datacenter_id), HTTP_Bad_Request)
+ if result["dpid"] == None:
+ raise NfvoException("It was not possible to determine DPID for SDN controller {}".format(result["sdn-controller"]),
+ HTTP_Internal_Server_Error)
if len(maps) == 0:
return result
sdn_controller_properties={
"name": name_schema,
- "dpid": {"type":"string", "pattern":"^[0-9a-fA-F][02468aceACE](:[0-9a-fA-F]{2}){7}$"},
+ "dpid": {"type":"string", "pattern":"^[0-9a-fA-F]{2}(:[0-9a-fA-F]{2}){7}$"},
"ip": ip_schema,
"port": port_schema,
"type": {"type": "string", "enum": ["opendaylight","floodlight","onos"]},
}
},
"required": ["sdn_port_mapping"]
+}
+
+sdn_external_port_schema = {
+ "$schema": "http://json-schema.org/draft-04/schema#",
+ "title":"External port ingformation",
+ "type": "object",
+ "properties": {
+ "port": {"type" : "string", "minLength":1, "maxLength":60},
+ "vlan": vlan_schema,
+ "mac": mac_schema
+ },
+ "required": ["port"]
}
\ No newline at end of file
FROM="instance_interfaces as ii left join instance_nets as ine on "
"ii.instance_net_id=ine.uuid left join instance_vms as iv on "
"ii.instance_vm_id=iv.uuid",
- SELECT=("ii.uuid as iface_id", "ine.uuid as net_id", "iv.uuid as vm_id", "sdn_net_id"),
+ SELECT=("ii.uuid as iface_id", "ine.uuid as net_id", "iv.uuid as vm_id", "sdn_net_id", "vim_net_id"),
WHERE=where_)
if len(db_ifaces)>1:
self.logger.critical("Refresing interfaces. "
continue
else:
db_iface = db_ifaces[0]
+ #If there is no sdn_net_id, check if it is because an already created vim network is being used
+ #in that case, the sdn_net_id will be in that entry of the instance_nets table
+ if not db_iface.get("sdn_net_id"):
+ result = self.db.get_rows(SELECT=('sdn_net_id',), FROM='instance_nets',
+ WHERE={'vim_net_id': db_iface.get("vim_net_id"), 'instance_scenario_id': None, "datacenter_tenant_id": self.datacenter_tenant_id})
+ if len(result) == 1:
+ db_iface["sdn_net_id"] = result[0]['sdn_net_id']
+
if db_iface.get("sdn_net_id") and interface.get("compute_node") and interface.get("pci"):
sdn_net_id = db_iface["sdn_net_id"]
sdn_port_name = sdn_net_id + "." + db_iface["vm_id"]
self._remove_refresh("get-net", net_id)
result = self.vim.delete_network(net_id)
if sdn_net_id:
+ #Delete any attached port to this sdn network
+ #At this point, there will be ports associated to this network in case it was manually done using 'openmano vim-net-sdn-attach'
+ try:
+ port_list = self.ovim.get_ports(columns={'uuid'}, filter={'name': 'external_port', 'net_id': sdn_net_id})
+ except ovimException as e:
+ raise vimconn.vimconnException(
+ "ovimException obtaining external ports for net {}. ".format(sdn_net_id) + str(e))
+
+ for port in port_list:
+ try:
+ self.ovim.delete_port(port['uuid'])
+ except ovimException as e:
+ raise vimconn.vimconnException(
+ "ovimException deleting port {} for net {}. ".format(port['uuid'], sdn_net_id) + str(e))
with self.db_lock:
self.ovim.delete_network(sdn_net_id)
return True, result