X-Git-Url: https://osm.etsi.org/gitweb/?p=osm%2Fvim-emu.git;a=blobdiff_plain;f=src%2Femuvim%2Fapi%2Ftango%2Fllcm.py;h=bd3e1f94be9c5c8a1567b4ce4bb7ca28b5a33b8c;hp=8b4a35064f270f5b18e086e29d45a288b4fee455;hb=85408ed517f100c3e477efd35e54630bf9171af0;hpb=5a5f40533189c4bc21ffe2daed13dd2fa68a2d0b diff --git a/src/emuvim/api/tango/llcm.py b/src/emuvim/api/tango/llcm.py index 8b4a350..bd3e1f9 100755 --- a/src/emuvim/api/tango/llcm.py +++ b/src/emuvim/api/tango/llcm.py @@ -52,6 +52,10 @@ LOG = logging.getLogger("5gtango.llcm") LOG.setLevel(logging.INFO) +CORS_HEADER = {'Access-Control-Allow-Origin': '*', + 'Access-Control-Allow-Methods': 'GET,OPTIONS'} + + GK_STORAGE = "/tmp/vim-emu-tango-llcm/" UPLOAD_FOLDER = os.path.join(GK_STORAGE, "uploads/") CATALOG_FOLDER = os.path.join(GK_STORAGE, "catalog/") @@ -353,6 +357,8 @@ class Service(object): # do some re-naming of fields to be compatible to containernet for i in intfs: if i.get("address"): + LOG.info("Found static address for {}: {}" + .format(i.get("id"), i.get("address"))) i["ip"] = i.get("address") # get ports and port_bindings from the port and publish fields of CNFD @@ -360,11 +366,30 @@ class Service(object): ports = list() # Containernet naming port_bindings = dict() for i in intfs: - if i.get("port"): + if i.get("port"): # field with a single port if not isinstance(i.get("port"), int): LOG.info("Field 'port' is no int CP: {}".format(i)) else: - ports.append(i.get("port")) + ports.append(i.get("port")) # collect all ports + if i.get("ports"): # list with multiple ports + if not isinstance(i.get("ports"), list): + LOG.info("Field 'port' is no list CP: {}".format(i)) + else: + for p in i.get("ports"): + if not isinstance(p, int): + # do some parsing + try: + if "/udp" in p: + p = tuple(p.split("/")) + else: + p = int(p) + ports.append(p) # collect all ports + except BaseException as ex: + LOG.error( + "Could not parse ports list: {}".format(p)) + LOG.error(ex) + else: + ports.append(p) # collect all ports if i.get("publish"): if not isinstance(i.get("publish"), dict): LOG.info("Field 'publish' is no dict CP: {}".format(i)) @@ -396,6 +421,13 @@ class Service(object): conf_envs = self._load_instance_conf_envs(vnf_container_instance_name) cenv.update(conf_envs) + # 5.3 handle optional ipc_mode setting + ipc_mode = u.get("ipc_mode", None) + # 5.4 handle optional devices setting + devices = u.get("devices", []) + # 5.5 handle optional cap_add setting + cap_add = u.get("cap_add", []) + # 6. Start the container LOG.info("Starting %r as %r in DC %r" % (vnf_name, vnf_container_instance_name, target_dc)) @@ -415,6 +447,9 @@ class Service(object): port_bindings=port_bindings, # only publish if explicitly stated in descriptor publish_all_ports=False, + ipc_mode=ipc_mode, + devices=devices, + cap_add=cap_add, type=kwargs.get('type', 'docker')) # add vnfd reference to vnfi vnfi.vnfd = vnfd @@ -712,8 +747,8 @@ class Service(object): lan_hosts = list(lan_net.hosts()) # generate lan ip address for all interfaces (of all involved (V/CDUs)) - for intf in link["connection_points_reference"]: - vnf_id, intf_name = parse_interface(intf) + for intf_ref in link["connection_points_reference"]: + vnf_id, intf_name = parse_interface(intf_ref) if vnf_id is None: continue # skip references to NS connection points units = self._get_vnf_instance_units(instance_uuid, vnf_id) @@ -724,10 +759,20 @@ class Service(object): # Attention: we apply a simplification for multi DU VNFs here: # the connection points of all involved DUs have to have the same # name as the connection points of the surrounding VNF to be mapped. - # This is because we do not consider links specified in the VNFds + # This is because we do not consider links specified in the VNFDs container_name = uvnfi.name - ip_address = "{0}/{1}".format(str(lan_hosts.pop(0)), - lan_net.prefixlen) + + ip_address = None + # get the interface of the unit + intf = self._get_vnfd_cp_from_vnfi(uvnfi, intf_name) + # check if there is a manually assigned address + if intf is not None: + if intf.get("address"): + ip_address = intf.get("address") + if ip_address is None: + # automatically asign an IP from our pool + ip_address = "{0}/{1}".format(str(lan_hosts.pop(0)), + lan_net.prefixlen) LOG.debug( "Setting up E-LAN/E-Tree interface. (%s:%s) -> %s" % ( container_name, intf_name, ip_address)) @@ -1038,7 +1083,7 @@ class Packages(fr.Resource): pkg["pd"]["version"] = sobj.manifest.get("version") pkg["created_at"] = sobj.created_at result.append(pkg) - return result, 200 + return result, 200, CORS_HEADER class Services(fr.Resource): @@ -1060,7 +1105,7 @@ class Services(fr.Resource): service["nsd"]["version"] = sobj.nsd.get("version") service["created_at"] = sobj.created_at result.append(service) - return result, 200 + return result, 200, CORS_HEADER class Instantiations(fr.Resource): @@ -1107,7 +1152,7 @@ class Instantiations(fr.Resource): Returns a list of UUIDs containing all running services. :return: dict / list """ - LOG.info("GET /instantiations or /api/v3/records/services") + LOG.debug("GET /instantiations or /api/v3/records/services") # return {"service_instantiations_list": [ # list(s.instances.iterkeys()) for s in GK.services.itervalues()]} result = list() @@ -1120,7 +1165,7 @@ class Instantiations(fr.Resource): inst["status"] = "running" inst["created_at"] = iobj.get("created_at") result.append(inst) - return result, 200 + return result, 200, CORS_HEADER def delete(self): """