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
#TODO: log_level_of should not be needed. To be modified in ovim
'log_level_of': 'DEBUG'
}
- ovim = ovim_module.ovim(ovim_configuration)
- ovim.start_service()
-
- from_= 'tenants_datacenters as td join datacenters as d on td.datacenter_id=d.uuid join datacenter_tenants as dt on td.datacenter_tenant_id=dt.uuid'
- select_ = ('type','d.config as config','d.uuid as datacenter_id', 'vim_url', 'vim_url_admin', 'd.name as datacenter_name',
- 'dt.uuid as datacenter_tenant_id','dt.vim_tenant_name as vim_tenant_name','dt.vim_tenant_id as vim_tenant_id',
- 'user','passwd', 'dt.config as dt_config', 'nfvo_tenant_id')
try:
+ ovim = ovim_module.ovim(ovim_configuration)
+ ovim.start_service()
+
+ from_= 'tenants_datacenters as td join datacenters as d on td.datacenter_id=d.uuid join '\
+ 'datacenter_tenants as dt on td.datacenter_tenant_id=dt.uuid'
+ select_ = ('type', 'd.config as config', 'd.uuid as datacenter_id', 'vim_url', 'vim_url_admin',
+ 'd.name as datacenter_name', 'dt.uuid as datacenter_tenant_id',
+ 'dt.vim_tenant_name as vim_tenant_name', 'dt.vim_tenant_id as vim_tenant_id',
+ 'user', 'passwd', 'dt.config as dt_config', 'nfvo_tenant_id')
vims = mydb.get_rows(FROM=from_, SELECT=select_)
for vim in vims:
extra={'datacenter_tenant_id': vim.get('datacenter_tenant_id'),
config=extra, persistent_info=vim_persistent_info[thread_id]
)
except Exception as e:
- raise NfvoException("Error at VIM {}; {}: {}".format(vim["type"], type(e).__name__, str(e)), HTTP_Internal_Server_Error)
- thread_name = get_non_used_vim_name(vim['datacenter_name'], vim['vim_tenant_id'], vim['vim_tenant_name'], vim['vim_tenant_id'])
+ raise NfvoException("Error at VIM {}; {}: {}".format(vim["type"], type(e).__name__, e),
+ HTTP_Internal_Server_Error)
+ thread_name = get_non_used_vim_name(vim['datacenter_name'], vim['vim_tenant_id'], vim['vim_tenant_name'],
+ vim['vim_tenant_id'])
new_thread = vim_thread.vim_thread(myvim, task_lock, thread_name, vim['datacenter_name'],
vim['datacenter_tenant_id'], db=db, db_lock=db_lock, ovim=ovim)
new_thread.start()
vim_threads["running"][thread_id] = new_thread
except db_base_Exception as e:
raise NfvoException(str(e) + " at nfvo.get_vim", e.http_code)
+ except ovim_module.ovimException as e:
+ message = str(e)
+ if message[:22] == "DATABASE wrong version":
+ message = "DATABASE wrong version of lib_osm_openvim {msg} -d{dbname} -u{dbuser} -p{dbpass} {ver}' "\
+ "at host {dbhost}".format(
+ msg=message[22:-3], dbname=global_config["db_ovim_name"],
+ dbuser=global_config["db_ovim_user"], dbpass=global_config["db_ovim_passwd"],
+ ver=message[-3:-1], dbhost=global_config["db_ovim_host"])
+ raise NfvoException(message, HTTP_Bad_Request)
def stop_service():
for thread in global_config["console_thread"]:
thread.terminate = True
+def get_version():
+ return ("openmanod version {} {}\n(c) Copyright Telefonica".format(global_config["version"],
+ global_config["version_date"] ))
+
def get_flavorlist(mydb, vnf_id, nfvo_tenant=None):
'''Obtain flavorList
for scenario_net in scenarioDict['nets']:
if net_name == scenario_net["name"]:
if 'ip-profile' in net_instance_desc:
- ipprofile = net_instance_desc['ip-profile']
- ipprofile['subnet_address'] = ipprofile.pop('subnet-address',None)
- ipprofile['ip_version'] = ipprofile.pop('ip-version','IPv4')
- ipprofile['gateway_address'] = ipprofile.pop('gateway-address',None)
- ipprofile['dns_address'] = ipprofile.pop('dns-address',None)
- if 'dhcp' in ipprofile:
- ipprofile['dhcp_start_address'] = ipprofile['dhcp'].get('start-address',None)
- ipprofile['dhcp_enabled'] = ipprofile['dhcp'].get('enabled',True)
- ipprofile['dhcp_count'] = ipprofile['dhcp'].get('count',None)
- del ipprofile['dhcp']
+ # translate from input format to database format
+ ipprofile_in = net_instance_desc['ip-profile']
+ ipprofile_db = {}
+ ipprofile_db['subnet_address'] = ipprofile_in.get('subnet-address')
+ ipprofile_db['ip_version'] = ipprofile_in.get('ip-version', 'IPv4')
+ ipprofile_db['gateway_address'] = ipprofile_in.get('gateway-address')
+ ipprofile_db['dns_address'] = ipprofile_in.get('dns-address')
+ if isinstance(ipprofile_db['dns_address'], (list, tuple)):
+ ipprofile_db['dns_address'] = ";".join(ipprofile_db['dns_address'])
+ if 'dhcp' in ipprofile_in:
+ ipprofile_db['dhcp_start_address'] = ipprofile_in['dhcp'].get('start-address')
+ ipprofile_db['dhcp_enabled'] = ipprofile_in['dhcp'].get('enabled', True)
+ ipprofile_db['dhcp_count'] = ipprofile_in['dhcp'].get('count' )
if 'ip_profile' not in scenario_net:
- scenario_net['ip_profile'] = ipprofile
+ scenario_net['ip_profile'] = ipprofile_db
else:
- update(scenario_net['ip_profile'],ipprofile)
+ update(scenario_net['ip_profile'], ipprofile_db)
for interface in net_instance_desc.get('interfaces', () ):
if 'ip_address' in interface:
for vnf in scenarioDict['vnfs']:
def associate_datacenter_to_tenant(mydb, nfvo_tenant, datacenter, vim_tenant_id=None, vim_tenant_name=None, vim_username=None, vim_password=None, config=None):
#get datacenter info
- datacenter_id, myvim = get_datacenter_by_name_uuid(mydb, None, datacenter)
+ datacenter_id, myvim = get_datacenter_by_name_uuid(mydb, None, datacenter, vim_user=vim_username, vim_passwd=vim_password)
datacenter_name = myvim["name"]
create_vim_tenant = True if not vim_tenant_id and not vim_tenant_name else False
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