X-Git-Url: https://osm.etsi.org/gitweb/?p=osm%2FRO.git;a=blobdiff_plain;f=RO%2Fosm_ro%2Fnfvo.py;h=23c5f1c54a00ed8d6caa4419237e6ceab7e5beb2;hp=36109cb817c98f15e64679008c2a1bf4161a102f;hb=f33ea71e00f0fb9ec9f8525d9e50e005702a5354;hpb=4126d05e24ada55226bb13a9d556655811cedadc diff --git a/RO/osm_ro/nfvo.py b/RO/osm_ro/nfvo.py index 36109cb8..23c5f1c5 100644 --- a/RO/osm_ro/nfvo.py +++ b/RO/osm_ro/nfvo.py @@ -30,6 +30,7 @@ __date__ ="$16-sep-2014 22:05:01$" # import imp import json import yaml +from random import choice as random_choice from osm_ro import utils from osm_ro.utils import deprecated from osm_ro.vim_thread import vim_thread @@ -63,7 +64,7 @@ from pkg_resources import iter_entry_points # WIM from .wim import sdnconn -from .wim.wimconn_fake import FakeConnector +from .wim.wimconn_dummy import DummyConnector from .wim.failing_connector import FailingConnector from .http_tools import errors as httperrors from .wim.engine import WimEngine @@ -100,6 +101,7 @@ last_task_id = 0.0 db = None db_lock = Lock() +worker_id = None class NfvoException(httperrors.HttpMappedError): """Common Class for NFVO errors""" @@ -144,20 +146,29 @@ def new_task(name, params, depends=None): def is_task_id(id): return True if id[:5] == "TASK-" else False - -def get_non_used_vim_name(datacenter_name, datacenter_id, tenant_name, tenant_id): - name = datacenter_name[:16] - if name not in vim_threads["names"]: - vim_threads["names"].append(name) - return name - if tenant_name: - name = datacenter_name[:16] + "." + tenant_name[:16] - if name not in vim_threads["names"]: - vim_threads["names"].append(name) - return name - name = datacenter_id - vim_threads["names"].append(name) - return name +def get_process_id(): + """ + Obtain a unique ID for this process. If running from inside docker, it will get docker ID. If not it + will provide a random one + :return: Obtained ID + """ + # Try getting docker id. If fails, get pid + try: + with open("/proc/self/cgroup", "r") as f: + text_id_ = f.readline() + _, _, text_id = text_id_.rpartition("/") + text_id = text_id.replace("\n", "")[:12] + if text_id: + return text_id + except Exception: + pass + # Return a random id + return "".join(random_choice("0123456789abcdef") for _ in range(12)) + +def get_non_used_vim_name(datacenter_name, datacenter_id): + return "{}:{}:{}".format( + worker_id[:12], datacenter_id.replace("-", "")[:32], datacenter_name[:16] + ) # -- Move def get_non_used_wim_name(wim_name, wim_id, tenant_name, tenant_id): @@ -175,7 +186,7 @@ def get_non_used_wim_name(wim_name, wim_id, tenant_name, tenant_id): def start_service(mydb, persistence=None, wim=None): - global db, global_config, plugins, ovim + global db, global_config, plugins, ovim, worker_id db = nfvo_db.nfvo_db(lock=db_lock) mydb.lock = db_lock db.connect(global_config['db_host'], global_config['db_user'], global_config['db_passwd'], global_config['db_name']) @@ -183,8 +194,9 @@ def start_service(mydb, persistence=None, wim=None): persistence = persistence or WimPersistence(db) try: - if "rosdn_fake" not in plugins: - plugins["rosdn_fake"] = FakeConnector + worker_id = get_process_id() + if "rosdn_dummy" not in plugins: + plugins["rosdn_dummy"] = DummyConnector # starts ovim library ovim = Sdn(db, plugins) @@ -237,8 +249,7 @@ def start_service(mydb, persistence=None, wim=None): vim['datacenter_id'], e)) # raise NfvoException("Error at VIM {}; {}: {}".format(vim["type"], type(e).__name__, e), # httperrors.Internal_Server_Error) - thread_name = get_non_used_vim_name(vim['datacenter_name'], vim['datacenter_id'], vim['vim_tenant_name'], - vim['vim_tenant_id']) + thread_name = get_non_used_vim_name(vim['datacenter_name'], vim['datacenter_id']) new_thread = vim_thread(task_lock, plugins, thread_name, None, vim['datacenter_tenant_id'], db=db) new_thread.start() @@ -252,7 +263,7 @@ def start_service(mydb, persistence=None, wim=None): _load_plugin(plugin_name, type="sdn") thread_id = wim['uuid'] - thread_name = get_non_used_vim_name(wim['name'], wim['uuid'], wim['uuid'], None) + thread_name = get_non_used_vim_name(wim['name'], wim['uuid']) new_thread = vim_thread(task_lock, plugins, thread_name, wim['uuid'], None, db=db) new_thread.start() vim_threads["running"][thread_id] = new_thread @@ -977,6 +988,7 @@ def new_vnfd_v3(mydb, tenant_id, vnf_descriptor): # table nets (internal-vld) net_id2uuid = {} # for mapping interface with network + net_id2index = {} # for mapping interface with network for vld in vnfd.get("internal-vld").values(): net_uuid = str(uuid4()) uuid_list.append(net_uuid) @@ -989,6 +1001,7 @@ def new_vnfd_v3(mydb, tenant_id, vnf_descriptor): "type": "bridge", # TODO adjust depending on connection point type } net_id2uuid[vld.get("id")] = net_uuid + net_id2index[vld.get("id")] = len(db_nets) db_nets.append(db_net) # ip-profile, link db_ip_profile with db_sce_net if vld.get("ip-profile-ref"): @@ -1181,7 +1194,7 @@ def new_vnfd_v3(mydb, tenant_id, vnf_descriptor): raise KeyError() if vdu_id in vdu_id2cp_name: - vdu_id2cp_name[vdu_id] = None # more than two connecdtion point for this VDU + vdu_id2cp_name[vdu_id] = None # more than two connection point for this VDU else: vdu_id2cp_name[vdu_id] = db_interface["external_name"] @@ -1216,6 +1229,10 @@ def new_vnfd_v3(mydb, tenant_id, vnf_descriptor): if not icp: raise KeyError("is not referenced by any 'internal-vld'") + # set network type as data + if iface.get("virtual-interface") and iface["virtual-interface"].get("type") in \ + ("SR-IOV", "PCI-PASSTHROUGH"): + db_nets[net_id2index[icp_vld.get("id")]]["type"] = "data" db_interface["net_id"] = net_id2uuid[icp_vld.get("id")] if str(icp_descriptor.get("port-security-enabled")).lower() == "false": db_interface["port_security"] = 0 @@ -2433,7 +2450,6 @@ 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 @@ -2447,7 +2463,7 @@ def new_nsd_v3(mydb, tenant_id, nsd_descriptor): "'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], @@ -2474,7 +2490,7 @@ def new_nsd_v3(mydb, tenant_id, nsd_descriptor): "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" @@ -2963,7 +2979,7 @@ def get_vim_thread(mydb, tenant_id, datacenter_id_name=None, datacenter_tenant_i if datacenter_tenant_id: thread_id = datacenter_tenant_id thread = vim_threads["running"].get(datacenter_tenant_id) - else: + if not thread: where_={"td.nfvo_tenant_id": tenant_id} if datacenter_id_name: if utils.check_valid_uuid(datacenter_id_name): @@ -2975,7 +2991,7 @@ def get_vim_thread(mydb, tenant_id, datacenter_id_name=None, datacenter_tenant_i if datacenter_tenant_id: where_["dt.uuid"] = datacenter_tenant_id datacenters = mydb.get_rows( - SELECT=("dt.uuid as datacenter_tenant_id",), + SELECT=("dt.uuid as datacenter_tenant_id, d.name as datacenter_name",), FROM="datacenter_tenants as dt join tenants_datacenters as td on dt.uuid=td.datacenter_tenant_id " "join datacenters as d on d.uuid=dt.datacenter_id", WHERE=where_) @@ -2983,7 +2999,14 @@ def get_vim_thread(mydb, tenant_id, datacenter_id_name=None, datacenter_tenant_i raise NfvoException("More than one datacenters found, try to identify with uuid", httperrors.Conflict) elif datacenters: thread_id = datacenters[0]["datacenter_tenant_id"] + datacenter_name = datacenters[0]["datacenter_name"] thread = vim_threads["running"].get(thread_id) + if not thread: + thread_name = get_non_used_vim_name(datacenter_name, datacenter_id) + thread = vim_thread(task_lock, plugins, thread_name, None, + thread_id, db=mydb) + thread.start() + vim_threads["running"][thread_id] = thread if not thread: raise NfvoException("datacenter '{}' not found".format(str(datacenter_id_name)), httperrors.Not_Found) return thread_id, thread @@ -3793,6 +3816,7 @@ def instantiate_vnf(mydb, sce_vnf, params, params_out, rollbackList): sce_net2wim_instance = params_out["sce_net2wim_instance"] vnf_net2instance = {} + vnf_net2wim_instance = {} # 2. Creating new nets (vnf internal nets) in the VIM" # For each vnf net, we create it and we add it to instanceNetlist. @@ -3840,6 +3864,7 @@ def instantiate_vnf(mydb, sce_vnf, params, params_out, rollbackList): "created": True, # TODO py3 "sdn": True, }) + vnf_net2wim_instance[net_uuid] = sdn_net_id db_net = { "uuid": net_uuid, @@ -4076,7 +4101,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 + instance_wim_net_id = vnf_net2wim_instance.get(instance_net_id) 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: @@ -4853,8 +4878,10 @@ def instance_action(mydb,nfvo_tenant,instance_id, action_dict): "uuid": iface_uuid, 'instance_vm_id': vm_uuid, "instance_net_id": vm_iface["instance_net_id"], + "instance_wim_net_id": vm_iface["instance_wim_net_id"], 'interface_id': vm_iface['interface_id'], 'type': vm_iface['type'], + 'model': vm_iface['model'], 'floating_ip': vm_iface['floating_ip'], 'port_security': vm_iface['port_security'] } @@ -5239,7 +5266,7 @@ def create_vim_account(mydb, nfvo_tenant, datacenter_id, name=None, vim_id=None, mydb.new_row('tenants_datacenters', tenants_datacenter_dict) # create thread - thread_name = get_non_used_vim_name(datacenter_name, datacenter_id, tenant_dict['name'], tenant_dict['uuid']) + thread_name = get_non_used_vim_name(datacenter_name, datacenter_id) new_thread = vim_thread(task_lock, plugins, thread_name, None, datacenter_tenant_id, db=db) new_thread.start() thread_id = datacenter_tenants_dict["uuid"] @@ -5759,7 +5786,13 @@ def sdn_controller_create(mydb, tenant_id, 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) + # Load plugin if not previously loaded + controller_type = sdn_controller.get("type") + plugin_name = "rosdn_" + controller_type + if plugin_name not in plugins: + _load_plugin(plugin_name, type="sdn") + + thread_name = get_non_used_vim_name(sdn_controller['name'], wim_id) new_thread = vim_thread(task_lock, plugins, thread_name, wim_id, None, db=db) new_thread.start() thread_id = wim_id @@ -5823,6 +5856,8 @@ def datacenter_sdn_port_mapping_set(mydb, tenant_id, datacenter_id, sdn_port_map pci = port.get("pci") element["switch_port"] = port.get("switch_port") element["switch_mac"] = port.get("switch_mac") + element["switch_dpid"] = port.get("switch_dpid") + element["switch_id"] = port.get("switch_id") if not element["switch_port"] and not element["switch_mac"]: raise NfvoException ("The mapping must contain 'switch_port' or 'switch_mac'", httperrors.Bad_Request) for pci_expanded in utils.expand_brackets(pci):