import vimconn
import logging
import collections
+from uuid import uuid4
from db_base import db_base_Exception
import nfvo_db
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
if item["where"]=="vim":
if item["vim_id"] not in vims:
continue
- vim=vims[ item["vim_id"] ]
+ if is_task_id(item["uuid"]):
+ continue
+ vim = vims[item["vim_id"]]
try:
if item["what"]=="image":
vim.delete_image(item["uuid"])
name_dict[ interface["name"] ] = "overlay"
vnfc_interfaces[ vnfc["name"] ] = name_dict
# check bood-data info
- if "boot-data" in vnfc:
- # check that user-data is incompatible with users and config-files
- if (vnfc["boot-data"].get("users") or vnfc["boot-data"].get("config-files")) and vnfc["boot-data"].get("user-data"):
- raise NfvoException(
- "Error at vnf:VNFC:boot-data, fields 'users' and 'config-files' are not compatible with 'user-data'",
- HTTP_Bad_Request)
+ # if "boot-data" in vnfc:
+ # # check that user-data is incompatible with users and config-files
+ # if (vnfc["boot-data"].get("users") or vnfc["boot-data"].get("config-files")) and vnfc["boot-data"].get("user-data"):
+ # raise NfvoException(
+ # "Error at vnf:VNFC:boot-data, fields 'users' and 'config-files' are not compatible with 'user-data'",
+ # HTTP_Bad_Request)
#check if the info in external_connections matches with the one in the vnfcs
name_list=[]
HTTP_Bad_Request)
-def create_or_use_image(mydb, vims, image_dict, rollback_list, only_create_at_vim=False, return_on_error = None):
+def create_or_use_image(mydb, vims, image_dict, rollback_list, only_create_at_vim=False, return_on_error=None):
#look if image exist
if only_create_at_vim:
image_mano_id = image_dict['uuid']
for vnfc in vnf_descriptor['vnf']['VNFC']:
VNFCitem={}
VNFCitem["name"] = vnfc['name']
+ VNFCitem["availability_zone"] = vnfc.get('availability_zone')
VNFCitem["description"] = vnfc.get("description", 'VM %s of the VNF %s' %(vnfc['name'],vnf_name))
#print "Flavor name: %s. Description: %s" % (VNFCitem["name"]+"-flv", VNFCitem["description"])
#print "Image id for VNFC %s: %s" % (vnfc['name'],image_id)
VNFCDict[vnfc['name']]["image_id"] = image_id
VNFCDict[vnfc['name']]["image_path"] = vnfc.get('VNFC image')
+ VNFCDict[vnfc['name']]["count"] = vnfc.get('count', 1)
if vnfc.get("boot-data"):
VNFCDict[vnfc['name']]["boot_data"] = yaml.safe_dump(vnfc["boot-data"], default_flow_style=True, width=256)
#print "Image id for VNFC %s: %s" % (vnfc['name'],image_id)
VNFCDict[vnfc['name']]["image_id"] = image_id
VNFCDict[vnfc['name']]["image_path"] = vnfc.get('VNFC image')
+ VNFCDict[vnfc['name']]["count"] = vnfc.get('count', 1)
if vnfc.get("boot-data"):
VNFCDict[vnfc['name']]["boot_data"] = yaml.safe_dump(vnfc["boot-data"], default_flow_style=True, width=256)
logger.debug("start_scenario 2. Creating new nets (vnf internal nets) in the VIM")
#For each vnf net, we create it and we add it to instanceNetlist.
+
for sce_vnf in scenarioDict['vnfs']:
for net in sce_vnf['nets']:
#print "Net name: %s. Description: %s" % (net["name"], net["description"])
#myvim.new_vminstance(self,vimURI,tenant_id,name,description,image_id,flavor_id,net_dict)
i = 0
for sce_vnf in scenarioDict['vnfs']:
+ vnf_availability_zones = []
+ for vm in sce_vnf['vms']:
+ vm_av = vm.get('availability_zone')
+ if vm_av and vm_av not in vnf_availability_zones:
+ vnf_availability_zones.append(vm_av)
+
+ # check if there is enough availability zones available at vim level.
+ if myvims[datacenter_id].availability_zone and vnf_availability_zones:
+ if len(vnf_availability_zones) > len(myvims[datacenter_id].availability_zone):
+ raise NfvoException('No enough availability zones at VIM for this deployment', HTTP_Bad_Request)
+
for vm in sce_vnf['vms']:
i += 1
myVMDict = {}
#print "networks", yaml.safe_dump(myVMDict['networks'], indent=4, default_flow_style=False)
#print "interfaces", yaml.safe_dump(vm['interfaces'], indent=4, default_flow_style=False)
#print ">>>>>>>>>>>>>>>>>>>>>>>>>>>"
- vm_id = myvim.new_vminstance(myVMDict['name'],myVMDict['description'],myVMDict.get('start', None),
- myVMDict['imageRef'],myVMDict['flavorRef'],myVMDict['networks'])
+
+ if 'availability_zone' in myVMDict:
+ av_index = vnf_availability_zones.index(myVMDict['availability_zone'])
+ else:
+ av_index = None
+
+ vm_id = myvim.new_vminstance(myVMDict['name'], myVMDict['description'], myVMDict.get('start', None),
+ myVMDict['imageRef'], myVMDict['flavorRef'], myVMDict['networks'],
+ availability_zone_index=av_index,
+ availability_zone_list=vnf_availability_zones)
#print "VIM vm instance id (server id) for scenario %s: %s" % (scenarioDict['name'],vm_id)
vm['vim_id'] = vm_id
rollbackList.append({'what':'vm','where':'vim','vim_id':datacenter_id,'uuid':vm_id})
def unify_cloud_config(cloud_config_preserve, cloud_config):
- ''' join the cloud config information into cloud_config_preserve.
+ """ join the cloud config information into cloud_config_preserve.
In case of conflict cloud_config_preserve preserves
- None is admited
- '''
+ None is allowed
+ """
if not cloud_config_preserve and not cloud_config:
return None
new_cloud_config["boot-data-drive"] = cloud_config_preserve["boot-data-drive"]
# user-data
- if cloud_config and cloud_config.get("user-data") != None:
- new_cloud_config["user-data"] = cloud_config["user-data"]
- if cloud_config_preserve and cloud_config_preserve.get("user-data") != None:
- new_cloud_config["user-data"] = cloud_config_preserve["user-data"]
+ new_cloud_config["user-data"] = []
+ if cloud_config and cloud_config.get("user-data"):
+ if isinstance(cloud_config["user-data"], list):
+ new_cloud_config["user-data"] += cloud_config["user-data"]
+ else:
+ new_cloud_config["user-data"].append(cloud_config["user-data"])
+ if cloud_config_preserve and cloud_config_preserve.get("user-data"):
+ if isinstance(cloud_config_preserve["user-data"], list):
+ new_cloud_config["user-data"] += cloud_config_preserve["user-data"]
+ else:
+ new_cloud_config["user-data"].append(cloud_config_preserve["user-data"])
+ if not new_cloud_config["user-data"]:
+ del new_cloud_config["user-data"]
# config files
new_cloud_config["config-files"] = []
except db_base_Exception as e:
raise NfvoException("{} {}".format(type(e).__name__ , str(e)), e.http_code)
+
def get_datacenter_by_name_uuid(mydb, tenant_id, datacenter_id_name=None, **extra_filter):
datacenter_id = None
datacenter_name = None
#logger.debug(">>>>>>> InstanceDict:\n{}".format(yaml.safe_dump(instance_dict,default_flow_style=False, width=256)))
#logger.debug(">>>>>>> ScenarioDict:\n{}".format(yaml.safe_dump(scenarioDict,default_flow_style=False, width=256)))
- scenarioDict['datacenter_id'] = default_datacenter_id
+ uuid_list = []
+ instance_name = instance_dict["name"]
+ instance_uuid = str(uuid4())
+ uuid_list.append(instance_uuid)
+ db_instance_scenario = {
+ "uuid": instance_uuid,
+ "name": instance_name,
+ "tenant_id": tenant_id,
+ "scenario_id": scenarioDict['uuid'],
+ "datacenter_id": default_datacenter_id,
+ # filled bellow 'datacenter_tenant_id'
+ "description": instance_dict.get("description"),
+ }
+ db_ip_profiles=[]
+ if scenarioDict.get("cloud-config"):
+ db_instance_scenario["cloud_config"] = yaml.safe_dump(scenarioDict["cloud-config"],
+ default_flow_style=True, width=256)
+ vnf_net2instance = {} #Auxiliar dictionary. First key:'scenario' or sce_vnf uuid. Second Key: uuid of the net/sce_net. Value: vim_net_id
+ sce_net2instance = {}
auxNetDict = {} #Auxiliar dictionary. First key:'scenario' or sce_vnf uuid. Second Key: uuid of the net/sce_net. Value: vim_net_id
auxNetDict['scenario'] = {}
logger.debug("Creating instance from scenario-dict:\n%s", yaml.safe_dump(scenarioDict, indent=4, default_flow_style=False)) #TODO remove
- instance_name = instance_dict["name"]
- instance_description = instance_dict.get("description")
try:
# 0 check correct parameters
for net_name, net_instance_desc in instance_dict.get("networks",{}).iteritems():
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']:
#logger.debug(">>>>>>>> Merged dictionary")
logger.debug("Creating instance scenario-dict MERGED:\n%s", yaml.safe_dump(scenarioDict, indent=4, default_flow_style=False))
-
# 1. Creating new nets (sce_nets) in the VIM"
+ db_instance_nets = []
for sce_net in scenarioDict['nets']:
- sce_net["vim_id_sites"]={}
- descriptor_net = instance_dict.get("networks",{}).get(sce_net["name"],{})
+ descriptor_net = instance_dict.get("networks",{}).get(sce_net["name"],{})
net_name = descriptor_net.get("vim-network-name")
+ sce_net2instance[sce_net['uuid']] = {}
auxNetDict['scenario'][sce_net['uuid']] = {}
sites = descriptor_net.get("sites", [ {} ])
if not create_network:
raise NfvoException("No candidate VIM network found for " + filter_text, HTTP_Bad_Request )
else:
- sce_net["vim_id_sites"][datacenter_id] = vim_nets[0]['id']
+ vim_id = vim_nets[0]['id']
auxNetDict['scenario'][sce_net['uuid']][datacenter_id] = vim_nets[0]['id']
create_network = False
if create_network:
instance_tasks[task_id] = task
tasks_to_launch[myvim_thread_id].append(task)
#network_id = vim.new_network(net_vim_name, net_type, sce_net.get('ip_profile',None))
- sce_net["vim_id_sites"][datacenter_id] = task_id
+ vim_id = task_id
auxNetDict['scenario'][sce_net['uuid']][datacenter_id] = task_id
rollbackList.append({'what':'network', 'where':'vim', 'vim_id':datacenter_id, 'uuid':task_id})
sce_net["created"] = True
+ # fill database content
+ net_uuid = str(uuid4())
+ uuid_list.append(net_uuid)
+ sce_net2instance[sce_net['uuid']][datacenter_id] = net_uuid
+ db_net = {
+ "uuid": net_uuid,
+ 'vim_net_id': vim_id,
+ "instance_scenario_id": instance_uuid,
+ "sce_net_id": sce_net["uuid"],
+ "created": create_network,
+ 'datacenter_id': datacenter_id,
+ 'datacenter_tenant_id': myvim_thread_id,
+ 'status': 'BUILD' if create_network else "ACTIVE"
+ }
+ db_instance_nets.append(db_net)
+ if 'ip_profile' in sce_net:
+ db_ip_profile={
+ 'instance_net_id': net_uuid,
+ 'ip_version': sce_net['ip_profile']['ip_version'],
+ 'subnet_address': sce_net['ip_profile']['subnet_address'],
+ 'gateway_address': sce_net['ip_profile']['gateway_address'],
+ 'dns_address': sce_net['ip_profile']['dns_address'],
+ 'dhcp_enabled': sce_net['ip_profile']['dhcp_enabled'],
+ 'dhcp_start_address': sce_net['ip_profile']['dhcp_start_address'],
+ 'dhcp_count': sce_net['ip_profile']['dhcp_count'],
+ }
+ db_ip_profiles.append(db_ip_profile)
+
# 2. Creating new nets (vnf internal nets) in the VIM"
- #For each vnf net, we create it and we add it to instanceNetlist.
+ # For each vnf net, we create it and we add it to instanceNetlist.
for sce_vnf in scenarioDict['vnfs']:
for net in sce_vnf['nets']:
if sce_vnf.get("datacenter"):
instance_tasks[task_id] = task
tasks_to_launch[myvim_thread_id].append(task)
# network_id = vim.new_network(net_name, net_type, net.get('ip_profile',None))
- net['vim_id'] = task_id
+ vim_id = task_id
+ if sce_vnf['uuid'] not in vnf_net2instance:
+ vnf_net2instance[sce_vnf['uuid']] = {}
+ vnf_net2instance[sce_vnf['uuid']][net['uuid']] = task_id
if sce_vnf['uuid'] not in auxNetDict:
auxNetDict[sce_vnf['uuid']] = {}
auxNetDict[sce_vnf['uuid']][net['uuid']] = task_id
rollbackList.append({'what':'network','where':'vim','vim_id':datacenter_id,'uuid':task_id})
net["created"] = True
-
- #print "auxNetDict:"
- #print yaml.safe_dump(auxNetDict, indent=4, default_flow_style=False)
+ # fill database content
+ net_uuid = str(uuid4())
+ uuid_list.append(net_uuid)
+ vnf_net2instance[sce_vnf['uuid']][net['uuid']] = net_uuid
+ db_net = {
+ "uuid": net_uuid,
+ 'vim_net_id': vim_id,
+ "instance_scenario_id": instance_uuid,
+ "net_id": net["uuid"],
+ "created": True,
+ 'datacenter_id': datacenter_id,
+ 'datacenter_tenant_id': myvim_thread_id,
+ }
+ db_instance_nets.append(db_net)
+ if 'ip_profile' in net:
+ db_ip_profile = {
+ 'instance_net_id': net_uuid,
+ 'ip_version': net['ip_profile']['ip_version'],
+ 'subnet_address': net['ip_profile']['subnet_address'],
+ 'gateway_address': net['ip_profile']['gateway_address'],
+ 'dns_address': net['ip_profile']['dns_address'],
+ 'dhcp_enabled': net['ip_profile']['dhcp_enabled'],
+ 'dhcp_start_address': net['ip_profile']['dhcp_start_address'],
+ 'dhcp_count': net['ip_profile']['dhcp_count'],
+ }
+ db_ip_profiles.append(db_ip_profile)
+
+ #print "vnf_net2instance:"
+ #print yaml.safe_dump(vnf_net2instance, indent=4, default_flow_style=False)
# 3. Creating new vm instances in the VIM
+ db_instance_vnfs = []
+ db_instance_vms = []
+ db_instance_interfaces = []
#myvim.new_vminstance(self,vimURI,tenant_id,name,description,image_id,flavor_id,net_dict)
- for sce_vnf in scenarioDict['vnfs']:
+ sce_vnf_list = sorted(scenarioDict['vnfs'], key=lambda k: k['name'])
+ #for sce_vnf in scenarioDict['vnfs']:
+ for sce_vnf in sce_vnf_list:
+ vnf_availability_zones = []
+ for vm in sce_vnf['vms']:
+ vm_av = vm.get('availability_zone')
+ if vm_av and vm_av not in vnf_availability_zones:
+ vnf_availability_zones.append(vm_av)
+
+ # check if there is enough availability zones available at vim level.
+ if myvims[datacenter_id].availability_zone and vnf_availability_zones:
+ if len(vnf_availability_zones) > len(myvims[datacenter_id].availability_zone):
+ raise NfvoException('No enough availability zones at VIM for this deployment', HTTP_Bad_Request)
+
if sce_vnf.get("datacenter"):
vim = myvims[ sce_vnf["datacenter"] ]
myvim_thread_id = myvim_threads_id[ sce_vnf["datacenter"] ]
vim = myvims[ default_datacenter_id ]
myvim_thread_id = myvim_threads_id[ default_datacenter_id ]
datacenter_id = default_datacenter_id
- sce_vnf["datacenter_id"] = datacenter_id
+ sce_vnf["datacenter_id"] = datacenter_id
i = 0
+
+ vnf_uuid = str(uuid4())
+ uuid_list.append(vnf_uuid)
+ db_instance_vnf = {
+ 'uuid': vnf_uuid,
+ 'instance_scenario_id': instance_uuid,
+ 'vnf_id': sce_vnf['vnf_id'],
+ 'sce_vnf_id': sce_vnf['uuid'],
+ 'datacenter_id': datacenter_id,
+ 'datacenter_tenant_id': myvim_thread_id,
+ }
+ db_instance_vnfs.append(db_instance_vnf)
+
for vm in sce_vnf['vms']:
- i += 1
myVMDict = {}
- myVMDict['name'] = "{}.{}.{}".format(instance_name,sce_vnf['name'],chr(96+i))
+ myVMDict['name'] = "{}.{}.{}".format(instance_name[:64], sce_vnf['name'][:64], vm["name"][:64])
myVMDict['description'] = myVMDict['name'][0:99]
# if not startvms:
# myVMDict['start'] = "no"
vm['vim_flavor_id'] = flavor_id
myVMDict['imageRef'] = vm['vim_image_id']
myVMDict['flavorRef'] = vm['vim_flavor_id']
+ myVMDict['availability_zone'] = vm.get('availability_zone')
myVMDict['networks'] = []
task_depends = {}
#TODO ALF. connect_mgmt_interfaces. Connect management interfaces if this is true
+ db_vm_ifaces = []
for iface in vm['interfaces']:
netDict = {}
if iface['type']=="data":
#print vnf_iface
if vnf_iface['interface_id']==iface['uuid']:
netDict['net_id'] = auxNetDict['scenario'][ vnf_iface['sce_net_id'] ][datacenter_id]
+ instance_net_id = sce_net2instance[ vnf_iface['sce_net_id'] ][datacenter_id]
break
else:
netDict['net_id'] = auxNetDict[ sce_vnf['uuid'] ][ iface['net_id'] ]
+ instance_net_id = vnf_net2instance[ sce_vnf['uuid'] ][ iface['net_id'] ]
if netDict.get('net_id') and is_task_id(netDict['net_id']):
task_depends[netDict['net_id']] = instance_tasks[netDict['net_id']]
#skip bridge ifaces not connected to any net
#if 'net_id' not in netDict or netDict['net_id']==None:
# continue
myVMDict['networks'].append(netDict)
- #print ">>>>>>>>>>>>>>>>>>>>>>>>>>>"
- #print myVMDict['name']
- #print "networks", yaml.safe_dump(myVMDict['networks'], indent=4, default_flow_style=False)
- #print "interfaces", yaml.safe_dump(vm['interfaces'], indent=4, default_flow_style=False)
- #print ">>>>>>>>>>>>>>>>>>>>>>>>>>>"
+ db_vm_iface={
+ # "uuid"
+ # 'instance_vm_id': instance_vm_uuid,
+ "instance_net_id": instance_net_id,
+ 'interface_id': iface['uuid'],
+ # 'vim_interface_id': ,
+ 'type': 'external' if iface['external_name'] is not None else 'internal',
+ 'ip_address': iface.get('ip_address'),
+ 'floating_ip': int(iface.get('floating-ip', False)),
+ 'port_security': int(iface.get('port-security', True))
+ }
+ db_vm_ifaces.append(db_vm_iface)
+ # print ">>>>>>>>>>>>>>>>>>>>>>>>>>>"
+ # print myVMDict['name']
+ # print "networks", yaml.safe_dump(myVMDict['networks'], indent=4, default_flow_style=False)
+ # print "interfaces", yaml.safe_dump(vm['interfaces'], indent=4, default_flow_style=False)
+ # print ">>>>>>>>>>>>>>>>>>>>>>>>>>>"
if vm.get("boot_data"):
cloud_config_vm = unify_cloud_config(vm["boot_data"], cloud_config)
else:
cloud_config_vm = cloud_config
- task = new_task("new-vm", (myVMDict['name'], myVMDict['description'], myVMDict.get('start', None),
- myVMDict['imageRef'], myVMDict['flavorRef'], myVMDict['networks'],
- cloud_config_vm, myVMDict['disks']), depends=task_depends)
- instance_tasks[task["id"]] = task
- tasks_to_launch[myvim_thread_id].append(task)
- vm_id = task["id"]
- vm['vim_id'] = vm_id
- rollbackList.append({'what':'vm','where':'vim','vim_id':datacenter_id,'uuid':vm_id})
- #put interface uuid back to scenario[vnfs][vms[[interfaces]
- for net in myVMDict['networks']:
- if "vim_id" in net:
- for iface in vm['interfaces']:
- if net["name"]==iface["internal_name"]:
- iface["vim_id"]=net["vim_id"]
- break
+ if myVMDict.get('availability_zone'):
+ av_index = vnf_availability_zones.index(myVMDict['availability_zone'])
+ else:
+ av_index = None
+ for vm_index in range(0, vm.get('count', 1)):
+ vm_index_name = ""
+ if vm.get('count', 1) > 1:
+ vm_index_name += "." + chr(97 + vm_index)
+ task = new_task("new-vm", (myVMDict['name']+vm_index_name, myVMDict['description'],
+ myVMDict.get('start', None), myVMDict['imageRef'],
+ myVMDict['flavorRef'], myVMDict['networks'],
+ cloud_config_vm, myVMDict['disks'], av_index,
+ vnf_availability_zones), depends=task_depends)
+ instance_tasks[task["id"]] = task
+ tasks_to_launch[myvim_thread_id].append(task)
+ vm_id = task["id"]
+ vm['vim_id'] = vm_id
+ rollbackList.append({'what':'vm','where':'vim','vim_id':datacenter_id,'uuid':vm_id})
+ # put interface uuid back to scenario[vnfs][vms[[interfaces]
+ for net in myVMDict['networks']:
+ if "vim_id" in net:
+ for iface in vm['interfaces']:
+ if net["name"]==iface["internal_name"]:
+ iface["vim_id"]=net["vim_id"]
+ break
+ vm_uuid = str(uuid4())
+ uuid_list.append(vm_uuid)
+ db_vm = {
+ "uuid": vm_uuid,
+ 'instance_vnf_id': vnf_uuid,
+ "vim_vm_id": vm_id,
+ "vm_id": vm["uuid"],
+ # "status":
+ }
+ db_instance_vms.append(db_vm)
+ for db_vm_iface in db_vm_ifaces:
+ iface_uuid = str(uuid4())
+ uuid_list.append(iface_uuid)
+ db_vm_iface_instance = {
+ "uuid": iface_uuid,
+ "instance_vm_id": vm_uuid
+ }
+ db_vm_iface_instance.update(db_vm_iface)
+ if db_vm_iface_instance.get("ip_address"): # increment ip_address
+ ip = db_vm_iface_instance.get("ip_address")
+ i = ip.rfind(".")
+ if i > 0:
+ try:
+ i += 1
+ ip = ip[i:] + str(int(ip[:i]) +1)
+ db_vm_iface_instance["ip_address"] = ip
+ except:
+ db_vm_iface_instance["ip_address"] = None
+ db_instance_interfaces.append(db_vm_iface_instance)
+
scenarioDict["datacenter2tenant"] = myvim_threads_id
+
+ db_instance_scenario['datacenter_tenant_id'] = myvim_threads_id[default_datacenter_id]
+ db_instance_scenario['datacenter_id'] = default_datacenter_id
+ db_tables=[
+ {"instance_scenarios": db_instance_scenario},
+ {"instance_vnfs": db_instance_vnfs},
+ {"instance_nets": db_instance_nets},
+ {"ip_profiles": db_ip_profiles},
+ {"instance_vms": db_instance_vms},
+ {"instance_interfaces": db_instance_interfaces},
+ ]
+
logger.debug("create_instance Deployment done scenarioDict: %s",
- yaml.safe_dump(scenarioDict, indent=4, default_flow_style=False) )
- instance_id = mydb.new_instance_scenario_as_a_whole(tenant_id,instance_name, instance_description, scenarioDict)
+ yaml.safe_dump(db_tables, indent=4, default_flow_style=False) )
+ mydb.new_rows(db_tables, uuid_list)
for myvim_thread_id,task_list in tasks_to_launch.items():
for task in task_list:
vim_threads["running"][myvim_thread_id].insert_task(task)
- global_instance_tasks[instance_id] = instance_tasks
+ global_instance_tasks[instance_uuid] = instance_tasks
# Update database with those ended instance_tasks
# for task in instance_tasks.values():
# if task["status"] == "ok":
# elif task["name"] == "new-net":
# mydb.update_rows("instance_nets", UPDATE={"vim_net_id": task["result"]},
# WHERE={"vim_net_id": task["id"]})
- return mydb.get_instance_scenario(instance_id)
+ return mydb.get_instance_scenario(instance_uuid)
except (NfvoException, vimconn.vimconnException,db_base_Exception) as e:
message = rollback(mydb, myvims, rollbackList)
if isinstance(e, db_base_Exception):
def edit_datacenter(mydb, datacenter_id_name, datacenter_descriptor):
- #obtain data, check that only one exist
+ # obtain data, check that only one exist
datacenter = mydb.get_table_by_uuid_name('datacenters', datacenter_id_name)
- #edit data
+
+ # edit data
datacenter_id = datacenter['uuid']
where={'uuid': datacenter['uuid']}
+ remove_port_mapping = False
if "config" in datacenter_descriptor:
- if datacenter_descriptor['config']!=None:
+ if datacenter_descriptor['config'] != None:
try:
new_config_dict = datacenter_descriptor["config"]
#delete null fields
to_delete=[]
for k in new_config_dict:
- if new_config_dict[k]==None:
+ if new_config_dict[k] == None:
to_delete.append(k)
+ if k == 'sdn-controller':
+ remove_port_mapping = True
config_text = datacenter.get("config")
if not config_text:
del config_dict[k]
except Exception as e:
raise NfvoException("Bad format at datacenter:config " + str(e), HTTP_Bad_Request)
- datacenter_descriptor["config"]= yaml.safe_dump(config_dict,default_flow_style=True,width=256) if len(config_dict)>0 else None
+ if config_dict:
+ datacenter_descriptor["config"] = yaml.safe_dump(config_dict, default_flow_style=True, width=256)
+ else:
+ datacenter_descriptor["config"] = None
+ if remove_port_mapping:
+ try:
+ datacenter_sdn_port_mapping_delete(mydb, None, datacenter_id)
+ except ovimException as e:
+ logger.error("Error deleting datacenter-port-mapping " + str(e))
+
mydb.update_rows('datacenters', datacenter_descriptor, where)
return datacenter_id
#get nfvo_tenant info
datacenter_dict = mydb.get_table_by_uuid_name('datacenters', datacenter, 'datacenter')
mydb.delete_row_by_id("datacenters", datacenter_dict['uuid'])
+ try:
+ datacenter_sdn_port_mapping_delete(mydb, None, datacenter_dict['uuid'])
+ except ovimException as e:
+ logger.error("Error deleting datacenter-port-mapping " + str(e))
return datacenter_dict['uuid'] + " " + datacenter_dict['name']
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