global global_config
global vimconn_imported
+global logger
vimconn_imported={} #dictionary with VIM type as key, loaded module as value
-logger = logging.getLogger('mano.nfvo')
+logger = logging.getLogger('openmano.nfvo')
class NfvoException(Exception):
def __init__(self, message, http_code):
imageList.append(image['image_id'])
return imageList
-def get_vim(mydb, nfvo_tenant=None, datacenter_id=None, datacenter_name=None, vim_tenant=None):
+def get_vim(mydb, nfvo_tenant=None, datacenter_id=None, datacenter_name=None, vim_tenant=None, vim_tenant_name=None, vim_user=None, vim_passwd=None):
'''Obtain a dictionary of VIM (datacenter) classes with some of the input parameters
return dictionary with {datacenter_id: vim_class, ... }. vim_class contain:
'nfvo_tenant_id','datacenter_id','vim_tenant_id','vim_url','vim_url_admin','datacenter_name','type','user','passwd'
# return -HTTP_Bad_Request, "You must provide a valid tenant name or uuid for VIM %s" % ( vim["type"])
vim_dict[ vim['datacenter_id'] ] = vimconn_imported[ vim["type"] ].vimconnector(
uuid=vim['datacenter_id'], name=vim['datacenter_name'],
- tenant_id=vim.get('vim_tenant_id'), tenant_name=vim.get('vim_tenant_name'),
+ tenant_id=vim.get('vim_tenant_id',vim_tenant), tenant_name=vim.get('vim_tenant_name',vim_tenant_name),
url=vim['vim_url'], url_admin=vim['vim_url_admin'],
- user=vim.get('user'), passwd=vim.get('passwd'),
+ user=vim.get('user',vim_user), passwd=vim.get('passwd',vim_passwd),
config=extra
)
except Exception as e:
if only_create_at_vim:
image_mano_id = image_dict['uuid']
else:
- images = mydb.get_rows(FROM="images", WHERE={'location':image_dict['location'], 'metadata':image_dict['metadata']})
+ if image_dict['location'] is not None:
+ images = mydb.get_rows(FROM="images", WHERE={'location':image_dict['location'], 'metadata':image_dict['metadata']})
+ else:
+ images = mydb.get_rows(FROM="images", WHERE={'universal_name':image_dict['universal_name'], 'checksum':image_dict['checksum']})
if len(images)>=1:
image_mano_id = images[0]['uuid']
else:
#create image
temp_image_dict={'name':image_dict['name'], 'description':image_dict.get('description',None),
- 'location':image_dict['location'], 'metadata':image_dict.get('metadata',None)
+ 'location':image_dict['location'], 'metadata':image_dict.get('metadata',None),
+ 'universal_name':image_dict['universal_name'] , 'checksum':image_dict['checksum']
}
image_mano_id = mydb.new_row('images', temp_image_dict, add_uuid=True)
rollback_list.append({"where":"mano", "what":"image","uuid":image_mano_id})
image_db = mydb.get_rows(FROM="datacenters_images", WHERE={'datacenter_id':vim_id, 'image_id':image_mano_id})
#look at VIM if this image exist
try:
- image_vim_id = vim.get_image_id_from_path(image_dict['location'])
+ if image_dict['location'] is not None:
+ image_vim_id = vim.get_image_id_from_path(image_dict['location'])
+ else:
+ filter_dict={}
+ filter_dict['name']=image_dict['universal_name']
+ filter_dict['checksum']=image_dict['checksum']
+ #logger.debug('>>>>>>>> Filter dict: %s', str(filter_dict))
+ vim_images = vim.get_image_list(filter_dict)
+ if len(vim_images) > 1:
+ raise NfvoException("More than one candidate VIM image found for filter: " + str(filter_dict), HTTP_Conflict)
+ elif len(vim_images) == 0:
+ raise NfvoException("Image not found at VIM with filter: '%s'", str(filter_dict))
+ else:
+ image_vim_id = vim_images[0].id
+
except vimconn.vimconnNotFoundException as e:
#Create the image in VIM
try:
logger.warn("Error creating image at VIM: %s", str(e))
continue
except vimconn.vimconnException as e:
- logger.warn("Error contacting VIM to know if the image exist at VIM: %s", str(e))
+ logger.warn("Error contacting VIM to know if the image exists at VIM: %s", str(e))
image_vim_id = str(e)
continue
- #if reach here the image has been create or exist
+ #if we reach here, the image has been created or existed
if len(image_db)==0:
#add new vim_id at datacenters_images
mydb.new_row('datacenters_images', {'datacenter_id':vim_id, 'image_id':image_mano_id, 'vim_id': image_vim_id, 'created':image_created})
if 'extended' in flavor_dict and flavor_dict['extended']!=None:
dev_nb=0
for device in flavor_dict['extended'].get('devices',[]):
- if "image" not in device:
+ if "image" not in device and "image name" not in device:
continue
- image_dict={'location':device['image'], 'name':flavor_dict['name']+str(dev_nb)+"-img", 'description':flavor_dict.get('description')}
+ image_dict={}
+ image_dict['name']=device.get('image name',flavor_dict['name']+str(dev_nb)+"-img")
+ image_dict['universal_name']=device.get('image name')
+ image_dict['description']=flavor_dict['name']+str(dev_nb)+"-img"
+ image_dict['location']=device.get('image')
+ image_dict['checksum']=device.get('image checksum')
image_metadata_dict = device.get('image metadata', None)
image_metadata_str = None
if image_metadata_dict != None:
dev_nb=0
for index in range(0,len(devices_original)) :
device=devices_original[index]
- if "image" not in device:
+ if "image" not in device or "image name" not in device:
continue
- image_dict={'location':device['image'], 'name':flavor_dict['name']+str(dev_nb)+"-img", 'description':flavor_dict.get('description')}
+ image_dict={}
+ image_dict['name']=device.get('image name',flavor_dict['name']+str(dev_nb)+"-img")
+ image_dict['universal_name']=device.get('image name')
+ image_dict['description']=flavor_dict['name']+str(dev_nb)+"-img"
+ image_dict['location']=device.get('image')
+ image_dict['checksum']=device.get('image checksum')
image_metadata_dict = device.get('image metadata', None)
image_metadata_str = None
if image_metadata_dict != None:
#print "Flavor name: %s. Description: %s" % (VNFCitem["name"]+"-flv", VNFCitem["description"])
myflavorDict = {}
- myflavorDict["name"] = vnfc['name']+"-flv"
+ myflavorDict["name"] = vnfc['name']+"-flv" #Maybe we could rename the flavor by using the field "image name" if exists
myflavorDict["description"] = VNFCitem["description"]
myflavorDict["ram"] = vnfc.get("ram", 0)
myflavorDict["vcpus"] = vnfc.get("vcpus", 0)
#In case this integration is made, the VNFCDict might become a VNFClist.
for vnfc in vnf_descriptor['vnf']['VNFC']:
#print "Image name: %s. Description: %s" % (vnfc['name']+"-img", VNFCDict[vnfc['name']]['description'])
- image_dict={'location':vnfc['VNFC image'], 'name':vnfc['name']+"-img", 'description':VNFCDict[vnfc['name']]['description']}
+ image_dict={}
+ image_dict['name']=vnfc.get('image name',vnf_name+"-"+vnfc['name']+"-img")
+ image_dict['universal_name']=vnfc.get('image name')
+ image_dict['description']=vnfc.get('image name', VNFCDict[vnfc['name']]['description'])
+ image_dict['location']=vnfc.get('VNFC image')
+ image_dict['checksum']=vnfc.get('image checksum')
image_metadata_dict = vnfc.get('image metadata', None)
image_metadata_str = None
if image_metadata_dict is not None:
image_id = create_or_use_image(mydb, vims, image_dict, rollback_list)
#print "Image id for VNFC %s: %s" % (vnfc['name'],image_id)
VNFCDict[vnfc['name']]["image_id"] = image_id
- VNFCDict[vnfc['name']]["image_path"] = vnfc['VNFC image']
+ VNFCDict[vnfc['name']]["image_path"] = vnfc.get('VNFC image')
# Step 7. Storing the VNF descriptor in the repository
#print "Flavor name: %s. Description: %s" % (VNFCitem["name"]+"-flv", VNFCitem["description"])
myflavorDict = {}
- myflavorDict["name"] = vnfc['name']+"-flv"
+ myflavorDict["name"] = vnfc['name']+"-flv" #Maybe we could rename the flavor by using the field "image name" if exists
myflavorDict["description"] = VNFCitem["description"]
myflavorDict["ram"] = vnfc.get("ram", 0)
myflavorDict["vcpus"] = vnfc.get("vcpus", 0)
#In case this integration is made, the VNFCDict might become a VNFClist.
for vnfc in vnf_descriptor['vnf']['VNFC']:
#print "Image name: %s. Description: %s" % (vnfc['name']+"-img", VNFCDict[vnfc['name']]['description'])
- image_dict={'location':vnfc['VNFC image'], 'name':vnfc['name']+"-img", 'description':VNFCDict[vnfc['name']]['description']}
+ image_dict={}
+ image_dict['name']=vnfc.get('image name',vnf_name+"-"+vnfc['name']+"-img")
+ image_dict['universal_name']=vnfc.get('image name')
+ image_dict['description']=vnfc.get('image name', VNFCDict[vnfc['name']]['description'])
+ image_dict['location']=vnfc.get('VNFC image')
+ image_dict['checksum']=vnfc.get('image checksum')
image_metadata_dict = vnfc.get('image metadata', None)
image_metadata_str = None
if image_metadata_dict is not None:
image_id = create_or_use_image(mydb, vims, image_dict, rollback_list)
#print "Image id for VNFC %s: %s" % (vnfc['name'],image_id)
VNFCDict[vnfc['name']]["image_id"] = image_id
- VNFCDict[vnfc['name']]["image_path"] = vnfc['VNFC image']
+ VNFCDict[vnfc['name']]["image_path"] = vnfc.get('VNFC image')
# Step 7. Storing the VNF descriptor in the repository
#1.4 get list of connections
conections = topo['topology']['connections']
conections_list = []
+ conections_list_name = []
for k in conections.keys():
if type(conections[k]['nodes'])==dict: #dict with node:iface pairs
ifaces_list = conections[k]['nodes'].items()
if con_type == "dataplane_net" or con_type == "bridge_net":
other_nets[k]["model"] = con_type
-
+ conections_list_name.append(k)
conections_list.append(set(ifaces_list)) #from list to set to operate as a set (this conversion removes elements that are repeated in a list)
#print set(ifaces_list)
#check valid VNF and iface names
if len(conections_list[index] & conections_list[index2])>0: #common interface, join nets
conections_list[index] |= conections_list[index2]
del conections_list[index2]
+ del conections_list_name[index2]
else:
index2 += 1
conections_list[index] = list(conections_list[index]) # from set to list again
net_type_bridge=False
net_type_data=False
net_target = "__-__net"+str(net_nb)
- net_list[net_target] = {'name': "net-"+str(net_nb), 'description':"net-%s in scenario %s" %(net_nb,topo['name']),
+ net_list[net_target] = {'name': conections_list_name[net_nb], #"net-"+str(net_nb),
+ 'description':"net-%s in scenario %s" %(net_nb,topo['name']),
'external':False}
for iface in con:
vnfs[ iface[0] ]['ifaces'][ iface[1] ]['net_key'] = net_target
where={}
where_or={"tenant_id": tenant_id, 'public': "true"}
error_text = ""
- error_pos = "'topology':'nodes':'" + name + "'"
+ error_pos = "'scenario':'vnfs':'" + name + "'"
if 'vnf_id' in vnf:
error_text += " 'vnf_id' " + vnf['vnf_id']
where['uuid'] = vnf['vnf_id']
error_text += " 'vnf_name' " + vnf['vnf_name']
where['name'] = vnf['vnf_name']
if len(where) == 0:
- raise NfvoException("Needed a 'vnf_id' or 'VNF model' at " + error_pos, HTTP_Bad_Request)
+ raise NfvoException("Needed a 'vnf_id' or 'vnf_name' at " + error_pos, HTTP_Bad_Request)
vnf_db = mydb.get_rows(SELECT=('uuid','name','description'),
FROM='vnfs',
WHERE=where,
sce_net['vim_id'] = network_id
auxNetDict['scenario'][sce_net['uuid']] = network_id
rollbackList.append({'what':'network','where':'vim','vim_id':datacenter_id,'uuid':network_id})
+ sce_net["created"] = True
else:
if sce_net['vim_id'] == None:
error_text = "Error, datacenter '%s' does not have external network '%s'." % (datacenter_name, sce_net['name'])
auxNetDict[sce_vnf['uuid']] = {}
auxNetDict[sce_vnf['uuid']][net['uuid']] = network_id
rollbackList.append({'what':'network','where':'vim','vim_id':datacenter_id,'uuid':network_id})
+ net["created"] = True
#print "auxNetDict:"
#print yaml.safe_dump(auxNetDict, indent=4, default_flow_style=False)
where={}
where_or={"tenant_id": tenant_id, 'public': "true"}
error_text = ""
- error_pos = "'topology':'nodes':'" + name + "'"
+ error_pos = "'scenario':'vnfs':'" + name + "'"
if 'vnf_id' in vnf:
error_text += " 'vnf_id' " + vnf['vnf_id']
where['uuid'] = vnf['vnf_id']
error_text += " 'vnf_name' " + vnf['vnf_name']
where['name'] = vnf['vnf_name']
if len(where) == 0:
- raise NfvoException("Needed a 'vnf_id' or 'VNF model' at " + error_pos, HTTP_Bad_Request)
+ raise NfvoException("Needed a 'vnf_id' or 'vnf_name' at " + error_pos, HTTP_Bad_Request)
vnf_db = mydb.get_rows(SELECT=('uuid','name','description'),
FROM='vnfs',
WHERE=where,
def create_instance(mydb, tenant_id, instance_dict):
#print "Checking that nfvo_tenant_id exists and getting the VIM URI and the VIM tenant_id"
- logger.debug("Creating instance...")
+ #logger.debug("Creating instance...")
scenario = instance_dict["scenario"]
#find main datacenter
#print "Checking that the scenario exists and getting the scenario dictionary"
scenarioDict = mydb.get_scenario(scenario, tenant_id, default_datacenter_id)
- #logger.debug("Dictionaries before merging")
- #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)))
+ #logger.debug(">>>>>>> Dictionaries before merging")
+ #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_tenant_id'] = default_datacenter_tenant_id
scenarioDict['datacenter_id'] = default_datacenter_id
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("scenario dict: {}".format(yaml.safe_dump(scenarioDict, indent=4, default_flow_style=False))) #TODO remove
+ 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:
ipprofile['dhcp_enabled'] = ipprofile['dhcp'].get('enabled',True)
ipprofile['dhcp_count'] = ipprofile['dhcp'].get('count',None)
del ipprofile['dhcp']
- update(scenario_net['ip_profile'],ipprofile)
- for interface in net_instance_desc['interfaces']:
+ if 'ip_profile' not in scenario_net:
+ scenario_net['ip_profile'] = ipprofile
+ else:
+ update(scenario_net['ip_profile'],ipprofile)
+ for interface in net_instance_desc.get('interfaces', () ):
if 'ip_address' in interface:
for vnf in scenarioDict['vnfs']:
if interface['vnf'] == vnf['name']:
if interface['vnf_interface'] == vnf_interface['external_name']:
vnf_interface['ip_address']=interface['ip_address']
- logger.debug("Merged dictionary")
- logger.debug("ScenarioDict:\n{}".format(yaml.safe_dump(scenarioDict,default_flow_style=False, width=256)))
+ #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"
sce_net["vim_id_sites"][datacenter_id] = network_id
auxNetDict['scenario'][sce_net['uuid']][datacenter_id] = network_id
rollbackList.append({'what':'network', 'where':'vim', 'vim_id':datacenter_id, 'uuid':network_id})
+ sce_net["created"] = True
#2. Creating new nets (vnf internal nets) in the VIM"
#For each vnf net, we create it and we add it to instanceNetlist.
auxNetDict[sce_vnf['uuid']] = {}
auxNetDict[sce_vnf['uuid']][net['uuid']] = network_id
rollbackList.append({'what':'network','where':'vim','vim_id':datacenter_id,'uuid':network_id})
+ net["created"] = True
+
#print "auxNetDict:"
#print yaml.safe_dump(auxNetDict, indent=4, default_flow_style=False)
#2.2 deleting NETS
#net_fail_list=[]
for net in instanceDict['nets']:
- if net['external']:
+ if not net['created']:
continue #skip not created nets
if not myvim:
continue
if iface["type"]=="mgmt":
has_mgmt_iface = True
if vm_dict[vm_id]['status'] == "ACTIVE:NoMgmtIP" and not has_mgmt_iface:
- vm_dict[vm_id]['status'] = "ACTIVE"
+ vm_dict[vm_id]['status'] = "ACTIVE"
if vm['status'] != vm_dict[vm_id]['status'] or vm.get('error_msg')!=vm_dict[vm_id].get('error_msg') or vm.get('vim_info')!=vm_dict[vm_id].get('vim_info'):
vm['status'] = vm_dict[vm_id]['status']
vm['error_msg'] = vm_dict[vm_id].get('error_msg')
# 2.2. Update in openmano DB the interface VMs
for interface in interfaces:
#translate from vim_net_id to instance_net_id
- network_id=None
+ network_id_list=[]
for net in instanceDict['nets']:
if net["vim_net_id"] == interface["vim_net_id"]:
- network_id = net["uuid"]
- break
- if not network_id:
+ network_id_list.append(net["uuid"])
+ if not network_id_list:
continue
del interface["vim_net_id"]
- try:
- mydb.update_rows('instance_interfaces', UPDATE=interface, WHERE={'instance_vm_id':vm["uuid"], "instance_net_id":network_id})
+ try:
+ for network_id in network_id_list:
+ mydb.update_rows('instance_interfaces', UPDATE=interface, WHERE={'instance_vm_id':vm["uuid"], "instance_net_id":network_id})
except db_base_Exception as e:
logger.error( "nfvo.refresh_instance error with vm=%s, interface_net_id=%s", vm["uuid"], network_id)
def new_datacenter(mydb, datacenter_descriptor):
if "config" in datacenter_descriptor:
datacenter_descriptor["config"]=yaml.safe_dump(datacenter_descriptor["config"],default_flow_style=True,width=256)
+ #Check that datacenter-type is correct
+ datacenter_type = datacenter_descriptor.get("type", "openvim");
+ module_info = None
+ try:
+ module = "vimconn_" + datacenter_type
+ module_info = imp.find_module(module)
+ except (IOError, ImportError):
+ if module_info and module_info[0]:
+ file.close(module_info[0])
+ raise NfvoException("Incorrect datacenter type '{}'. Plugin '{}'.py not installed".format(datacenter_type, module), HTTP_Bad_Request)
+
datacenter_id = mydb.new_row("datacenters", datacenter_descriptor, add_uuid=True)
return datacenter_id
def associate_datacenter_to_tenant(mydb, nfvo_tenant, datacenter, vim_tenant_id=None, vim_tenant_name=None, vim_username=None, vim_password=None):
#get datacenter info
if utils.check_valid_uuid(datacenter):
- vims = get_vim(mydb, datacenter_id=datacenter)
+ vims = get_vim(mydb, datacenter_id=datacenter, vim_tenant_name=vim_tenant_name, vim_user=vim_username, vim_passwd=vim_password)
else:
- vims = get_vim(mydb, datacenter_name=datacenter)
+ vims = get_vim(mydb, datacenter_name=datacenter, vim_tenant_name=vim_tenant_name, vim_user=vim_username, vim_passwd=vim_password)
if len(vims) == 0:
raise NfvoException("datacenter '{}' not found".format(str(datacenter)), HTTP_Not_Found)
elif len(vims)>1: