X-Git-Url: https://osm.etsi.org/gitweb/?a=blobdiff_plain;ds=sidebyside;f=osm_ro%2Fnfvo.py;h=8a1d9490b492c440a4d75cf03e972ca00b4fa74d;hb=c4629bd3b12d44dd568240735f8cc546475170a3;hp=6ce8cd0ec9a09e6d5f9aa0fc86eed3ff288a6c89;hpb=51757e91da3ab11350718213dd3eccd1ca49fe4e;p=osm%2FRO.git diff --git a/osm_ro/nfvo.py b/osm_ro/nfvo.py index 6ce8cd0e..8a1d9490 100644 --- a/osm_ro/nfvo.py +++ b/osm_ro/nfvo.py @@ -30,18 +30,18 @@ __date__ ="$16-sep-2014 22:05:01$" # import imp # import json import yaml -import utils -import vim_thread -from db_base import HTTP_Unauthorized, HTTP_Bad_Request, HTTP_Internal_Server_Error, HTTP_Not_Found,\ +from . import utils +from . 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 -import console_proxy_thread as cli -import vimconn +from . import console_proxy_thread as cli +from . import vimconn import logging import collections from uuid import uuid4 -from db_base import db_base_Exception +from .db_base import db_base_Exception -import nfvo_db +from . import nfvo_db from threading import Lock import time as t from lib_osm_openvim import ovim as ovim_module @@ -182,6 +182,10 @@ def start_service(mydb): user=vim['user'], passwd=vim['passwd'], config=extra, persistent_info=vim_persistent_info[thread_id] ) + except vimconn.vimconnException as e: + myvim = e + logger.error("Cannot launch thread for VIM {} '{}': {}".format(vim['datacenter_name'], + vim['datacenter_id'], e)) except Exception as e: raise NfvoException("Error at VIM {}; {}: {}".format(vim["type"], type(e).__name__, e), HTTP_Internal_Server_Error) @@ -208,7 +212,7 @@ def stop_service(): global ovim, global_config if ovim: ovim.stop_service() - for thread_id,thread in vim_threads["running"].items(): + for thread_id,thread in list(vim_threads["running"].items()): thread.insert_task("exit") vim_threads["deleting"][thread_id] = thread vim_threads["running"] = {} @@ -514,7 +518,7 @@ def create_or_use_image(mydb, vims, image_dict, rollback_list, only_create_at_vi image_mano_id = mydb.new_row('images', temp_image_dict, add_uuid=True) rollback_list.append({"where":"mano", "what":"image","uuid":image_mano_id}) #create image at every vim - for vim_id,vim in vims.iteritems(): + for vim_id,vim in vims.items(): datacenter_vim_id = vim["config"]["datacenter_tenant_id"] image_created="false" #look at database @@ -632,7 +636,7 @@ def create_or_use_flavor(mydb, vims, flavor_dict, rollback_list, only_create_at_ if 'uuid' in flavor_dict: del flavor_dict['uuid'] flavor_vim_id=None - for vim_id,vim in vims.items(): + for vim_id,vim in list(vims.items()): datacenter_vim_id = vim["config"]["datacenter_tenant_id"] flavor_created="false" #look at database @@ -789,7 +793,7 @@ def new_vnfd_v3(mydb, tenant_id, vnf_descriptor): try: pybindJSONDecoder.load_ietf_json(vnf_descriptor, None, None, obj=myvnfd) except Exception as e: - raise NfvoException("Invalid yang descriptor format " + str(e), HTTP_Bad_Request) + raise NfvoException("Error. Invalid VNF descriptor format " + str(e), HTTP_Bad_Request) db_vnfs = [] db_nets = [] db_vms = [] @@ -799,8 +803,14 @@ def new_vnfd_v3(mydb, tenant_id, vnf_descriptor): db_flavors = [] uuid_list = [] vnfd_uuid_list = [] - for rift_vnfd in myvnfd.vnfd_catalog.vnfd.itervalues(): - vnfd = rift_vnfd.get() + vnfd_catalog_descriptor = vnf_descriptor.get("vnfd:vnfd-catalog") + if not vnfd_catalog_descriptor: + vnfd_catalog_descriptor = vnf_descriptor.get("vnfd-catalog") + vnfd_descriptor_list = vnfd_catalog_descriptor.get("vnfd") + if not vnfd_descriptor_list: + vnfd_descriptor_list = vnfd_catalog_descriptor.get("vnfd:vnfd") + for vnfd_yang in myvnfd.vnfd_catalog.vnfd.values(): + vnfd = vnfd_yang.get() # table vnf vnf_uuid = str(uuid4()) @@ -817,9 +827,13 @@ def new_vnfd_v3(mydb, tenant_id, vnf_descriptor): "descriptor": str(vnf_descriptor)[:60000] } + for vnfd_descriptor in vnfd_descriptor_list: + if vnfd_descriptor["id"] == str(vnfd["id"]): + break + # table nets (internal-vld) net_id2uuid = {} # for mapping interface with network - for vld in vnfd.get("internal-vld").itervalues(): + for vld in vnfd.get("internal-vld").values(): net_uuid = str(uuid4()) uuid_list.append(net_uuid) db_net = { @@ -835,7 +849,7 @@ def new_vnfd_v3(mydb, tenant_id, vnf_descriptor): # table vms (vdus) vdu_id2uuid = {} vdu_id2db_table_index = {} - for vdu in vnfd.get("vdu").itervalues(): + for vdu in vnfd.get("vdu").values(): vm_uuid = str(uuid4()) uuid_list.append(vm_uuid) db_vm = { @@ -904,22 +918,22 @@ def new_vnfd_v3(mydb, tenant_id, vnf_descriptor): if vdu["guest-epa"].get("numa-node-policy"): # TODO or dedicated_int: numa_node_policy = vdu["guest-epa"].get("numa-node-policy") if numa_node_policy.get("node"): - numa_node = numa_node_policy.node[0] + numa_node = numa_node_policy["node"]['0'] if numa_node.get("num-cores"): numa["cores"] = numa_node["num-cores"] epa_vcpu_set = True if numa_node.get("paired-threads"): if numa_node["paired-threads"].get("num-paired-threads"): - numa["paired-threads"] = numa_node["paired-threads"]["num-paired-threads"] + numa["paired-threads"] = int(numa_node["paired-threads"]["num-paired-threads"]) epa_vcpu_set = True - if len(numa_node["paired-threads"].get("paired-thread-ids")) > 0: + if len(numa_node["paired-threads"].get("paired-thread-ids")): numa["paired-threads-id"] = [] - for pair in numa_node["paired-threads"]["paired-thread-ids"].itervalues: + for pair in numa_node["paired-threads"]["paired-thread-ids"].values(): numa["paired-threads-id"].append( (str(pair["thread-a"]), str(pair["thread-b"])) ) if numa_node.get("num-threads"): - numa["threads"] = numa_node["num-threads"] + numa["threads"] = int(numa_node["num-threads"]) epa_vcpu_set = True if numa_node.get("memory-mb"): numa["memory"] = max(int(numa_node["memory-mb"] / 1024), 1) @@ -961,7 +975,7 @@ def new_vnfd_v3(mydb, tenant_id, vnf_descriptor): boot_data["user-data"] = str(vdu["cloud-init"]) elif vdu.get("cloud-init-file"): # TODO Where this file content is present??? - # boot_data["user-data"] = rift_vnfd.files[vdu["cloud-init-file"]] + # boot_data["user-data"] = vnfd_yang.files[vdu["cloud-init-file"]] boot_data["user-data"] = str(vdu["cloud-init-file"]) if vdu.get("supplemental-boot-data"): @@ -969,7 +983,7 @@ def new_vnfd_v3(mydb, tenant_id, vnf_descriptor): boot_data['boot-data-drive'] = True if vdu["supplemental-boot-data"].get('config-file'): om_cfgfile_list = list() - for custom_config_file in vdu["supplemental-boot-data"]['config-file'].itervalues(): + for custom_config_file in vdu["supplemental-boot-data"]['config-file'].values(): # TODO Where this file content is present??? cfg_source = str(custom_config_file["source"]) om_cfgfile_list.append({"dest": custom_config_file["dest"], @@ -985,7 +999,7 @@ def new_vnfd_v3(mydb, tenant_id, vnf_descriptor): cp_name2iface_uuid = {} cp_name2vm_uuid = {} # for iface in chain(vdu.get("internal-interface").itervalues(), vdu.get("external-interface").itervalues()): - for iface in vdu.get("interface").itervalues(): + for iface in vdu.get("interface").values(): iface_uuid = str(uuid4()) uuid_list.append(iface_uuid) db_interface = { @@ -1009,7 +1023,11 @@ def new_vnfd_v3(mydb, tenant_id, vnf_descriptor): db_interface["type"] = "data" db_interface["model"] = get_str(iface.get("virtual-interface"), "type", 12) else: - raise ValueError("Interface type {} not supported".format(iface.get("virtual-interface").get("type"))) + raise NfvoException("Error. Invalid VNF descriptor at 'vnfd[{}]':'vdu[{}]':'interface':'virtual" + "-interface':'type':'{}'. Interface type is not supported".format( + str(vnfd["id"])[:255], str(vdu["id"])[:255], + iface.get("virtual-interface").get("type")), + HTTP_Bad_Request) if iface.get("external-connection-point-ref"): try: @@ -1017,43 +1035,55 @@ def new_vnfd_v3(mydb, tenant_id, vnf_descriptor): db_interface["external_name"] = get_str(cp, "name", 255) cp_name2iface_uuid[db_interface["external_name"]] = iface_uuid cp_name2vm_uuid[db_interface["external_name"]] = vm_uuid - # TODO add port-security-enable - # if cp.get("port-security-enabled") == False: - # elif cp.get("port-security-enabled") == True: + for cp_descriptor in vnfd_descriptor["connection-point"]: + if cp_descriptor["name"] == db_interface["external_name"]: + break + if str(cp_descriptor.get("port-security-enabled")).lower() == "false": + db_interface["port_security"] = 0 + elif str(cp_descriptor.get("port-security-enabled")).lower() == "true": + db_interface["port_security"] = 1 except KeyError: - raise KeyError( - "Error wrong reference at vnfd['{vnf}'] vdu['{vdu}']:internal-interface['{iface}']:" - "vnfd-connection-point-ref '{cp}' is not present at connection-point".format( - vnf=vnfd["id"], vdu=vdu["id"], iface=iface["name"], - cp=iface.get("vnfd-connection-point-ref")) - ) + raise NfvoException("Error. Invalid VNF descriptor at 'vnfd[{vnf}]':'vdu[{vdu}]':" + "'interface[{iface}]':'vnfd-connection-point-ref':'{cp}' is not present" + " at connection-point".format( + vnf=vnfd["id"], vdu=vdu["id"], iface=iface["name"], + cp=iface.get("vnfd-connection-point-ref")), + HTTP_Bad_Request) elif iface.get("internal-connection-point-ref"): try: - for vld in vnfd.get("internal-vld").itervalues(): - for cp in vld.get("internal-connection-point").itervalues(): + for vld in vnfd.get("internal-vld").values(): + for cp in vld.get("internal-connection-point").values(): if cp.get("id-ref") == iface.get("internal-connection-point-ref"): db_interface["net_id"] = net_id2uuid[vld.get("id")] + for cp_descriptor in vnfd_descriptor["connection-point"]: + if cp_descriptor["name"] == db_interface["external_name"]: + break + if str(cp_descriptor.get("port-security-enabled")).lower() == "false": + db_interface["port_security"] = 0 + elif str(cp_descriptor.get("port-security-enabled")).lower() == "true": + db_interface["port_security"] = 1 break except KeyError: - raise KeyError( - "Error at vnfd['{vnf}'] vdu['{vdu}']:internal-interface['{iface}']:" - "vdu-internal-connection-point-ref '{cp}' is not referenced by any internal-vld".format( - vnf=vnfd["id"], vdu=vdu["id"], iface=iface["name"], - cp=iface.get("vdu-internal-connection-point-ref")) - ) + raise NfvoException("Error. Invalid VNF descriptor at 'vnfd[{vnf}]':'vdu[{vdu}]':" + "'interface[{iface}]':'vdu-internal-connection-point-ref':'{cp}' is not" + " referenced by any internal-vld".format( + vnf=vnfd["id"], vdu=vdu["id"], iface=iface["name"], + cp=iface.get("vdu-internal-connection-point-ref")), + HTTP_Bad_Request) if iface.get("position") is not None: db_interface["created_at"] = int(iface.get("position")) - 1000 db_interfaces.append(db_interface) # VNF affinity and antiaffinity - for pg in vnfd.get("placement-groups").itervalues(): + for pg in vnfd.get("placement-groups").values(): pg_name = get_str(pg, "name", 255) - for vdu in pg.get("member-vdus").itervalues(): + for vdu in pg.get("member-vdus").values(): vdu_id = get_str(vdu, "member-vdu-ref", 255) if vdu_id not in vdu_id2db_table_index: - raise KeyError( - "Error at 'vnfd'['{vnf}']:'placement-groups'['{pg}']:'member-vdus':'{vdu}' references a non existing vdu".format( - vnf=vnfd["id"], pg=pg_name, vdu=vdu_id)) + raise NfvoException("Error. Invalid VNF descriptor at 'vnfd[{vnf}]':'placement-groups[{pg}]':" + "'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 # TODO consider the case of isolation and not colocation # if pg.get("strategy") == "ISOLATION": @@ -1062,17 +1092,19 @@ def new_vnfd_v3(mydb, tenant_id, vnf_descriptor): mgmt_access = {} if vnfd["mgmt-interface"].get("vdu-id"): if vnfd["mgmt-interface"]["vdu-id"] not in vdu_id2uuid: - raise KeyError( - "Error at vnfd['{vnf}']:'mgmt-interface':'vdu-id':{vdu} reference a non existing vdu".format( - vnf=vnfd["id"], vdu=vnfd["mgmt-interface"]["vdu-id"])) + raise NfvoException("Error. Invalid VNF descriptor at 'vnfd[{vnf}]':'mgmt-interface':'vdu-id':" + "'{vdu}'. Reference to a non-existing vdu".format( + vnf=vnfd["id"], vdu=vnfd["mgmt-interface"]["vdu-id"]), + HTTP_Bad_Request) mgmt_access["vm_id"] = vdu_id2uuid[vnfd["mgmt-interface"]["vdu-id"]] 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 KeyError( - "Error at vnfd['{vnf}']:'mgmt-interface':'cp':{cp} reference a non existing connection-point". - format(vnf=vnfd["id"], cp=vnfd["mgmt-interface"]["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"]] default_user = get_str(vnfd.get("vnf-configuration", {}).get("config-access", {}).get("ssh-access", {}), @@ -1104,6 +1136,8 @@ def new_vnfd_v3(mydb, tenant_id, vnf_descriptor): yaml.safe_dump(db_tables, indent=4, default_flow_style=False) ) mydb.new_rows(db_tables, uuid_list) return vnfd_uuid_list + except NfvoException: + raise except Exception as e: logger.error("Exception {}".format(e)) raise # NfvoException("Exception {}".format(e), HTTP_Bad_Request) @@ -1393,7 +1427,7 @@ def get_vnf_id(mydb, tenant_id, vnf_id): vnf_id = vnf["uuid"] filter_keys = ('uuid', 'name', 'description', 'public', "tenant_id", "osm_id", "created_at") - filtered_content = dict( (k,v) for k,v in vnf.iteritems() if k in filter_keys ) + filtered_content = dict( (k,v) for k,v in vnf.items() if k in filter_keys ) #change_keys_http2db(filtered_content, http2db_vnf, reverse=True) data={'vnf' : filtered_content} #GET VM @@ -1546,7 +1580,7 @@ def get_hosts_info(mydb, nfvo_tenant_id, datacenter_name=None): return result, vims elif result == 0: return -HTTP_Not_Found, "datacenter '%s' not found" % datacenter_name - myvim = vims.values()[0] + myvim = list(vims.values())[0] result,servers = myvim.get_hosts_info() if result < 0: return result, servers @@ -1561,7 +1595,7 @@ def get_hosts(mydb, nfvo_tenant_id): elif len(vims)>1: #print "nfvo.datacenter_action() error. Several datacenters found" raise NfvoException("More than one datacenters found, try to identify with uuid", HTTP_Conflict) - myvim = vims.values()[0] + myvim = list(vims.values())[0] try: hosts = myvim.get_hosts() logger.debug('VIM hosts response: '+ yaml.safe_dump(hosts, indent=4, default_flow_style=False)) @@ -1609,7 +1643,7 @@ def new_scenario(mydb, tenant_id, topo): vnfs={} other_nets={} #external_networks, bridge_networks and data_networkds nodes = topo['topology']['nodes'] - for k in nodes.keys(): + for k in list(nodes.keys()): if nodes[k]['type'] == 'VNF': vnfs[k] = nodes[k] vnfs[k]['ifaces'] = {} @@ -1622,7 +1656,7 @@ def new_scenario(mydb, tenant_id, topo): #1.2: Check that VNF are present at database table vnfs. Insert uuid, description and external interfaces - for name,vnf in vnfs.items(): + for name,vnf in list(vnfs.items()): where={} where_or={"tenant_id": tenant_id, 'public': "true"} error_text = "" @@ -1658,12 +1692,12 @@ def new_scenario(mydb, tenant_id, topo): conections = topo['topology']['connections'] conections_list = [] conections_list_name = [] - for k in conections.keys(): + for k in list(conections.keys()): if type(conections[k]['nodes'])==dict: #dict with node:iface pairs - ifaces_list = conections[k]['nodes'].items() + ifaces_list = list(conections[k]['nodes'].items()) elif type(conections[k]['nodes'])==list: #list with dictionary ifaces_list=[] - conection_pair_list = map(lambda x: x.items(), conections[k]['nodes'] ) + conection_pair_list = [list(x.items()) for x in conections[k]['nodes']] for k2 in conection_pair_list: ifaces_list += k2 @@ -1727,7 +1761,7 @@ def new_scenario(mydb, tenant_id, topo): # del con[index] # del other_nets[k] #1.7: Check external_ports are present at database table datacenter_nets - for k,net in other_nets.items(): + for k,net in list(other_nets.items()): error_pos = "'topology':'nodes':'" + k + "'" if net['external']==False: if 'name' not in net: @@ -1775,7 +1809,7 @@ def new_scenario(mydb, tenant_id, topo): #print "con", con for index in range(0,len(con)): #check if this is connected to a external net - for net_key in other_nets.keys(): + for net_key in list(other_nets.keys()): if con[index][0]==net_key: if other_net_index>=0: error_text="There is some interface connected both to net '%s' and net '%s'" % (con[other_net_index][0], net_key) @@ -1846,8 +1880,8 @@ def new_scenario(mydb, tenant_id, topo): #1.8.2 check all interfaces from all vnfs if len(mgmt_net)>0: add_mgmt_net = False - for vnf in vnfs.values(): - for iface in vnf['ifaces'].values(): + for vnf in list(vnfs.values()): + for iface in list(vnf['ifaces'].values()): if iface['type']=='mgmt' and 'net_key' not in iface: #iface not connected iface['net_key'] = 'mgmt' @@ -1888,7 +1922,7 @@ def new_scenario_v02(mydb, tenant_id, scenario_dict, version): tenant_id=None # 1: Check that VNF are present at database table vnfs and update content into scenario dict - for name,vnf in scenario["vnfs"].iteritems(): + for name,vnf in scenario["vnfs"].items(): where={} where_or={"tenant_id": tenant_id, 'public': "true"} error_text = "" @@ -1922,7 +1956,7 @@ def new_scenario_v02(mydb, tenant_id, scenario_dict, version): # TODO? get internal-connections from db.nets and their profiles, and update scenario[vnfs][internal-connections] accordingly # 2: Insert net_key and ip_address at every vnf interface - for net_name, net in scenario["networks"].items(): + for net_name, net in list(scenario["networks"].items()): net_type_bridge = False net_type_data = False for iface_dict in net["interfaces"]: @@ -1932,7 +1966,7 @@ def new_scenario_v02(mydb, tenant_id, scenario_dict, version): elif version == "0.3": temp_dict = {iface_dict["vnf"] : iface_dict["vnf_interface"]} ip_address = iface_dict.get('ip_address', None) - for vnf, iface in temp_dict.items(): + for vnf, iface in list(temp_dict.items()): if vnf not in scenario["vnfs"]: error_text = "Error at 'networks':'{}':'interfaces' VNF '{}' not match any VNF at 'vnfs'".format( net_name, vnf) @@ -2011,7 +2045,7 @@ def new_nsd_v3(mydb, tenant_id, nsd_descriptor): try: pybindJSONDecoder.load_ietf_json(nsd_descriptor, None, None, obj=mynsd) except Exception as e: - raise NfvoException("Invalid yang descriptor format " + str(e), HTTP_Bad_Request) + raise NfvoException("Error. Invalid NS descriptor format: " + str(e), HTTP_Bad_Request) db_scenarios = [] db_sce_nets = [] db_sce_vnfs = [] @@ -2020,8 +2054,8 @@ def new_nsd_v3(mydb, tenant_id, nsd_descriptor): db_ip_profiles_index = 0 uuid_list = [] nsd_uuid_list = [] - for rift_nsd in mynsd.nsd_catalog.nsd.itervalues(): - nsd = rift_nsd.get() + for nsd_yang in mynsd.nsd_catalog.nsd.values(): + nsd = nsd_yang.get() # table sceanrios scenario_uuid = str(uuid4()) @@ -2042,13 +2076,14 @@ def new_nsd_v3(mydb, tenant_id, nsd_descriptor): # table sce_vnfs (constituent-vnfd) vnf_index2scevnf_uuid = {} vnf_index2vnf_uuid = {} - for vnf in nsd.get("constituent-vnfd").itervalues(): + for vnf in nsd.get("constituent-vnfd").values(): existing_vnf = mydb.get_rows(FROM="vnfs", WHERE={'osm_id': str(vnf["vnfd-id-ref"])[:255], 'tenant_id': tenant_id}) if not existing_vnf: - raise KeyError("Error at 'nsd[{}]':'constituent-vnfd':'vnfd-id-ref':'{}' references a " - "non existing VNFD in the catalog".format(str(nsd["id"]), - str(vnf["vnfd-id-ref"])[:255])) + raise NfvoException("Error. Invalid NS descriptor at 'nsd[{}]':'constituent-vnfd':'vnfd-id-ref':" + "'{}'. Reference to a non-existing VNFD in the catalog".format( + str(nsd["id"]), str(vnf["vnfd-id-ref"])[:255]), + HTTP_Bad_Request) sce_vnf_uuid = str(uuid4()) uuid_list.append(sce_vnf_uuid) db_sce_vnf = { @@ -2065,7 +2100,7 @@ def new_nsd_v3(mydb, tenant_id, nsd_descriptor): # table ip_profiles (ip-profiles) ip_profile_name2db_table_index = {} - for ip_profile in nsd.get("ip-profiles").itervalues(): + for ip_profile in nsd.get("ip-profiles").values(): db_ip_profile = { "ip_version": str(ip_profile["ip-profile-params"].get("ip-version", "ipv4")), "subnet_address": str(ip_profile["ip-profile-params"].get("subnet-address")), @@ -2075,7 +2110,7 @@ def new_nsd_v3(mydb, tenant_id, nsd_descriptor): "dhcp_count": str(ip_profile["ip-profile-params"]["dhcp-params"].get("count")), } dns_list = [] - for dns in ip_profile["ip-profile-params"]["dns-server"].itervalues(): + for dns in ip_profile["ip-profile-params"]["dns-server"].values(): dns_list.append(str(dns.get("address"))) db_ip_profile["dns_address"] = ";".join(dns_list) if ip_profile["ip-profile-params"].get('security-group'): @@ -2085,7 +2120,7 @@ def new_nsd_v3(mydb, tenant_id, nsd_descriptor): db_ip_profiles.append(db_ip_profile) # table sce_nets (internal-vld) - for vld in nsd.get("vld").itervalues(): + for vld in nsd.get("vld").values(): sce_net_uuid = str(uuid4()) uuid_list.append(sce_net_uuid) db_sce_net = { @@ -2111,19 +2146,22 @@ def new_nsd_v3(mydb, tenant_id, nsd_descriptor): if vld.get("ip-profile-ref"): ip_profile_name = vld.get("ip-profile-ref") if ip_profile_name not in ip_profile_name2db_table_index: - raise KeyError("Error at 'nsd[{}]':'vld[{}]':'ip-profile-ref':'{}' references a non existing " - "'ip_profiles'".format( - str(nsd["id"]), str(vld["id"]), str(vld["ip-profile-ref"]))) + raise NfvoException("Error. Invalid NS descriptor at 'nsd[{}]':'vld[{}]':'ip-profile-ref':'{}'." + " Reference to a non-existing 'ip_profiles'".format( + str(nsd["id"]), str(vld["id"]), str(vld["ip-profile-ref"])), + HTTP_Bad_Request) db_ip_profiles[ip_profile_name2db_table_index[ip_profile_name]]["sce_net_id"] = sce_net_uuid # table sce_interfaces (vld:vnfd-connection-point-ref) - for iface in vld.get("vnfd-connection-point-ref").itervalues(): + for iface in vld.get("vnfd-connection-point-ref").values(): vnf_index = int(iface['member-vnf-index-ref']) # check correct parameters if vnf_index not in vnf_index2vnf_uuid: - raise KeyError("Error at 'nsd[{}]':'vld[{}]':'vnfd-connection-point-ref':'member-vnf-index-ref'" - ":'{}' references a non existing index at 'nsd':'constituent-vnfd'".format( - str(nsd["id"]), str(vld["id"]), str(iface["member-vnf-index-ref"]))) + 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"])), + HTTP_Bad_Request) existing_ifaces = mydb.get_rows(SELECT=('i.uuid as uuid',), FROM="interfaces as i join vms on i.vm_id=vms.uuid", @@ -2131,11 +2169,12 @@ def new_nsd_v3(mydb, tenant_id, nsd_descriptor): 'external_name': get_str(iface, "vnfd-connection-point-ref", 255)}) if not existing_ifaces: - raise KeyError("Error at 'nsd[{}]':'vld[{}]':'vnfd-connection-point-ref':'vnfd-connection-point" - "-ref':'{}' references a non existing interface at VNFD '{}'".format( - str(nsd["id"]), str(vld["id"]), str(iface["vnfd-connection-point-ref"]), - str(iface.get("vnfd-id-ref"))[:255])) - + 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]), + HTTP_Bad_Request) interface_uuid = existing_ifaces[0]["uuid"] sce_interface_uuid = str(uuid4()) uuid_list.append(sce_net_uuid) @@ -2160,6 +2199,8 @@ def new_nsd_v3(mydb, tenant_id, nsd_descriptor): yaml.safe_dump(db_tables, indent=4, default_flow_style=False) ) mydb.new_rows(db_tables, uuid_list) return nsd_uuid_list + except NfvoException: + raise except Exception as e: logger.error("Exception {}".format(e)) raise # NfvoException("Exception {}".format(e), HTTP_Bad_Request) @@ -2515,6 +2556,28 @@ def get_vim_thread(mydb, tenant_id, datacenter_id_name=None, datacenter_tenant_i raise NfvoException("{} {}".format(type(e).__name__ , str(e)), e.http_code) +def get_datacenter_uuid(mydb, tenant_id, datacenter_id_name): + WHERE_dict={} + if utils.check_valid_uuid(datacenter_id_name): + WHERE_dict['d.uuid'] = datacenter_id_name + else: + WHERE_dict['d.name'] = datacenter_id_name + + if tenant_id: + WHERE_dict['nfvo_tenant_id'] = tenant_id + 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" + else: + from_ = 'datacenters as d' + vimaccounts = mydb.get_rows(FROM=from_, SELECT=("d.uuid as uuid",), WHERE=WHERE_dict ) + if len(vimaccounts) == 0: + raise NfvoException("datacenter '{}' not found".format(str(datacenter_id_name)), HTTP_Not_Found) + elif len(vimaccounts)>1: + #print "nfvo.datacenter_action() error. Several datacenters found" + raise NfvoException("More than one datacenters found, try to identify with uuid", HTTP_Conflict) + return vimaccounts[0]["uuid"] + + def get_datacenter_by_name_uuid(mydb, tenant_id, datacenter_id_name=None, **extra_filter): datacenter_id = None datacenter_name = None @@ -2529,13 +2592,13 @@ def get_datacenter_by_name_uuid(mydb, tenant_id, datacenter_id_name=None, **extr elif len(vims)>1: #print "nfvo.datacenter_action() error. Several datacenters found" raise NfvoException("More than one datacenters found, try to identify with uuid", HTTP_Conflict) - return vims.keys()[0], vims.values()[0] + return list(vims.keys())[0], list(vims.values())[0] def update(d, u): '''Takes dict d and updates it with the values in dict u.''' '''It merges all depth levels''' - for k, v in u.iteritems(): + for k, v in u.items(): if isinstance(v, collections.Mapping): r = update(d.get(k, {}), v) d[k] = r @@ -2607,7 +2670,7 @@ def create_instance(mydb, tenant_id, instance_dict): # yaml.safe_dump(scenarioDict, indent=4, default_flow_style=False)) try: # 0 check correct parameters - for net_name, net_instance_desc in instance_dict.get("networks", {}).iteritems(): + for net_name, net_instance_desc in instance_dict.get("networks", {}).items(): found = False for scenario_net in scenarioDict['nets']: if net_name == scenario_net["name"]: @@ -2621,6 +2684,7 @@ def create_instance(mydb, tenant_id, instance_dict): site_without_datacenter_field = False for site in net_instance_desc["sites"]: if site.get("datacenter"): + site["datacenter"] = get_datacenter_uuid(mydb, tenant_id, site["datacenter"]) if site["datacenter"] not in myvims: # Add this datacenter to myvims d, v = get_datacenter_by_name_uuid(mydb, tenant_id, site["datacenter"]) @@ -2634,7 +2698,7 @@ def create_instance(mydb, tenant_id, instance_dict): site_without_datacenter_field = True site["datacenter"] = default_datacenter_id # change name to id - for vnf_name, vnf_instance_desc in instance_dict.get("vnfs",{}).iteritems(): + for vnf_name, vnf_instance_desc in instance_dict.get("vnfs",{}).items(): found = False for scenario_vnf in scenarioDict['vnfs']: if vnf_name == scenario_vnf['name']: @@ -2644,6 +2708,7 @@ def create_instance(mydb, tenant_id, instance_dict): raise NfvoException("Invalid vnf name '{}' at instance:vnfs".format(vnf_instance_desc), HTTP_Bad_Request) if "datacenter" in vnf_instance_desc: # Add this datacenter to myvims + vnf_instance_desc["datacenter"] = get_datacenter_uuid(mydb, tenant_id, vnf_instance_desc["datacenter"]) if vnf_instance_desc["datacenter"] not in myvims: d, v = get_datacenter_by_name_uuid(mydb, tenant_id, vnf_instance_desc["datacenter"]) myvims[d] = v @@ -2660,7 +2725,7 @@ def create_instance(mydb, tenant_id, instance_dict): # 0.2 merge instance information into scenario # Ideally, the operation should be as simple as: update(scenarioDict,instance_dict) # However, this is not possible yet. - for net_name, net_instance_desc in instance_dict.get("networks",{}).iteritems(): + for net_name, net_instance_desc in instance_dict.get("networks",{}).items(): for scenario_net in scenarioDict['nets']: if net_name == scenario_net["name"]: if 'ip-profile' in net_instance_desc: @@ -2758,16 +2823,15 @@ def create_instance(mydb, tenant_id, instance_dict): create_network = True lookfor_network = False - if lookfor_network and create_network: - # TODO create two tasks FIND + CREATE with their relationship - task_action = "FIND_CREATE" - task_params = (lookfor_filter, (net_vim_name, net_type, sce_net.get('ip_profile', None))) + task_extra = {} + if create_network: + task_action = "CREATE" + task_extra["params"] = (net_vim_name, net_type, sce_net.get('ip_profile', None)) + if lookfor_network: + task_extra["find"] = (lookfor_filter,) elif lookfor_network: task_action = "FIND" - task_params = (lookfor_filter,) - elif create_network: - task_action = "CREATE" - task_params = (net_vim_name, net_type, sce_net.get('ip_profile', None)) + task_extra["params"] = (lookfor_filter,) # fill database content net_uuid = str(uuid4()) @@ -2792,7 +2856,7 @@ def create_instance(mydb, tenant_id, instance_dict): "action": task_action, "item": "instance_nets", "item_id": net_uuid, - "extra": yaml.safe_dump({"params": task_params}, default_flow_style=True, width=256) + "extra": yaml.safe_dump(task_extra, default_flow_style=True, width=256) } net2task_id['scenario'][sce_net['uuid']][datacenter_id] = task_index task_index += 1 @@ -3121,7 +3185,7 @@ def create_instance(mydb, tenant_id, instance_dict): logger.debug("create_instance done DB tables: %s", yaml.safe_dump(db_tables, indent=4, default_flow_style=False) ) mydb.new_rows(db_tables, uuid_list) - for myvim_thread_id in myvim_threads_id.values(): + for myvim_thread_id in list(myvim_threads_id.values()): vim_threads["running"][myvim_thread_id].insert_task(db_vim_actions) returned_instance = mydb.get_instance_scenario(instance_uuid) @@ -3186,7 +3250,7 @@ def delete_instance(mydb, tenant_id, instance_id): sce_vnf["datacenter_tenant_id"])) myvims[datacenter_key] = None else: - myvims[datacenter_key] = vims.values()[0] + myvims[datacenter_key] = list(vims.values())[0] myvim = myvims[datacenter_key] myvim_thread = myvim_threads[datacenter_key] for vm in sce_vnf['vms']: @@ -3238,7 +3302,7 @@ def delete_instance(mydb, tenant_id, instance_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] + myvims[datacenter_key] = list(vims.values())[0] myvim = myvims[datacenter_key] myvim_thread = myvim_threads[datacenter_key] @@ -3280,7 +3344,7 @@ def delete_instance(mydb, tenant_id, instance_id): logger.debug("delete_instance done DB tables: %s", yaml.safe_dump(db_tables, indent=4, default_flow_style=False)) mydb.new_rows(db_tables, ()) - for myvim_thread_id in vimthread_affected.keys(): + for myvim_thread_id in list(vimthread_affected.keys()): vim_threads["running"][myvim_thread_id].insert_task(db_vim_actions) if len(error_msg) > 0: @@ -3463,7 +3527,7 @@ def instance_action(mydb,nfvo_tenant,instance_id, action_dict): vims = get_vim(mydb, nfvo_tenant, instanceDict['datacenter_id']) if len(vims) == 0: raise NfvoException("datacenter '{}' not found".format(str(instanceDict['datacenter_id'])), HTTP_Not_Found) - myvim = vims.values()[0] + myvim = list(vims.values())[0] if action_dict.get("create-vdu"): for vdu in action_dict["create-vdu"]: @@ -3612,7 +3676,7 @@ def new_tenant(mydb, tenant_dict): pub_key, priv_key = create_RO_keypair(tenant_uuid) tenant_dict['RO_pub_key'] = pub_key tenant_dict['encrypted_RO_priv_key'] = priv_key - mydb.new_row("nfvo_tenants", tenant_dict) + mydb.new_row("nfvo_tenants", tenant_dict, confidential_data=True) except db_base_Exception as e: raise NfvoException("Error creating the new tenant: {} ".format(tenant_dict['name']) + str(e), HTTP_Internal_Server_Error) return tenant_uuid @@ -3641,7 +3705,7 @@ def new_datacenter(mydb, datacenter_descriptor): # 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) + datacenter_id = mydb.new_row("datacenters", datacenter_descriptor, add_uuid=True, confidential_data=True) return datacenter_id @@ -3701,73 +3765,79 @@ def delete_datacenter(mydb, datacenter): 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, 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 - - # get nfvo_tenant info - tenant_dict = mydb.get_table_by_uuid_name('nfvo_tenants', nfvo_tenant) - if vim_tenant_name==None: - vim_tenant_name=tenant_dict['name'] - - #check that this association does not exist before - tenants_datacenter_dict={"nfvo_tenant_id":tenant_dict['uuid'], "datacenter_id":datacenter_id } - tenants_datacenters = mydb.get_rows(FROM='tenants_datacenters', WHERE=tenants_datacenter_dict) - if len(tenants_datacenters)>0: - raise NfvoException("datacenter '{}' and tenant'{}' are already attached".format(datacenter_id, tenant_dict['uuid']), HTTP_Conflict) - - vim_tenant_id_exist_atdb=False - if not create_vim_tenant: - where_={"datacenter_id": datacenter_id} - if vim_tenant_id!=None: - where_["vim_tenant_id"] = vim_tenant_id - if vim_tenant_name!=None: - where_["vim_tenant_name"] = vim_tenant_name - #check if vim_tenant_id is already at database - datacenter_tenants_dict = mydb.get_rows(FROM='datacenter_tenants', WHERE=where_) - if len(datacenter_tenants_dict)>=1: - datacenter_tenants_dict = datacenter_tenants_dict[0] - vim_tenant_id_exist_atdb=True - #TODO check if a field has changed and edit entry at datacenter_tenants at DB - else: #result=0 + # get datacenter info + try: + datacenter_id = get_datacenter_uuid(mydb, None, datacenter) + + create_vim_tenant = True if not vim_tenant_id and not vim_tenant_name else False + + # get nfvo_tenant info + tenant_dict = mydb.get_table_by_uuid_name('nfvo_tenants', nfvo_tenant) + if vim_tenant_name==None: + vim_tenant_name=tenant_dict['name'] + + #check that this association does not exist before + tenants_datacenter_dict={"nfvo_tenant_id":tenant_dict['uuid'], "datacenter_id":datacenter_id } + tenants_datacenters = mydb.get_rows(FROM='tenants_datacenters', WHERE=tenants_datacenter_dict) + if len(tenants_datacenters)>0: + raise NfvoException("datacenter '{}' and tenant'{}' are already attached".format(datacenter_id, tenant_dict['uuid']), HTTP_Conflict) + + vim_tenant_id_exist_atdb=False + if not create_vim_tenant: + where_={"datacenter_id": datacenter_id} + if vim_tenant_id!=None: + where_["vim_tenant_id"] = vim_tenant_id + if vim_tenant_name!=None: + where_["vim_tenant_name"] = vim_tenant_name + #check if vim_tenant_id is already at database + datacenter_tenants_dict = mydb.get_rows(FROM='datacenter_tenants', WHERE=where_) + if len(datacenter_tenants_dict)>=1: + datacenter_tenants_dict = datacenter_tenants_dict[0] + vim_tenant_id_exist_atdb=True + #TODO check if a field has changed and edit entry at datacenter_tenants at DB + else: #result=0 + datacenter_tenants_dict = {} + #insert at table datacenter_tenants + else: #if vim_tenant_id==None: + #create tenant at VIM if not provided + try: + _, myvim = get_datacenter_by_name_uuid(mydb, None, datacenter, vim_user=vim_username, + vim_passwd=vim_password) + datacenter_name = myvim["name"] + vim_tenant_id = myvim.new_tenant(vim_tenant_name, "created by openmano for datacenter "+datacenter_name) + except vimconn.vimconnException as e: + raise NfvoException("Not possible to create vim_tenant {} at VIM: {}".format(vim_tenant_id, str(e)), HTTP_Internal_Server_Error) datacenter_tenants_dict = {} - #insert at table datacenter_tenants - else: #if vim_tenant_id==None: - #create tenant at VIM if not provided - try: - vim_tenant_id = myvim.new_tenant(vim_tenant_name, "created by openmano for datacenter "+datacenter_name) - except vimconn.vimconnException as e: - raise NfvoException("Not possible to create vim_tenant {} at VIM: {}".format(vim_tenant_id, str(e)), HTTP_Internal_Server_Error) - datacenter_tenants_dict = {} - datacenter_tenants_dict["created"]="true" - - #fill datacenter_tenants table - if not vim_tenant_id_exist_atdb: - datacenter_tenants_dict["vim_tenant_id"] = vim_tenant_id - datacenter_tenants_dict["vim_tenant_name"] = vim_tenant_name - datacenter_tenants_dict["user"] = vim_username - datacenter_tenants_dict["passwd"] = vim_password - datacenter_tenants_dict["datacenter_id"] = datacenter_id - if config: - datacenter_tenants_dict["config"] = yaml.safe_dump(config, default_flow_style=True, width=256) - id_ = mydb.new_row('datacenter_tenants', datacenter_tenants_dict, add_uuid=True) - datacenter_tenants_dict["uuid"] = id_ - - #fill tenants_datacenters table - datacenter_tenant_id = datacenter_tenants_dict["uuid"] - tenants_datacenter_dict["datacenter_tenant_id"] = datacenter_tenant_id - mydb.new_row('tenants_datacenters', tenants_datacenter_dict) - # create thread - datacenter_id, myvim = get_datacenter_by_name_uuid(mydb, tenant_dict['uuid'], datacenter_id) # reload data - thread_name = get_non_used_vim_name(datacenter_name, datacenter_id, tenant_dict['name'], tenant_dict['uuid']) - new_thread = vim_thread.vim_thread(myvim, task_lock, thread_name, datacenter_name, datacenter_tenant_id, - db=db, db_lock=db_lock, ovim=ovim) - new_thread.start() - thread_id = datacenter_tenants_dict["uuid"] - vim_threads["running"][thread_id] = new_thread - return datacenter_id + datacenter_tenants_dict["created"]="true" + + #fill datacenter_tenants table + if not vim_tenant_id_exist_atdb: + datacenter_tenants_dict["vim_tenant_id"] = vim_tenant_id + datacenter_tenants_dict["vim_tenant_name"] = vim_tenant_name + datacenter_tenants_dict["user"] = vim_username + datacenter_tenants_dict["passwd"] = vim_password + datacenter_tenants_dict["datacenter_id"] = datacenter_id + if config: + datacenter_tenants_dict["config"] = yaml.safe_dump(config, default_flow_style=True, width=256) + id_ = mydb.new_row('datacenter_tenants', datacenter_tenants_dict, add_uuid=True, confidential_data=True) + datacenter_tenants_dict["uuid"] = id_ + + #fill tenants_datacenters table + datacenter_tenant_id = datacenter_tenants_dict["uuid"] + tenants_datacenter_dict["datacenter_tenant_id"] = datacenter_tenant_id + mydb.new_row('tenants_datacenters', tenants_datacenter_dict) + # create thread + datacenter_id, myvim = get_datacenter_by_name_uuid(mydb, tenant_dict['uuid'], datacenter_id) # reload data + datacenter_name = myvim["name"] + thread_name = get_non_used_vim_name(datacenter_name, datacenter_id, tenant_dict['name'], tenant_dict['uuid']) + new_thread = vim_thread.vim_thread(myvim, task_lock, thread_name, datacenter_name, datacenter_tenant_id, + db=db, db_lock=db_lock, ovim=ovim) + new_thread.start() + thread_id = datacenter_tenants_dict["uuid"] + vim_threads["running"][thread_id] = new_thread + return datacenter_id + except vimconn.vimconnException as e: + raise NfvoException(str(e), HTTP_Bad_Request) def edit_datacenter_to_tenant(mydb, nfvo_tenant, datacenter_id, vim_tenant_id=None, vim_tenant_name=None, @@ -3809,9 +3879,6 @@ def edit_datacenter_to_tenant(mydb, nfvo_tenant, datacenter_id, vim_tenant_id=No return datacenter_id def deassociate_datacenter_to_tenant(mydb, tenant_id, datacenter, vim_tenant_id=None): - #get datacenter info - datacenter_id, myvim = get_datacenter_by_name_uuid(mydb, tenant_id, datacenter) - #get nfvo_tenant info if not tenant_id or tenant_id=="any": tenant_uuid = None @@ -3819,8 +3886,9 @@ def deassociate_datacenter_to_tenant(mydb, tenant_id, datacenter, vim_tenant_id= tenant_dict = mydb.get_table_by_uuid_name('nfvo_tenants', tenant_id) tenant_uuid = tenant_dict['uuid'] + datacenter_id = get_datacenter_uuid(mydb, tenant_uuid, datacenter) #check that this association exist before - tenants_datacenter_dict={"datacenter_id":datacenter_id } + tenants_datacenter_dict={"datacenter_id": datacenter_id } if tenant_uuid: tenants_datacenter_dict["nfvo_tenant_id"] = tenant_uuid tenant_datacenter_list = mydb.get_rows(FROM='tenants_datacenters', WHERE=tenants_datacenter_dict) @@ -3840,6 +3908,7 @@ def deassociate_datacenter_to_tenant(mydb, tenant_id, datacenter, vim_tenant_id= if vim_tenant_dict['created']=='true': #delete tenant at VIM if created by NFVO try: + datacenter_id, myvim = get_datacenter_by_name_uuid(mydb, tenant_id, datacenter) myvim.delete_tenant(vim_tenant_dict['vim_tenant_id']) except vimconn.vimconnException as e: warning = "Not possible to delete vim_tenant_id {} from VIM: {} ".format(vim_tenant_dict['vim_tenant_id'], str(e)) @@ -4130,12 +4199,12 @@ def vim_action_get(mydb, tenant_id, datacenter, item, name): if name and len(content)==1: return {item[:-1]: content[0]} elif name and len(content)==0: - raise NfvoException("No {} found with ".format(item[:-1]) + " and ".join(map(lambda x: str(x[0])+": "+str(x[1]), filter_dict.iteritems())), + raise NfvoException("No {} found with ".format(item[:-1]) + " and ".join([str(x[0])+": "+str(x[1]) for x in iter(filter_dict.items())]), datacenter) else: return {item: content} except vimconn.vimconnException as e: - print "vim_action Not possible to get_%s_list from VIM: %s " % (item, str(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) @@ -4148,7 +4217,7 @@ def vim_action_delete(mydb, tenant_id, datacenter, item, name): #get uuid name content = vim_action_get(mydb, tenant_id, datacenter, item, name) logger.debug("vim_action_delete vim response: " + str(content)) - items = content.values()[0] + items = list(content.values())[0] if type(items)==list and len(items)==0: raise NfvoException("Not found " + item, HTTP_Not_Found) elif type(items)==list and len(items)>1: