X-Git-Url: https://osm.etsi.org/gitweb/?p=osm%2FRO.git;a=blobdiff_plain;f=osm_ro%2Fnfvo.py;h=cfd2b43ddbb0d259fa711cde9512115ee338f30a;hp=02413234b0ec6c417fd5dbcdafbfb1c84db90fc6;hb=b699079de277df00143b293e9d0e1b04ea54a1b8;hpb=e72710b0ac189586e822a71a611f87fdce6a917d diff --git a/osm_ro/nfvo.py b/osm_ro/nfvo.py index 02413234..cfd2b43d 100644 --- a/osm_ro/nfvo.py +++ b/osm_ro/nfvo.py @@ -1,7 +1,7 @@ # -*- coding: utf-8 -*- ## -# Copyright 2015 Telefónica Investigación y Desarrollo, S.A.U. +# Copyright 2015 Telefonica Investigacion y Desarrollo, S.A.U. # This file is part of openmano # All Rights Reserved. # @@ -31,6 +31,7 @@ __date__ ="$16-sep-2014 22:05:01$" # import json import yaml import utils +from utils import deprecated import vim_thread from db_base import HTTP_Unauthorized, HTTP_Bad_Request, HTTP_Internal_Server_Error, HTTP_Not_Found,\ HTTP_Conflict, HTTP_Method_Not_Allowed @@ -721,8 +722,8 @@ def create_or_use_flavor(mydb, vims, flavor_dict, rollback_list, only_create_at_ for index in range(0,len(devices_original)) : device=devices_original[index] if "image" not in device and "image name" not in device: - if 'size' in device: - disk_list.append({'size': device.get('size', default_volume_size), 'name': device.get('name')}) + # if 'size' in device: + disk_list.append({'size': device.get('size', default_volume_size), 'name': device.get('name')}) continue image_dict={} image_dict['name']=device.get('image name',flavor_dict['name']+str(dev_nb)+"-img") @@ -942,6 +943,7 @@ def new_vnfd_v3(mydb, tenant_id, vnf_descriptor): cp_name2iface_uuid = {} cp_name2vm_uuid = {} cp_name2db_interface = {} + vdu_id2cp_name = {} # stored only when one external connection point is presented at this VDU # table vms (vdus) vdu_id2uuid = {} @@ -959,6 +961,7 @@ def new_vnfd_v3(mydb, tenant_id, vnf_descriptor): "osm_id": vdu_id, "name": get_str(vdu, "name", 255), "description": get_str(vdu, "description", 255), + "pdu_type": get_str(vdu, "pdu-type", 255), "vnf_id": vnf_uuid, } vdu_id2uuid[db_vm["osm_id"]] = vm_uuid @@ -1048,7 +1051,6 @@ def new_vnfd_v3(mydb, tenant_id, vnf_descriptor): # table interfaces (internal/external interfaces) flavor_epa_interfaces = [] - vdu_id2cp_name = {} # stored only when one external connection point is presented at this VDU # for iface in chain(vdu.get("internal-interface").itervalues(), vdu.get("external-interface").itervalues()): for iface in vdu.get("interface").itervalues(): flavor_epa_interface = {} @@ -1071,7 +1073,7 @@ def new_vnfd_v3(mydb, tenant_id, vnf_descriptor): if iface.get("virtual-interface").get("type") == "OM-MGMT": db_interface["type"] = "mgmt" - elif iface.get("virtual-interface").get("type") in ("VIRTIO", "E1000"): + elif iface.get("virtual-interface").get("type") in ("VIRTIO", "E1000", "PARAVIRT"): db_interface["type"] = "bridge" db_interface["model"] = get_str(iface.get("virtual-interface"), "type", 12) elif iface.get("virtual-interface").get("type") in ("SR-IOV", "PCI-PASSTHROUGH"): @@ -1239,7 +1241,8 @@ def new_vnfd_v3(mydb, tenant_id, vnf_descriptor): "'member-vdus':'{vdu}'. Reference to a non-existing vdu".format( vnf=vnfd_id, pg=pg_name, vdu=vdu_id), HTTP_Bad_Request) - db_vms[vdu_id2db_table_index[vdu_id]]["availability_zone"] = pg_name + if vdu_id2db_table_index[vdu_id]: + db_vms[vdu_id2db_table_index[vdu_id]]["availability_zone"] = pg_name # TODO consider the case of isolation and not colocation # if pg.get("strategy") == "ISOLATION": @@ -1255,20 +1258,22 @@ def new_vnfd_v3(mydb, tenant_id, vnf_descriptor): mgmt_access["vm_id"] = vdu_id2uuid[vnfd["mgmt-interface"]["vdu-id"]] # if only one cp is defined by this VDU, mark this interface as of type "mgmt" if vdu_id2cp_name.get(mgmt_vdu_id): - cp_name2db_interface[vdu_id2cp_name[mgmt_vdu_id]]["type"] = "mgmt" + if cp_name2db_interface[vdu_id2cp_name[mgmt_vdu_id]]: + cp_name2db_interface[vdu_id2cp_name[mgmt_vdu_id]]["type"] = "mgmt" if vnfd["mgmt-interface"].get("ip-address"): mgmt_access["ip-address"] = str(vnfd["mgmt-interface"].get("ip-address")) if vnfd["mgmt-interface"].get("cp"): if vnfd["mgmt-interface"]["cp"] not in cp_name2iface_uuid: - raise NfvoException("Error. Invalid VNF descriptor at 'vnfd[{vnf}]':'mgmt-interface':'cp':'{cp}'. " + raise NfvoException("Error. Invalid VNF descriptor at 'vnfd[{vnf}]':'mgmt-interface':'cp'['{cp}']. " "Reference to a non-existing connection-point".format( vnf=vnfd_id, cp=vnfd["mgmt-interface"]["cp"]), HTTP_Bad_Request) mgmt_access["vm_id"] = cp_name2vm_uuid[vnfd["mgmt-interface"]["cp"]] mgmt_access["interface_id"] = cp_name2iface_uuid[vnfd["mgmt-interface"]["cp"]] # mark this interface as of type mgmt - cp_name2db_interface[vnfd["mgmt-interface"]["cp"]]["type"] = "mgmt" + if cp_name2db_interface[vnfd["mgmt-interface"]["cp"]]: + cp_name2db_interface[vnfd["mgmt-interface"]["cp"]]["type"] = "mgmt" default_user = get_str(vnfd.get("vnf-configuration", {}).get("config-access", {}).get("ssh-access", {}), "default-user", 64) @@ -1305,6 +1310,7 @@ def new_vnfd_v3(mydb, tenant_id, vnf_descriptor): raise # NfvoException("Exception {}".format(e), HTTP_Bad_Request) +@deprecated("Use new_vnfd_v3") def new_vnf(mydb, tenant_id, vnf_descriptor): global global_config @@ -1442,6 +1448,7 @@ def new_vnf(mydb, tenant_id, vnf_descriptor): raise NfvoException(error_text, e.http_code) +@deprecated("Use new_vnfd_v3") def new_vnf_v02(mydb, tenant_id, vnf_descriptor): global global_config @@ -1597,13 +1604,13 @@ def get_vnf_id(mydb, tenant_id, vnf_id): SELECT=('vms.uuid as uuid', 'vms.osm_id as osm_id', 'vms.name as name', 'vms.description as description', 'boot_data'), WHERE={'vnfs.uuid': vnf_id} ) - if len(content)==0: - raise NfvoException("vnf '{}' not found".format(vnf_id), HTTP_Not_Found) + if len(content)!=0: + #raise NfvoException("vnf '{}' not found".format(vnf_id), HTTP_Not_Found) # change boot_data into boot-data - for vm in content: - if vm.get("boot_data"): - vm["boot-data"] = yaml.safe_load(vm["boot_data"]) - del vm["boot_data"] + for vm in content: + if vm.get("boot_data"): + vm["boot-data"] = yaml.safe_load(vm["boot_data"]) + del vm["boot_data"] data['vnf']['VNFC'] = content #TODO: GET all the information from a VNFC and include it in the output. @@ -1742,6 +1749,7 @@ def delete_vnf(mydb,tenant_id,vnf_id,datacenter=None,vim_tenant=None): # return "delete_vnf. Undeleted: %s" %(undeletedItems) +@deprecated("Not used") def get_hosts_info(mydb, nfvo_tenant_id, datacenter_name=None): result, vims = get_vim(mydb, nfvo_tenant_id, None, datacenter_name) if result < 0: @@ -1792,6 +1800,7 @@ def get_hosts(mydb, nfvo_tenant_id): raise NfvoException("Not possible to get_host_list from VIM: {}".format(str(e)), e.http_code) +@deprecated("Use new_nsd_v3") def new_scenario(mydb, tenant_id, topo): # result, vims = get_vim(mydb, tenant_id) @@ -2073,6 +2082,7 @@ def new_scenario(mydb, tenant_id, topo): return c +@deprecated("Use new_nsd_v3") def new_scenario_v02(mydb, tenant_id, scenario_dict, version): """ This creates a new scenario for version 0.2 and 0.3""" scenario = scenario_dict["scenario"] @@ -2518,6 +2528,7 @@ def edit_scenario(mydb, tenant_id, scenario_id, data): return c +@deprecated("Use create_instance") def start_scenario(mydb, tenant_id, scenario_id, instance_scenario_name, instance_scenario_description, datacenter=None,vim_tenant=None, startvms=True): #print "Checking that nfvo_tenant_id exists and getting the VIM URI and the VIM tenant_id" datacenter_id, myvim = get_datacenter_by_name_uuid(mydb, tenant_id, datacenter, vim_tenant=vim_tenant) @@ -3112,6 +3123,8 @@ def create_instance(mydb, tenant_id, instance_dict): if sce_vnf_ifaces.get("sce_net_id") == sce_net["uuid"]: involved_datacenters.append(vnf_datacenter) break + if not involved_datacenters: + involved_datacenters.append(default_datacenter_id) descriptor_net = {} if instance_dict.get("networks") and instance_dict["networks"].get(sce_net["name"]): @@ -3137,6 +3150,7 @@ def create_instance(mydb, tenant_id, instance_dict): myvim_thread_id = myvim_threads_id[datacenter_id] net_type = sce_net['type'] + net_vim_name = None lookfor_filter = {'admin_state_up': True, 'status': 'ACTIVE'} # 'shared': True if not net_name: @@ -3209,6 +3223,7 @@ def create_instance(mydb, tenant_id, instance_dict): db_net = { "uuid": net_uuid, 'vim_net_id': None, + "vim_name": net_vim_name, "instance_scenario_id": instance_uuid, "sce_net_id": sce_net["uuid"], "created": create_network, @@ -3254,6 +3269,7 @@ def create_instance(mydb, tenant_id, instance_dict): "myvims": myvims, "cloud_config": cloud_config, "RO_pub_key": tenant[0].get('RO_pub_key'), + "instance_parameters": instance_dict, } vnf_params_out = { "task_index": task_index, @@ -3268,7 +3284,7 @@ def create_instance(mydb, tenant_id, instance_dict): "sce_net2instance": sce_net2instance, } # sce_vnf_list = sorted(scenarioDict['vnfs'], key=lambda k: k['name']) - for sce_vnf in scenarioDict['vnfs']: # sce_vnf_list: + for sce_vnf in scenarioDict.get('vnfs'): # sce_vnf_list: instantiate_vnf(mydb, sce_vnf, vnf_params, vnf_params_out, rollbackList) task_index = vnf_params_out["task_index"] uuid_list = vnf_params_out["uuid_list"] @@ -3521,6 +3537,7 @@ def instantiate_vnf(mydb, sce_vnf, params, params_out, rollbackList): db_net = { "uuid": net_uuid, 'vim_net_id': None, + "vim_name": net_name, "instance_scenario_id": instance_uuid, "net_id": net["uuid"], "created": True, @@ -3572,7 +3589,7 @@ def instantiate_vnf(mydb, sce_vnf, params, params_out, rollbackList): if sce_vnf.get('mgmt_access'): ssh_access = sce_vnf['mgmt_access'].get('config-access', {}).get('ssh-access') vnf_availability_zones = [] - for vm in sce_vnf['vms']: + for vm in sce_vnf.get('vms'): vm_av = vm.get('availability_zone') if vm_av and vm_av not in vnf_availability_zones: vnf_availability_zones.append(vm_av) @@ -3606,6 +3623,10 @@ def instantiate_vnf(mydb, sce_vnf, params, params_out, rollbackList): db_instance_vnfs.append(db_instance_vnf) for vm in sce_vnf['vms']: + # skip PDUs + if vm.get("pdu_type"): + continue + myVMDict = {} sce_vnf_name = sce_vnf['member_vnf_index'] if sce_vnf['member_vnf_index'] else sce_vnf['name'] myVMDict['name'] = "{}-{}-{}".format(instance_name[:64], sce_vnf_name[:64], vm["name"][:64]) @@ -3657,6 +3678,7 @@ def instantiate_vnf(mydb, sce_vnf, params, params_out, rollbackList): myVMDict['networks'] = [] task_depends_on = [] # TODO ALF. connect_mgmt_interfaces. Connect management interfaces if this is true + is_management_vm = False db_vm_ifaces = [] for iface in vm['interfaces']: netDict = {} @@ -3689,12 +3711,17 @@ def instantiate_vnf(mydb, sce_vnf, params, params_out, rollbackList): Try to delete and create the scenarios and VNFs again", HTTP_Conflict) else: raise NfvoException(e_text, HTTP_Internal_Server_Error) - if netDict["use"] == "mgmt" or netDict["use"] == "bridge": + if netDict["use"] == "mgmt": + is_management_vm = True + netDict["type"] = "virtual" + if netDict["use"] == "bridge": netDict["type"] = "virtual" if iface.get("vpci"): netDict['vpci'] = iface['vpci'] if iface.get("mac"): netDict['mac_address'] = iface['mac'] + if iface.get("mac_address"): + netDict['mac_address'] = iface['mac_address'] if iface.get("ip_address"): netDict['ip_address'] = iface['ip_address'] if iface.get("port-security") is not None: @@ -3741,9 +3768,16 @@ def instantiate_vnf(mydb, sce_vnf, params, params_out, rollbackList): # We add the RO key to cloud_config if vnf will need ssh access cloud_config_vm = cloud_config - if ssh_access and ssh_access['required'] and ssh_access['default-user'] and tenant[0].get('RO_pub_key'): - RO_key = {"key-pairs": [tenant[0]['RO_pub_key']]} - cloud_config_vm = unify_cloud_config(cloud_config_vm, RO_key) + if is_management_vm and params["instance_parameters"].get("mgmt_keys"): + cloud_config_vm = unify_cloud_config({"key-pairs": params["instance_parameters"]["mgmt_keys"]}, + cloud_config_vm) + + if vm.get("instance_parameters") and vm["instance_parameters"].get("mgmt_keys"): + cloud_config_vm = unify_cloud_config({"key-pairs": vm["instance_parameters"]["mgmt_keys"]}, + cloud_config_vm) + # if ssh_access and ssh_access['required'] and ssh_access['default-user'] and tenant[0].get('RO_pub_key'): + # RO_key = {"key-pairs": [tenant[0]['RO_pub_key']]} + # cloud_config_vm = unify_cloud_config(cloud_config_vm, RO_key) if vm.get("boot_data"): cloud_config_vm = unify_cloud_config(vm["boot_data"], cloud_config_vm) @@ -3842,68 +3876,21 @@ def delete_instance(mydb, tenant_id, instance_id): # "number_tasks": 0 # filled bellow } - # 2.1 deleting VMs - # vm_fail_list=[] - for sce_vnf in instanceDict['vnfs']: - datacenter_key = (sce_vnf["datacenter_id"], sce_vnf["datacenter_tenant_id"]) - vimthread_affected[sce_vnf["datacenter_tenant_id"]] = None - if datacenter_key not in myvims: - try: - _,myvim_thread = get_vim_thread(mydb, tenant_id, sce_vnf["datacenter_id"], sce_vnf["datacenter_tenant_id"]) - except NfvoException as e: - logger.error(str(e)) - myvim_thread = None - myvim_threads[datacenter_key] = myvim_thread - vims = get_vim(mydb, tenant_id, datacenter_id=sce_vnf["datacenter_id"], - datacenter_tenant_id=sce_vnf["datacenter_tenant_id"]) - if len(vims) == 0: - logger.error("datacenter '{}' with datacenter_tenant_id '{}' not found".format(sce_vnf["datacenter_id"], - sce_vnf["datacenter_tenant_id"])) - myvims[datacenter_key] = None - else: - myvims[datacenter_key] = vims.values()[0] - myvim = myvims[datacenter_key] - myvim_thread = myvim_threads[datacenter_key] - for vm in sce_vnf['vms']: - if not myvim: - error_msg += "\n VM id={} cannot be deleted because datacenter={} not found".format(vm['vim_vm_id'], sce_vnf["datacenter_id"]) - continue - db_vim_action = { - "instance_action_id": instance_action_id, - "task_index": task_index, - "datacenter_vim_id": sce_vnf["datacenter_tenant_id"], - "action": "DELETE", - "status": "SCHEDULED", - "item": "instance_vms", - "item_id": vm["uuid"], - "extra": yaml.safe_dump({"params": vm["interfaces"]}, - default_flow_style=True, width=256) - } - db_vim_actions.append(db_vim_action) - for interface in vm["interfaces"]: - if not interface.get("instance_net_id"): - continue - if interface["instance_net_id"] not in net2vm_dependencies: - net2vm_dependencies[interface["instance_net_id"]] = [] - net2vm_dependencies[interface["instance_net_id"]].append(task_index) - task_index += 1 - - # 2.2 deleting NETS - # net_fail_list=[] - for net in instanceDict['nets']: - vimthread_affected[net["datacenter_tenant_id"]] = None - datacenter_key = (net["datacenter_id"], net["datacenter_tenant_id"]) + # 2.1 deleting VNFFGs + for sfp in instanceDict.get('sfps', ()): + vimthread_affected[sfp["datacenter_tenant_id"]] = None + datacenter_key = (sfp["datacenter_id"], sfp["datacenter_tenant_id"]) if datacenter_key not in myvims: try: - _,myvim_thread = get_vim_thread(mydb, tenant_id, sce_vnf["datacenter_id"], sce_vnf["datacenter_tenant_id"]) + _, myvim_thread = get_vim_thread(mydb, tenant_id, sfp["datacenter_id"], sfp["datacenter_tenant_id"]) except NfvoException as e: logger.error(str(e)) myvim_thread = None myvim_threads[datacenter_key] = myvim_thread - vims = get_vim(mydb, tenant_id, datacenter_id=net["datacenter_id"], - datacenter_tenant_id=net["datacenter_tenant_id"]) + vims = get_vim(mydb, tenant_id, datacenter_id=sfp["datacenter_id"], + datacenter_tenant_id=sfp["datacenter_tenant_id"]) if len(vims) == 0: - logger.error("datacenter '{}' with datacenter_tenant_id '{}' not found".format(net["datacenter_id"], net["datacenter_tenant_id"])) + logger.error("datacenter '{}' with datacenter_tenant_id '{}' not found".format(sfp["datacenter_id"], sfp["datacenter_tenant_id"])) myvims[datacenter_key] = None else: myvims[datacenter_key] = vims.values()[0] @@ -3911,40 +3898,37 @@ def delete_instance(mydb, tenant_id, instance_id): myvim_thread = myvim_threads[datacenter_key] if not myvim: - error_msg += "\n Net VIM_id={} cannot be deleted because datacenter={} not found".format(net['vim_net_id'], net["datacenter_id"]) + error_msg += "\n vim_sfp_id={} cannot be deleted because datacenter={} not found".format(sfp['vim_sfp_id'], sfp["datacenter_id"]) continue - extra = {"params": (net['vim_net_id'], net['sdn_net_id'])} - if net2vm_dependencies.get(net["uuid"]): - extra["depends_on"] = net2vm_dependencies[net["uuid"]] + extra = {"params": (sfp['vim_sfp_id'])} db_vim_action = { "instance_action_id": instance_action_id, "task_index": task_index, - "datacenter_vim_id": net["datacenter_tenant_id"], + "datacenter_vim_id": sfp["datacenter_tenant_id"], "action": "DELETE", "status": "SCHEDULED", - "item": "instance_nets", - "item_id": net["uuid"], + "item": "instance_sfps", + "item_id": sfp["uuid"], "extra": yaml.safe_dump(extra, default_flow_style=True, width=256) } task_index += 1 db_vim_actions.append(db_vim_action) - # 2.3 deleting VNFFGs - - for sfp in instanceDict.get('sfps', ()): - vimthread_affected[sfp["datacenter_tenant_id"]] = None - datacenter_key = (sfp["datacenter_id"], sfp["datacenter_tenant_id"]) + for classification in instanceDict['classifications']: + vimthread_affected[classification["datacenter_tenant_id"]] = None + datacenter_key = (classification["datacenter_id"], classification["datacenter_tenant_id"]) if datacenter_key not in myvims: try: - _,myvim_thread = get_vim_thread(mydb, tenant_id, sfp["datacenter_id"], sfp["datacenter_tenant_id"]) + _, myvim_thread = get_vim_thread(mydb, tenant_id, classification["datacenter_id"], classification["datacenter_tenant_id"]) except NfvoException as e: logger.error(str(e)) myvim_thread = None myvim_threads[datacenter_key] = myvim_thread - vims = get_vim(mydb, tenant_id, datacenter_id=sfp["datacenter_id"], - datacenter_tenant_id=sfp["datacenter_tenant_id"]) + vims = get_vim(mydb, tenant_id, datacenter_id=classification["datacenter_id"], + datacenter_tenant_id=classification["datacenter_tenant_id"]) if len(vims) == 0: - logger.error("datacenter '{}' with datacenter_tenant_id '{}' not found".format(sfp["datacenter_id"], sfp["datacenter_tenant_id"])) + logger.error("datacenter '{}' with datacenter_tenant_id '{}' not found".format(classification["datacenter_id"], + classification["datacenter_tenant_id"])) myvims[datacenter_key] = None else: myvims[datacenter_key] = vims.values()[0] @@ -3952,17 +3936,19 @@ def delete_instance(mydb, tenant_id, instance_id): myvim_thread = myvim_threads[datacenter_key] if not myvim: - error_msg += "\n vim_sfp_id={} cannot be deleted because datacenter={} not found".format(sfp['vim_sfp_id'], sfp["datacenter_id"]) + error_msg += "\n vim_classification_id={} cannot be deleted because datacenter={} not found".format(classification['vim_classification_id'], + classification["datacenter_id"]) continue - extra = {"params": (sfp['vim_sfp_id'])} + depends_on = [action["task_index"] for action in db_vim_actions if action["item"] == "instance_sfps"] + extra = {"params": (classification['vim_classification_id']), "depends_on": depends_on} db_vim_action = { "instance_action_id": instance_action_id, "task_index": task_index, - "datacenter_vim_id": sfp["datacenter_tenant_id"], + "datacenter_vim_id": classification["datacenter_tenant_id"], "action": "DELETE", "status": "SCHEDULED", - "item": "instance_sfps", - "item_id": sfp["uuid"], + "item": "instance_classifications", + "item_id": classification["uuid"], "extra": yaml.safe_dump(extra, default_flow_style=True, width=256) } task_index += 1 @@ -3973,7 +3959,7 @@ def delete_instance(mydb, tenant_id, instance_id): datacenter_key = (sf["datacenter_id"], sf["datacenter_tenant_id"]) if datacenter_key not in myvims: try: - _,myvim_thread = get_vim_thread(mydb, tenant_id, sf["datacenter_id"], sf["datacenter_tenant_id"]) + _, myvim_thread = get_vim_thread(mydb, tenant_id, sf["datacenter_id"], sf["datacenter_tenant_id"]) except NfvoException as e: logger.error(str(e)) myvim_thread = None @@ -3991,7 +3977,8 @@ def delete_instance(mydb, tenant_id, instance_id): if not myvim: error_msg += "\n vim_sf_id={} cannot be deleted because datacenter={} not found".format(sf['vim_sf_id'], sf["datacenter_id"]) continue - extra = {"params": (sf['vim_sf_id'])} + depends_on = [action["task_index"] for action in db_vim_actions if action["item"] == "instance_sfps"] + extra = {"params": (sf['vim_sf_id']), "depends_on": depends_on} db_vim_action = { "instance_action_id": instance_action_id, "task_index": task_index, @@ -4010,7 +3997,7 @@ def delete_instance(mydb, tenant_id, instance_id): datacenter_key = (sfi["datacenter_id"], sfi["datacenter_tenant_id"]) if datacenter_key not in myvims: try: - _,myvim_thread = get_vim_thread(mydb, tenant_id, sfi["datacenter_id"], sfi["datacenter_tenant_id"]) + _, myvim_thread = get_vim_thread(mydb, tenant_id, sfi["datacenter_id"], sfi["datacenter_tenant_id"]) except NfvoException as e: logger.error(str(e)) myvim_thread = None @@ -4028,7 +4015,8 @@ def delete_instance(mydb, tenant_id, instance_id): if not myvim: error_msg += "\n vim_sfi_id={} cannot be deleted because datacenter={} not found".format(sfi['vim_sfi_id'], sfi["datacenter_id"]) continue - extra = {"params": (sfi['vim_sfi_id'])} + depends_on = [action["task_index"] for action in db_vim_actions if action["item"] == "instance_sfs"] + extra = {"params": (sfi['vim_sfi_id']), "depends_on": depends_on} db_vim_action = { "instance_action_id": instance_action_id, "task_index": task_index, @@ -4042,20 +4030,70 @@ def delete_instance(mydb, tenant_id, instance_id): task_index += 1 db_vim_actions.append(db_vim_action) - for classification in instanceDict['classifications']: - vimthread_affected[classification["datacenter_tenant_id"]] = None - datacenter_key = (classification["datacenter_id"], classification["datacenter_tenant_id"]) + # 2.2 deleting VMs + # vm_fail_list=[] + for sce_vnf in instanceDict.get('vnfs', ()): + datacenter_key = (sce_vnf["datacenter_id"], sce_vnf["datacenter_tenant_id"]) + vimthread_affected[sce_vnf["datacenter_tenant_id"]] = None if datacenter_key not in myvims: try: - _,myvim_thread = get_vim_thread(mydb, tenant_id, classification["datacenter_id"], classification["datacenter_tenant_id"]) + _, myvim_thread = get_vim_thread(mydb, tenant_id, sce_vnf["datacenter_id"], sce_vnf["datacenter_tenant_id"]) except NfvoException as e: logger.error(str(e)) myvim_thread = None myvim_threads[datacenter_key] = myvim_thread - vims = get_vim(mydb, tenant_id, datacenter_id=classification["datacenter_id"], - datacenter_tenant_id=classification["datacenter_tenant_id"]) + vims = get_vim(mydb, tenant_id, datacenter_id=sce_vnf["datacenter_id"], + datacenter_tenant_id=sce_vnf["datacenter_tenant_id"]) + if len(vims) == 0: + logger.error("datacenter '{}' with datacenter_tenant_id '{}' not found".format(sce_vnf["datacenter_id"], + sce_vnf["datacenter_tenant_id"])) + myvims[datacenter_key] = None + else: + myvims[datacenter_key] = vims.values()[0] + myvim = myvims[datacenter_key] + myvim_thread = myvim_threads[datacenter_key] + + for vm in sce_vnf['vms']: + if not myvim: + error_msg += "\n VM id={} cannot be deleted because datacenter={} not found".format(vm['vim_vm_id'], sce_vnf["datacenter_id"]) + continue + sfi_dependencies = [action["task_index"] for action in db_vim_actions if action["item"] == "instance_sfis"] + db_vim_action = { + "instance_action_id": instance_action_id, + "task_index": task_index, + "datacenter_vim_id": sce_vnf["datacenter_tenant_id"], + "action": "DELETE", + "status": "SCHEDULED", + "item": "instance_vms", + "item_id": vm["uuid"], + "extra": yaml.safe_dump({"params": vm["interfaces"], "depends_on": sfi_dependencies}, + default_flow_style=True, width=256) + } + db_vim_actions.append(db_vim_action) + for interface in vm["interfaces"]: + if not interface.get("instance_net_id"): + continue + if interface["instance_net_id"] not in net2vm_dependencies: + net2vm_dependencies[interface["instance_net_id"]] = [] + net2vm_dependencies[interface["instance_net_id"]].append(task_index) + task_index += 1 + + # 2.3 deleting NETS + # net_fail_list=[] + for net in instanceDict['nets']: + vimthread_affected[net["datacenter_tenant_id"]] = None + datacenter_key = (net["datacenter_id"], net["datacenter_tenant_id"]) + if datacenter_key not in myvims: + try: + _,myvim_thread = get_vim_thread(mydb, tenant_id, net["datacenter_id"], net["datacenter_tenant_id"]) + except NfvoException as e: + logger.error(str(e)) + myvim_thread = None + myvim_threads[datacenter_key] = myvim_thread + vims = get_vim(mydb, tenant_id, datacenter_id=net["datacenter_id"], + datacenter_tenant_id=net["datacenter_tenant_id"]) if len(vims) == 0: - logger.error("datacenter '{}' with datacenter_tenant_id '{}' not found".format(classification["datacenter_id"], classification["datacenter_tenant_id"])) + logger.error("datacenter '{}' with datacenter_tenant_id '{}' not found".format(net["datacenter_id"], net["datacenter_tenant_id"])) myvims[datacenter_key] = None else: myvims[datacenter_key] = vims.values()[0] @@ -4063,17 +4101,25 @@ def delete_instance(mydb, tenant_id, instance_id): myvim_thread = myvim_threads[datacenter_key] if not myvim: - error_msg += "\n vim_classification_id={} cannot be deleted because datacenter={} not found".format(classification['vim_classification_id'], classification["datacenter_id"]) + error_msg += "\n Net VIM_id={} cannot be deleted because datacenter={} not found".format(net['vim_net_id'], net["datacenter_id"]) continue - extra = {"params": (classification['vim_classification_id'])} + extra = {"params": (net['vim_net_id'], net['sdn_net_id'])} + if net2vm_dependencies.get(net["uuid"]): + extra["depends_on"] = net2vm_dependencies[net["uuid"]] + sfi_dependencies = [action["task_index"] for action in db_vim_actions if action["item"] == "instance_sfis"] + if len(sfi_dependencies) > 0: + if "depends_on" in extra: + extra["depends_on"] += sfi_dependencies + else: + extra["depends_on"] = sfi_dependencies db_vim_action = { "instance_action_id": instance_action_id, "task_index": task_index, - "datacenter_vim_id": classification["datacenter_tenant_id"], + "datacenter_vim_id": net["datacenter_tenant_id"], "action": "DELETE", "status": "SCHEDULED", - "item": "instance_classifications", - "item_id": classification["uuid"], + "item": "instance_nets", + "item_id": net["uuid"], "extra": yaml.safe_dump(extra, default_flow_style=True, width=256) } task_index += 1 @@ -4118,6 +4164,7 @@ def get_instance_id(mydb, tenant_id, instance_id): } return instance_dict +@deprecated("Instance is automatically refreshed by vim_threads") def refresh_instance(mydb, nfvo_tenant, instanceDict, datacenter=None, vim_tenant=None): '''Refreshes a scenario instance. It modifies instanceDict''' '''Returns: @@ -4309,6 +4356,8 @@ def instance_action(mydb,nfvo_tenant,instance_id, action_dict): "description": "SCALE", } vm_result["instance_action_id"] = instance_action_id + vm_result["created"] = [] + vm_result["deleted"] = [] task_index = 0 for vdu in action_dict["vdu-scaling"]: vdu_id = vdu.get("vdu-id") @@ -4316,17 +4365,17 @@ def instance_action(mydb,nfvo_tenant,instance_id, action_dict): member_vnf_index = vdu.get("member-vnf-index") vdu_count = vdu.get("count", 1) if vdu_id: - target_vm = mydb.get_rows( + target_vms = mydb.get_rows( FROM="instance_vms as vms join instance_vnfs as vnfs on vms.instance_vnf_id=vnfs.uuid", WHERE={"vms.uuid": vdu_id}, ORDER_BY="vms.created_at" ) - if not target_vm: + if not target_vms: raise NfvoException("Cannot find the vdu with id {}".format(vdu_id), HTTP_Not_Found) else: if not osm_vdu_id and not member_vnf_index: raise NfvoException("Invalid imput vdu parameters. Must supply either 'vdu-id' of 'osm_vdu_id','member-vnf-index'") - target_vm = mydb.get_rows( + target_vms = mydb.get_rows( # SELECT=("ivms.uuid", "ivnfs.datacenter_id", "ivnfs.datacenter_tenant_id"), FROM="instance_vms as ivms join instance_vnfs as ivnfs on ivms.instance_vnf_id=ivnfs.uuid"\ " join sce_vnfs as svnfs on ivnfs.sce_vnf_id=svnfs.uuid"\ @@ -4334,38 +4383,41 @@ def instance_action(mydb,nfvo_tenant,instance_id, action_dict): WHERE={"vms.osm_id": osm_vdu_id, "svnfs.member_vnf_index": member_vnf_index}, ORDER_BY="ivms.created_at" ) - if not target_vm: + if not target_vms: raise NfvoException("Cannot find the vdu with osm_vdu_id {} and member-vnf-index {}".format(osm_vdu_id, member_vnf_index), HTTP_Not_Found) - vdu_id = target_vm[-1]["uuid"] - vm_result[vdu_id] = {"created": [], "deleted": [], "description": "scheduled"} - target_vm = target_vm[-1] + vdu_id = target_vms[-1]["uuid"] + target_vm = target_vms[-1] datacenter = target_vm["datacenter_id"] myvim_threads_id[datacenter], _ = get_vim_thread(mydb, nfvo_tenant, datacenter) + if vdu["type"] == "delete": - # look for nm - vm_interfaces = None - for sce_vnf in instanceDict['vnfs']: - for vm in sce_vnf['vms']: - if vm["uuid"] == vdu_id: - vm_interfaces = vm["interfaces"] - break + for index in range(0, vdu_count): + target_vm = target_vms[-1-index] + vdu_id = target_vm["uuid"] + # look for nm + vm_interfaces = None + for sce_vnf in instanceDict['vnfs']: + for vm in sce_vnf['vms']: + if vm["uuid"] == vdu_id: + vm_interfaces = vm["interfaces"] + break - db_vim_action = { - "instance_action_id": instance_action_id, - "task_index": task_index, - "datacenter_vim_id": target_vm["datacenter_tenant_id"], - "action": "DELETE", - "status": "SCHEDULED", - "item": "instance_vms", - "item_id": target_vm["uuid"], - "extra": yaml.safe_dump({"params": vm_interfaces}, - default_flow_style=True, width=256) - } - task_index += 1 - db_vim_actions.append(db_vim_action) - vm_result[vdu_id]["deleted"].append(vdu_id) - # delete from database - db_instance_vms.append({"TO-DELETE": vdu_id}) + db_vim_action = { + "instance_action_id": instance_action_id, + "task_index": task_index, + "datacenter_vim_id": target_vm["datacenter_tenant_id"], + "action": "DELETE", + "status": "SCHEDULED", + "item": "instance_vms", + "item_id": vdu_id, + "extra": yaml.safe_dump({"params": vm_interfaces}, + default_flow_style=True, width=256) + } + task_index += 1 + db_vim_actions.append(db_vim_action) + vm_result["deleted"].append(vdu_id) + # delete from database + db_instance_vms.append({"TO-DELETE": vdu_id}) else: # vdu["type"] == "create": iface2iface = {} @@ -4400,7 +4452,7 @@ def instance_action(mydb,nfvo_tenant,instance_id, action_dict): vm_name = target_vm.get('vim_name') try: suffix = vm_name.rfind("-") - vm_name = vm_name[:suffix+1] + str(1 + int(vm_name[suffix+1:])) + vm_name = vm_name[:suffix+1] + str(index + 1 + int(vm_name[suffix+1:])) except Exception: pass db_instance_vm = { @@ -4457,7 +4509,7 @@ def instance_action(mydb,nfvo_tenant,instance_id, action_dict): } task_index += 1 db_vim_actions.append(db_vim_action) - vm_result[vdu_id]["created"].append(vm_uuid) + vm_result["created"].append(vm_uuid) db_instance_action["number_tasks"] = task_index db_tables = [ @@ -4668,7 +4720,7 @@ def edit_datacenter(mydb, datacenter_id_name, datacenter_descriptor): # edit data datacenter_id = datacenter['uuid'] - where={'uuid': datacenter['uuid']} + where = {'uuid': datacenter['uuid']} remove_port_mapping = False new_sdn_port_mapping = None if "config" in datacenter_descriptor: @@ -4678,10 +4730,10 @@ def edit_datacenter(mydb, datacenter_id_name, datacenter_descriptor): if "sdn-port-mapping" in new_config_dict: remove_port_mapping = True new_sdn_port_mapping = new_config_dict.pop("sdn-port-mapping") - #delete null fields - to_delete=[] + # delete null fields + to_delete = [] for k in new_config_dict: - if new_config_dict[k] == None: + if new_config_dict[k] is None: to_delete.append(k) if k == 'sdn-controller': remove_port_mapping = True @@ -4691,7 +4743,7 @@ def edit_datacenter(mydb, datacenter_id_name, datacenter_descriptor): config_text = '{}' config_dict = yaml.load(config_text) config_dict.update(new_config_dict) - #delete null fields + # delete null fields for k in to_delete: del config_dict[k] except Exception as e: @@ -4704,14 +4756,16 @@ def edit_datacenter(mydb, datacenter_id_name, datacenter_descriptor): try: datacenter_sdn_port_mapping_delete(mydb, None, datacenter_id) except ovimException as e: - logger.error("Error deleting datacenter-port-mapping " + str(e)) + raise NfvoException("Error deleting datacenter-port-mapping " + str(e), HTTP_Conflict) mydb.update_rows('datacenters', datacenter_descriptor, where) if new_sdn_port_mapping: try: datacenter_sdn_port_mapping_set(mydb, None, datacenter_id, new_sdn_port_mapping) except ovimException as e: - logger.error("Error adding datacenter-port-mapping " + str(e)) + # Rollback + mydb.update_rows('datacenters', datacenter, where) + raise NfvoException("Error adding datacenter-port-mapping " + str(e), HTTP_Conflict) return datacenter_id @@ -4722,7 +4776,7 @@ def delete_datacenter(mydb, datacenter): try: datacenter_sdn_port_mapping_delete(mydb, None, datacenter_dict['uuid']) except ovimException as e: - logger.error("Error deleting datacenter-port-mapping " + str(e)) + raise NfvoException("Error deleting datacenter-port-mapping " + str(e)) return datacenter_dict['uuid'] + " " + datacenter_dict['name']