import traceback
import ROclient
# from osm_lcm import version as lcm_version, version_date as lcm_version_date, ROclient
-from osm_common import dbmemory
-from osm_common import dbmongo
-from osm_common import fslocal
-from osm_common import msglocal
-from osm_common import msgkafka
-from osm_common.dbbase import DbException
+from osm_common import dbmemory, dbmongo, fslocal, msglocal, msgkafka
+from osm_common import version as common_version
+from osm_common.dbbase import DbException, deep_update
from osm_common.fsbase import FsException
from osm_common.msgbase import MsgException
from os import environ, path
__author__ = "Alfonso Tierno"
min_RO_version = [0, 5, 72]
+# uncomment if LCM is installed as library and installed, and get them from __init__.py
+lcm_version = '0.1.14'
+lcm_version_date = '2018-09-11'
class LcmException(Exception):
for task_name, task in self.task_registry[topic][_id][op_id].items():
if target_task_name and target_task_name != task_name:
continue
- result = task.cancel()
- if result:
- self.logger.debug("{} _id={} order_id={} task={} cancelled".format(topic, _id, op_id, task_name))
+ # result =
+ task.cancel()
+ # if result:
+ # self.logger.debug("{} _id={} order_id={} task={} cancelled".format(topic, _id, op_id, task_name))
class Lcm:
config["database"]["logger_name"] = "lcm.db"
config["storage"]["logger_name"] = "lcm.fs"
config["message"]["logger_name"] = "lcm.msg"
- if "logfile" in config["global"]:
+ if config["global"].get("logfile"):
file_handler = logging.handlers.RotatingFileHandler(config["global"]["logfile"],
maxBytes=100e6, backupCount=9, delay=0)
file_handler.setFormatter(log_formatter_simple)
self.logger.addHandler(file_handler)
- else:
+ if not config["global"].get("nologging"):
str_handler = logging.StreamHandler()
str_handler.setFormatter(log_formatter_simple)
self.logger.addHandler(str_handler)
for k1, logname in {"message": "lcm.msg", "database": "lcm.db", "storage": "lcm.fs"}.items():
config[k1]["logger_name"] = logname
logger_module = logging.getLogger(logname)
- if "logfile" in config[k1]:
+ if config[k1].get("logfile"):
file_handler = logging.handlers.RotatingFileHandler(config[k1]["logfile"],
maxBytes=100e6, backupCount=9, delay=0)
file_handler.setFormatter(log_formatter_simple)
logger_module.addHandler(file_handler)
- if "loglevel" in config[k1]:
+ if config[k1].get("loglevel"):
logger_module.setLevel(config[k1]["loglevel"])
- # self.logger.critical("starting osm/lcm version {} {}".format(lcm_version, lcm_version_date))
+ self.logger.critical("starting osm/lcm version {} {}".format(lcm_version, lcm_version_date))
self.n2vc = N2VC(
log=self.logger,
server=config['VCA']['host'],
# or with list(map(int, version.split(".")))
if N2VC_version < "0.0.2":
raise LcmException("Not compatible osm/N2VC version '{}'. Needed '0.0.2' or higher".format(N2VC_version))
+ if common_version < "0.1.7":
+ raise LcmException("Not compatible osm/common version '{}'. Needed '0.1.7' or higher".format(
+ common_version))
try:
# TODO check database version
def ip_profile_2_RO(ip_profile):
RO_ip_profile = deepcopy((ip_profile))
if "dns-server" in RO_ip_profile:
- RO_ip_profile["dns-address"] = RO_ip_profile.pop("dns-server")
+ if isinstance(RO_ip_profile["dns-server"], list):
+ RO_ip_profile["dns-address"] = []
+ for ds in RO_ip_profile.pop("dns-server"):
+ RO_ip_profile["dns-address"].append(ds['address'])
+ else:
+ RO_ip_profile["dns-address"] = RO_ip_profile.pop("dns-server")
if RO_ip_profile.get("ip-version") == "ipv4":
RO_ip_profile["ip-version"] = "IPv4"
if RO_ip_profile.get("ip-version") == "ipv6":
for vdu_descriptor in vnf_descriptor["vdu"]:
for vdu_interface in vdu_descriptor["interface"]:
if vdu_interface.get("internal-connection-point-ref") == icp_params["id-ref"]:
- if vdu_descriptor["id"] not in RO_vnf["vdus"]:
- RO_vnf["vdus"][vdu_descriptor["id"]] = {}
- if "interfaces" not in RO_vnf["vdus"][vdu_descriptor["id"]]:
- RO_vnf["vdus"][vdu_descriptor["id"]]["interfaces"] = {}
- RO_ifaces = RO_vnf["vdus"][vdu_descriptor["id"]]["interfaces"]
- if vdu_interface["name"] not in RO_ifaces:
- RO_ifaces[vdu_interface["name"]] = {}
-
- RO_ifaces[vdu_interface["name"]]["ip_address"] = icp_params["ip-address"]
+ RO_interface_update = {}
+ if icp_params.get("ip-address"):
+ RO_interface_update["ip_address"] = icp_params["ip-address"]
+ if icp_params.get("mac-address"):
+ RO_interface_update["mac_address"] = icp_params["mac-address"]
+ if RO_interface_update:
+ RO_vnf_update = {"vdus": {vdu_descriptor["id"]: {
+ "interfaces": {vdu_interface["name"]: RO_interface_update}}}}
+ deep_update(RO_vnf, RO_vnf_update)
iface_found = True
break
if iface_found:
})
else: # isinstance str
RO_vld["sites"].append({"netmap-use": vld_params["vim-network-name"]})
+ if "vnfd-connection-point-ref" in vld_params:
+ for cp_params in vld_params["vnfd-connection-point-ref"]:
+ # look for interface
+ for constituent_vnfd in nsd["constituent-vnfd"]:
+ if constituent_vnfd["member-vnf-index"] == cp_params["member-vnf-index-ref"]:
+ vnf_descriptor = vnfd_dict[constituent_vnfd["vnfd-id-ref"]]
+ break
+ else:
+ raise LcmException(
+ "Invalid instantiate parameter vld:vnfd-connection-point-ref:member-vnf-index-ref={} "
+ "is not present at nsd:constituent-vnfd".format(cp_params["member-vnf-index-ref"]))
+ match_cp = False
+ for vdu_descriptor in vnf_descriptor["vdu"]:
+ for interface_descriptor in vdu_descriptor["interface"]:
+ if interface_descriptor.get("external-connection-point-ref") == \
+ cp_params["vnfd-connection-point-ref"]:
+ match_cp = True
+ break
+ if match_cp:
+ break
+ else:
+ raise LcmException(
+ "Invalid instantiate parameter vld:vnfd-connection-point-ref:member-vnf-index-ref={}:"
+ "vnfd-connection-point-ref={} is not present at vnfd={}".format(
+ cp_params["member-vnf-index-ref"],
+ cp_params["vnfd-connection-point-ref"],
+ vnf_descriptor["id"]))
+ RO_cp_params = {}
+ if cp_params.get("ip-address"):
+ RO_cp_params["ip_address"] = cp_params["ip-address"]
+ if cp_params.get("mac-address"):
+ RO_cp_params["mac_address"] = cp_params["mac-address"]
+ if RO_cp_params:
+ RO_vnf_params = {
+ cp_params["member-vnf-index-ref"]: {
+ "vdus": {
+ vdu_descriptor["id"]: {
+ "interfaces": {
+ interface_descriptor["name"]: RO_cp_params
+ }
+ }
+ }
+ }
+ }
+ deep_update(RO_ns_params["vnfs"], RO_vnf_params)
if RO_vld:
RO_ns_params["networks"][vld_params["name"]] = RO_vld
return RO_ns_params
# remove from RO
RO_fail = False
RO = ROclient.ROClient(self.loop, **self.ro_config)
+
# Delete ns
- if nsr_lcm and nsr_lcm.get("RO") and nsr_lcm["RO"].get("nsr_id"):
- RO_nsr_id = nsr_lcm["RO"]["nsr_id"]
- try:
+ RO_nsr_id = RO_delete_action = None
+ if nsr_lcm and nsr_lcm.get("RO"):
+ RO_nsr_id = nsr_lcm["RO"].get("nsr_id")
+ RO_delete_action = nsr_lcm["RO"].get("nsr_delete_action_id")
+ try:
+ if RO_nsr_id:
step = db_nsr_update["detailed-status"] = db_nslcmop_update["detailed-status"] = "Deleting ns at RO"
self.logger.debug(logging_text + step)
- await RO.delete("ns", RO_nsr_id)
+ desc = await RO.delete("ns", RO_nsr_id)
+ RO_delete_action = desc["action_id"]
+ db_nsr_update["_admin.deployed.RO.nsr_delete_action_id"] = RO_delete_action
db_nsr_update["_admin.deployed.RO.nsr_id"] = None
db_nsr_update["_admin.deployed.RO.nsr_status"] = "DELETED"
- except ROclient.ROClientException as e:
- if e.http_code == 404: # not found
- db_nsr_update["_admin.deployed.RO.nsr_id"] = None
- db_nsr_update["_admin.deployed.RO.nsr_status"] = "DELETED"
- self.logger.debug(logging_text + "RO_ns_id={} already deleted".format(RO_nsr_id))
- elif e.http_code == 409: # conflict
- failed_detail.append("RO_ns_id={} delete conflict: {}".format(RO_nsr_id, e))
- self.logger.debug(logging_text + failed_detail[-1])
- RO_fail = True
- else:
- failed_detail.append("RO_ns_id={} delete error: {}".format(RO_nsr_id, e))
- self.logger.error(logging_text + failed_detail[-1])
- RO_fail = True
+ if RO_delete_action:
+ # wait until NS is deleted from VIM
+ step = detailed_status = "Waiting ns deleted from VIM. RO_id={}".format(RO_nsr_id)
+ detailed_status_old = None
+ self.logger.debug(logging_text + step)
+
+ delete_timeout = 20 * 60 # 20 minutes
+ while delete_timeout > 0:
+ desc = await RO.show("ns", item_id_name=RO_nsr_id, extra_item="action",
+ extra_item_id=RO_delete_action)
+ ns_status, ns_status_info = RO.check_action_status(desc)
+ if ns_status == "ERROR":
+ raise ROclient.ROClientException(ns_status_info)
+ elif ns_status == "BUILD":
+ detailed_status = step + "; {}".format(ns_status_info)
+ elif ns_status == "ACTIVE":
+ break
+ else:
+ assert False, "ROclient.check_action_status returns unknown {}".format(ns_status)
+ await asyncio.sleep(5, loop=self.loop)
+ delete_timeout -= 5
+ if detailed_status != detailed_status_old:
+ detailed_status_old = db_nslcmop_update["detailed-status"] = detailed_status
+ self.update_db_2("nslcmops", nslcmop_id, db_nslcmop_update)
+ else: # delete_timeout <= 0:
+ raise ROclient.ROClientException("Timeout waiting ns deleted from VIM")
+
+ except ROclient.ROClientException as e:
+ if e.http_code == 404: # not found
+ db_nsr_update["_admin.deployed.RO.nsr_id"] = None
+ db_nsr_update["_admin.deployed.RO.nsr_status"] = "DELETED"
+ self.logger.debug(logging_text + "RO_ns_id={} already deleted".format(RO_nsr_id))
+ elif e.http_code == 409: # conflict
+ failed_detail.append("RO_ns_id={} delete conflict: {}".format(RO_nsr_id, e))
+ self.logger.debug(logging_text + failed_detail[-1])
+ RO_fail = True
+ else:
+ failed_detail.append("RO_ns_id={} delete error: {}".format(RO_nsr_id, e))
+ self.logger.error(logging_text + failed_detail[-1])
+ RO_fail = True
# Delete nsd
if not RO_fail and nsr_lcm and nsr_lcm.get("RO") and nsr_lcm["RO"].get("nsd_id"):