X-Git-Url: https://osm.etsi.org/gitweb/?p=osm%2FRO.git;a=blobdiff_plain;f=RO%2Fosm_ro%2Fnfvo.py;h=36109cb817c98f15e64679008c2a1bf4161a102f;hp=6a06a4cab266a4ce17570296a74aa82762d05a9a;hb=4126d05e24ada55226bb13a9d556655811cedadc;hpb=ed3e4d4fc2819e425bb8b165e43fcbac259d3f1b diff --git a/RO/osm_ro/nfvo.py b/RO/osm_ro/nfvo.py index 6a06a4ca..36109cb8 100644 --- a/RO/osm_ro/nfvo.py +++ b/RO/osm_ro/nfvo.py @@ -20,7 +20,7 @@ # For those usages not covered by the Apache License, Version 2.0 please # contact with: nfvlabs@tid.es ## - + ''' NFVO engine, implementing all the methods for the creation, deletion and management of vnfs, scenarios and instances ''' @@ -1355,7 +1355,7 @@ def new_vnfd_v3(mydb, tenant_id, vnf_descriptor): 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"].get("cp") and vnfd.get("vdu"): if vnfd["mgmt-interface"]["cp"] not in cp_name2iface_uuid: raise NfvoException("Error. Invalid VNF descriptor at 'vnfd[{vnf}]':'mgmt-interface':'cp'['{cp}']. " "Reference to a non-existing connection-point".format( @@ -2433,47 +2433,51 @@ def new_nsd_v3(mydb, tenant_id, nsd_descriptor): elif vld.get("vim-network-name"): db_sce_net["vim_network_name"] = get_str(vld, "vim-network-name", 255) + # table sce_interfaces (vld:vnfd-connection-point-ref) for iface in vld.get("vnfd-connection-point-ref").values(): + # Check if there are VDUs in the descriptor vnf_index = str(iface['member-vnf-index-ref']) - # check correct parameters - if vnf_index not in vnf_index2vnf_uuid: - raise NfvoException("Error. Invalid NS descriptor at 'nsd[{}]':'vld[{}]':'vnfd-connection-point" - "-ref':'member-vnf-index-ref':'{}'. Reference to a non-existing index at " - "'nsd':'constituent-vnfd'".format( - str(nsd["id"]), str(vld["id"]), str(iface["member-vnf-index-ref"])), - httperrors.Bad_Request) - - existing_ifaces = mydb.get_rows(SELECT=('i.uuid as uuid', 'i.type as iface_type'), - FROM="interfaces as i join vms on i.vm_id=vms.uuid", - WHERE={'vnf_id': vnf_index2vnf_uuid[vnf_index], - 'external_name': get_str(iface, "vnfd-connection-point-ref", - 255)}) - if not existing_ifaces: - raise NfvoException("Error. Invalid NS descriptor at 'nsd[{}]':'vld[{}]':'vnfd-connection-point" - "-ref':'vnfd-connection-point-ref':'{}'. Reference to a non-existing " - "connection-point name at VNFD '{}'".format( - str(nsd["id"]), str(vld["id"]), str(iface["vnfd-connection-point-ref"]), - str(iface.get("vnfd-id-ref"))[:255]), - httperrors.Bad_Request) - interface_uuid = existing_ifaces[0]["uuid"] - if existing_ifaces[0]["iface_type"] == "data": - db_sce_net["type"] = "data" - sce_interface_uuid = str(uuid4()) - uuid_list.append(sce_net_uuid) - iface_ip_address = None - if iface.get("ip-address"): - iface_ip_address = str(iface.get("ip-address")) - db_sce_interface = { - "uuid": sce_interface_uuid, - "sce_vnf_id": vnf_index2scevnf_uuid[vnf_index], - "sce_net_id": sce_net_uuid, - "interface_id": interface_uuid, - "ip_address": iface_ip_address, - } - db_sce_interfaces.append(db_sce_interface) - if not db_sce_net["type"]: - db_sce_net["type"] = "bridge" + existing_vdus = mydb.get_rows(SELECT=('vms.uuid'), FROM="vms", WHERE={'vnf_id': vnf_index2vnf_uuid[vnf_index]}) + if existing_vdus: + # check correct parameters + if vnf_index not in vnf_index2vnf_uuid: + raise NfvoException("Error. Invalid NS descriptor at 'nsd[{}]':'vld[{}]':'vnfd-connection-point" + "-ref':'member-vnf-index-ref':'{}'. Reference to a non-existing index at " + "'nsd':'constituent-vnfd'".format( + str(nsd["id"]), str(vld["id"]), str(iface["member-vnf-index-ref"])), + httperrors.Bad_Request) + + existing_ifaces = mydb.get_rows(SELECT=('i.uuid as uuid', 'i.type as iface_type'), + FROM="interfaces as i join vms on i.vm_id=vms.uuid", + WHERE={'vnf_id': vnf_index2vnf_uuid[vnf_index], + 'external_name': get_str(iface, "vnfd-connection-point-ref", + 255)}) + if not existing_ifaces: + raise NfvoException("Error. Invalid NS descriptor at 'nsd[{}]':'vld[{}]':'vnfd-connection-point" + "-ref':'vnfd-connection-point-ref':'{}'. Reference to a non-existing " + "connection-point name at VNFD '{}'".format( + str(nsd["id"]), str(vld["id"]), str(iface["vnfd-connection-point-ref"]), + str(iface.get("vnfd-id-ref"))[:255]), + httperrors.Bad_Request) + interface_uuid = existing_ifaces[0]["uuid"] + if existing_ifaces[0]["iface_type"] == "data": + db_sce_net["type"] = "data" + sce_interface_uuid = str(uuid4()) + uuid_list.append(sce_net_uuid) + iface_ip_address = None + if iface.get("ip-address"): + iface_ip_address = str(iface.get("ip-address")) + db_sce_interface = { + "uuid": sce_interface_uuid, + "sce_vnf_id": vnf_index2scevnf_uuid[vnf_index], + "sce_net_id": sce_net_uuid, + "interface_id": interface_uuid, + "ip_address": iface_ip_address, + } + db_sce_interfaces.append(db_sce_interface) + if not db_sce_net["type"]: + db_sce_net["type"] = "bridge" # table sce_vnffgs (vnffgd) for vnffg in nsd.get("vnffgd").values(): @@ -2675,11 +2679,12 @@ def start_scenario(mydb, tenant_id, scenario_id, instance_scenario_name, instanc myNetDict["type"] = myNetType myNetDict["tenant_id"] = myvim_tenant myNetIPProfile = sce_net.get('ip_profile', None) + myProviderNetwork = sce_net.get('provider_network', None) #TODO: #We should use the dictionary as input parameter for new_network #print myNetDict if not sce_net["external"]: - network_id, _ = myvim.new_network(myNetName, myNetType, myNetIPProfile) + network_id, _ = myvim.new_network(myNetName, myNetType, myNetIPProfile, provider_network_profile=myProviderNetwork) #print "New VIM network created for scenario %s. Network id: %s" % (scenarioDict['name'],network_id) sce_net['vim_id'] = network_id auxNetDict['scenario'][sce_net['uuid']] = network_id @@ -2710,10 +2715,11 @@ def start_scenario(mydb, tenant_id, scenario_id, instance_scenario_name, instanc myNetDict["type"] = myNetType myNetDict["tenant_id"] = myvim_tenant myNetIPProfile = net.get('ip_profile', None) + myProviderNetwork = sce_net.get('provider_network', None) #print myNetDict #TODO: #We should use the dictionary as input parameter for new_network - network_id, _ = myvim.new_network(myNetName, myNetType, myNetIPProfile) + network_id, _ = myvim.new_network(myNetName, myNetType, myNetIPProfile, provider_network_profile=myProviderNetwork) #print "VIM network id for scenario %s: %s" % (scenarioDict['name'],network_id) net['vim_id'] = network_id if sce_vnf['uuid'] not in auxNetDict: @@ -3048,6 +3054,7 @@ def _get_wim(db, wim_account_id): 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...") + scenario = instance_dict["scenario"] # find main datacenter @@ -3198,6 +3205,13 @@ def create_instance(mydb, tenant_id, instance_dict): else: update(scenario_net['ip_profile'], ipprofile_db) + if 'provider-network' in net_instance_desc: + provider_network_db = net_instance_desc['provider-network'] + if 'provider-network' not in scenario_net: + scenario_net['provider-network'] = provider_network_db + else: + update(scenario_net['provider-network'], provider_network_db) + for vdu_id, vdu_instance_desc in vnf_instance_desc.get("vdus", {}).items(): for scenario_vm in scenario_vnf['vms']: if vdu_id == scenario_vm['osm_id'] or vdu_id == scenario_vm["name"]: @@ -3230,6 +3244,14 @@ def create_instance(mydb, tenant_id, instance_dict): scenario_net['ip_profile'] = ipprofile_db else: update(scenario_net['ip_profile'], ipprofile_db) + if 'provider-network' in net_instance_desc: + provider_network_db = net_instance_desc['provider-network'] + + if 'provider-network' not in scenario_net: + scenario_net['provider_network'] = provider_network_db + else: + update(scenario_net['provider-network'], provider_network_db) + for interface in net_instance_desc.get('interfaces', ()): if 'ip_address' in interface: for vnf in scenarioDict['vnfs']: @@ -3242,11 +3264,13 @@ def create_instance(mydb, tenant_id, instance_dict): # 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" number_mgmt_networks = 0 db_instance_nets = [] db_instance_wim_nets = [] for sce_net in scenarioDict['nets']: + sce_net_uuid = sce_net.get('uuid', sce_net["name"]) # get involved datacenters where this network need to be created involved_datacenters = [] @@ -3398,7 +3422,9 @@ def create_instance(mydb, tenant_id, instance_dict): task_extra = {} if create_network: task_action = "CREATE" - task_extra["params"] = (net_vim_name, net_type, sce_net.get('ip_profile', None), wim_account_name) + task_extra["params"] = (net_vim_name, net_type, sce_net.get('ip_profile', None), False, + sce_net.get('provider_network', None), wim_account_name) + if lookfor_network: task_extra["find"] = (lookfor_filter,) elif lookfor_network: @@ -3640,7 +3666,8 @@ def create_instance(mydb, tenant_id, instance_dict): "source_ip": match["source_ip"], "destination_ip": match["destination_ip"], "source_port": match["source_port"], - "destination_port": match["destination_port"] + "destination_port": match["destination_port"], + "logical_source_port": classifier["interface_id"] } db_vim_action = { "instance_action_id": instance_action_id, @@ -4049,6 +4076,7 @@ def instantiate_vnf(mydb, sce_vnf, params, params_out, rollbackList): else: netDict['net_id'] = "TASK-{}".format(net2task_id[sce_vnf['uuid']][iface['net_id']]) instance_net_id = vnf_net2instance[sce_vnf['uuid']][iface['net_id']] + instance_wim_net_id = None task_depends_on.append(net2task_id[sce_vnf['uuid']][iface['net_id']]) # skip bridge ifaces not connected to any net if 'net_id' not in netDict or netDict['net_id'] == None: @@ -4918,10 +4946,9 @@ def instance_action(mydb,nfvo_tenant,instance_id, action_dict): action_dict['add_public_key'], password=password, ro_key=priv_RO_key) vm_result[ vm['uuid'] ] = {"vim_result": 200, - "description": "Public key injected", - "name":vm['name'] + "description": "Public key injected", + "name":vm['name'] } - except KeyError: raise NfvoException("Unable to inject ssh key in vm: {} - Aborting".format(vm['uuid']), httperrors.Internal_Server_Error) @@ -5682,7 +5709,10 @@ def vim_action_create(mydb, tenant_id, datacenter, item, descriptor): net_public = net.pop("shared", False) 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) + net_provider_network_profile = None + if net_vlan: + net_provider_network_profile = {"segmentation-id": net_vlan} + content, _ = myvim.new_network(net_name, net_type, net_ipprofile, shared=net_public, provider_network_profile=net_provider_network_profile) #, **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'): @@ -5726,15 +5756,18 @@ def vim_action_create(mydb, tenant_id, datacenter, item, descriptor): return vim_action_get(mydb, tenant_id, datacenter, item, content) def sdn_controller_create(mydb, tenant_id, sdn_controller): - wim_id = ovim.new_of_controller(sdn_controller) + try: + wim_id = ovim.new_of_controller(sdn_controller) - thread_name = get_non_used_vim_name(sdn_controller['name'], wim_id, wim_id, None) - new_thread = vim_thread(task_lock, plugins, thread_name, wim_id, None, db=db) - new_thread.start() - thread_id = wim_id - vim_threads["running"][thread_id] = new_thread - logger.debug('New SDN controller created with uuid {}'.format(wim_id)) - return wim_id + thread_name = get_non_used_vim_name(sdn_controller['name'], wim_id, wim_id, None) + new_thread = vim_thread(task_lock, plugins, thread_name, wim_id, None, db=db) + new_thread.start() + thread_id = wim_id + vim_threads["running"][thread_id] = new_thread + logger.debug('New SDN controller created with uuid {}'.format(wim_id)) + return wim_id + except ovimException as e: + raise NfvoException(e) from e def sdn_controller_update(mydb, tenant_id, controller_id, sdn_controller): data = ovim.edit_of_controller(controller_id, sdn_controller) @@ -5877,6 +5910,10 @@ def create_RO_keypair(tenant_id): private_key = key.exportKey(passphrase=tenant_id, pkcs=8) except (ValueError, NameError) as e: raise NfvoException("Unable to create private key: {}".format(e), httperrors.Internal_Server_Error) + if isinstance(public_key, bytes): + public_key = public_key.decode(encoding='UTF-8') + if isinstance(private_key, bytes): + private_key = private_key.decode(encoding='UTF-8') return public_key, private_key def decrypt_key (key, tenant_id): @@ -5893,6 +5930,8 @@ def decrypt_key (key, tenant_id): unencrypted_key = key.exportKey('PEM') if isinstance(unencrypted_key, ValueError): raise NfvoException("Unable to decrypt the private key: {}".format(unencrypted_key), httperrors.Internal_Server_Error) + if isinstance(unencrypted_key, bytes): + unencrypted_key = unencrypted_key.decode(encoding='UTF-8') except ValueError as e: raise NfvoException("Unable to decrypt the private key: {}".format(e), httperrors.Internal_Server_Error) return unencrypted_key