def do_request_for_scaling(alert_id): alert = alert_db.get_alert(alert_id) ns_id = alert['ns_id'] ns_status = ns_db.get_ns_status(ns_id) # adding code to allow auto-scaling of nested NSs # the alert and the autoscaling rules are defined in the nested descriptors nested_info = ns_db.get_nested_service_info(ns_id) if nested_info: # we need to look for the corresponding nested nsdId = alert['nsd_id'] nsId_tmp = ns_id + '_' + nsdId particular_nested_info = ns_db.get_particular_nested_service_info(ns_id, nsId_tmp) current_il = particular_nested_info['nested_il'] else: current_il = ns_db.get_ns_il(alert['ns_id']) rule_actions = alert['ruleActions'] for rule_action in rule_actions: if rule_action['scaleNsToLevelData']['nsInstantiationLevel'] == current_il: log_queue.put(["DEBUG", "Current nsInstantiationLevel for nsId: " + ns_id + 'and Alert nsInstantiationLevel is the same']) continue if ns_status in ["FAILED", "TERMINATED", "INSTANTIATING", "SCALING"]: log_queue.put(["DEBUG","Current Status is " + ns_status + " for nsId: " + ns_id ]) log_queue.put(["DEBUG", "This status is not fit to scaling actions"]) continue log_queue.put(["DEBUG", "Do scaling request for alert: " + alert_id]) request_to_so_scale_ns(alert)
def scale_ns(nsId, body): """ Starts a process to scale the Network Service associated with the instance identified by "nsId". Parameters ---------- nsId: string Identifier of the Network Service Instance. body: request body Returns ------- string Id of the operation associated to the Network Service instantiation. """ log_queue.put( ["INFO", "scale_ns for nsId %s with body: %s" % (nsId, body)]) # client = MongoClient() # fgtso_db = client.fgtso # ns_coll = fgtso_db.ns if not ns_db.exists_nsId(nsId): return 404 status = ns_db.get_ns_status(nsId) if status != "INSTANTIATED": return 400 ns_db.set_ns_status(nsId, "INSTANTIATING") operationId = create_operation_identifier(nsId, "INSTANTIATION") ps = Process(target=scale_ns_process, args=(nsId, body)) ps.start() # save process processes[operationId] = ps return operationId
def do_request_for_scaling(alert_id): alert = alert_db.get_alert(alert_id) ns_id = alert['ns_id'] ns_status = ns_db.get_ns_status(ns_id) current_il = ns_db.get_ns_il(alert['ns_id']) rule_actions = alert['ruleActions'] for rule_action in rule_actions: if rule_action['scaleNsToLevelData'][ 'nsInstantiationLevel'] == current_il: log_queue.put([ "DEBUG", "Current nsInstantiationLevel for nsId: " + ns_id + 'and Alert nsInstantiationLevel is the same' ]) continue if ns_status in ["FAILED", "TERMINATED", "INSTANTIATING"]: log_queue.put([ "DEBUG", "Current Status is " + ns_status + " for nsId: " + ns_id ]) log_queue.put( ["DEBUG", "This status is not fit to scaling actions"]) continue log_queue.put(["DEBUG", "Do scaling request for alert: " + alert_id]) request_to_so_scale_ns(alert)
def instantiate_ns(nsId, body, requester): """ Starts a process to instantiate the Network Service associated to the instance identified by "nsId". Parameters ---------- nsId: string Identifier of the Network Service Instance. body: request body Returns ------- string Id of the operation associated to the Network Service instantiation. """ log_queue.put(["INFO", "*****Time measure: SOEc SOEc instantiating a nested"]) log_queue.put(["INFO", "instantiate_ns for nsId %s with body: %s" % (nsId, body)]) #client = MongoClient() #fgtso_db = client.fgtso #ns_coll = fgtso_db.ns if not ns_db.exists_nsId(nsId): return 404 status = ns_db.get_ns_status(nsId) if status != "NOT_INSTANTIATED": return 400 ns_db.save_instantiation_info(nsId, body, requester) operationId = create_operation_identifier(nsId, "INSTANTIATION") ps = Process(target=instantiate_ns_process, args=(nsId, body)) ps.start() # save process processes[operationId] = ps # log_queue.put(["INFO", "*****Time measure: SOEc finished instantiation at SOEc"]) return operationId
def query_ns(nsId): """ Returns the information of the Network Service Instance identified by nsId. Parameters ---------- nsId: string Identifier of the NS instance to terminate. Returns ------- dict Information of the Network Service Instance. """ if not ns_db.exists_nsId(nsId): # TODO create errors return 404 # TODO: lines below are a stub status = ns_db.get_ns_status(nsId) vs_status = "FAILED" if status in ["TERMINATED", "INSTANTIATING", "TERMINATING"]: vs_status = "NOT_INSTANTIATED" elif status == "INSTANTIATED": vs_status = "INSTANTIATED" nsd_id = ns_db.get_nsdId(nsId) nsd_json = nsd_db.get_nsd_json(nsd_id) ns_name = ns_db.get_ns_name(nsId) ns_description = ns_db.get_ns_description(nsId) flavour_id = ns_db.get_ns_flavour_id(nsId) info = { "nsInstanceId": nsId, "nsName": ns_name, "description": ns_description, "nsdId": nsd_id, "flavourId": flavour_id, "nsState": vs_status, } #turn void the sap_info and the monitoring if the service is terminated if vs_status == "NOT_INSTANTIATED": info["sapInfo"] = [] log_queue.put(["INFO", "hola"]) return info if "sapd" in nsd_json["nsd"]: total_sap_info = get_ns_sap_info(nsId, nsd_json["nsd"]["sapd"]) if total_sap_info is not None: info["sapInfo"] = total_sap_info dashboard_info = ns_db.get_dashboard_info(nsId) if "dashboardUrl" in dashboard_info.keys(): info["monitoringDashboardUrl"] = dashboard_info["dashboardUrl"] log_queue.put( ["INFO", "query_result: %s" % dumps(info, indent=4, sort_keys=True)]) return info
def terminate_ns(nsId): """ Function description Parameters ---------- param1: type param1 description Returns ------- name: type return description """ log_queue.put([ "INFO", "*****Time measure: ROE Starting ROE processing to terminate" ]) if (nsId.find('_') == -1): status = ns_db.get_ns_status(nsId) ns_db.set_ns_status(nsId, "TERMINATING") else: status = "INSTANTIATED" # tell the eenet to release the links # line below commented until mtp is ready if (status != "FAILED"): # if it has failed, the MANO platform should have cleaned the deployment and # no any logical link has been established # tell the mano to terminate coreMano = createWrapper() coreMano.terminate_ns(nsId) log_queue.put(["INFO", "*****Time measure: ROE ROE, terminated VNFs"]) # ask network execution engine to deploy the virtual links eenet.uninstall_vls(nsId) log_queue.put( ["INFO", "*****Time measure: ROE ROE, terminated VLs at MTP"]) # remove the information from the nsir nsir_db.delete_nsir_record(nsId) # set operation status as SUCCESSFULLY_DONE if (nsId.find('_') == -1): # update service status in db ns_db.set_ns_status(nsId, "TERMINATED") #the service is single, I can update the operationId and the status log_queue.put(["INFO", "Removing a single NS"]) operationId = operation_db.get_operationId(nsId, "TERMINATION") operation_db.set_operation_status(operationId, "SUCCESSFULLY_DONE") log_queue.put(["INFO", "TERMINATION FINISHED :)"])
def terminate_ns(nsId, requester): """ Starts a process to terminate the NS instance identified by "nsId". Parameters ---------- nsId: string Identifier of the NS instance to terminate. requester: string IP address of the entity making the request Returns ------- operationId: string Identifier of the operation in charge of terminating the service. """ log_queue.put( ["INFO", "*****Time measure: SOEc SOEc terminating a nested"]) if not ns_db.exists_nsId(nsId): return 404 registered_requester = ns_db.get_ns_requester(nsId) if (registered_requester != requester): return 404 # check the ns status status = ns_db.get_ns_status(nsId) log_queue.put( ["INFO", "Network service %s is in %s state." % (nsId, status)]) if status in ["TERMINATING", "TERMINATED", "NOT_INSTANTIATED"]: return 400 # if status is INSTANTIATING, kill the instantiation process if status == "INSTANTIATING": # set related operation as CANCELLED operationId = operation_db.get_operationId(nsId, "INSTANTIATION") operation_db.set_operation_status(operationId, "CANCELLED") # cancel instantiation process process = processes[operationId] process.terminate() process.join() operationId = create_operation_identifier(nsId, "TERMINATION") ps = Process(target=terminate_ns_process, args=(nsId, None)) ps.start() # save process processes[operationId] = ps # log_queue.put(["INFO", "*****Time measure: finished termination at SOEc"]) return operationId
def query_ns(nsId): """ Returns the information of the Network Service Instance identified by nsId. Parameters ---------- nsId: string Identifier of the NS instance to terminate. Returns ------- dict Information of the Network Service Instance. """ if not ns_db.exists_nsId(nsId): return 404 status = ns_db.get_ns_status(nsId) nsd_id = ns_db.get_nsdId(nsId) nsd_json = nsd_db.get_nsd_json(nsd_id) ns_name = ns_db.get_ns_name(nsId) ns_description = ns_db.get_ns_description(nsId) flavour_id = ns_db.get_ns_flavour_id(nsId) info = { "nsInstanceId": nsId, "nsName": ns_name, "description": ns_description, "nsdId": nsd_id, "flavourId": flavour_id, "nsState": status, } if "sapd" in nsd_json["nsd"]: info["sapInfo"] = get_ns_sap_info(nsId, nsd_json["nsd"]["sapd"]) query_result = {"queryNsResult": [info]} log_queue.put([ "DEBUG", "query_result: %s" % dumps(query_result, indent=4, sort_keys=True) ]) return query_result
def scale_ns_process(nsId, body, nestedInfo=None): """ Performs the scaling of the service identified by "nsId" according to the info at body Parameters ---------- nsId: string Identifier of the Network Service Instance. body: request body including scaling operation Returns ------- """ log_queue.put([ "INFO", "*****Time measure for nsId: %s: SOEc SOEc scaling a nested/regular NS" % nsId ]) log_queue.put( ["INFO", "scale_ns_process with nsId %s, body %s" % (nsId, body)]) # get the nsdId that corresponds to nsId if nestedInfo: nsdId = next(iter(nestedInfo)) current_df = nestedInfo[nsdId][0] current_il = nestedInfo[nsdId][1] else: nsdId = ns_db.get_nsdId(nsId) # get current instantiation level current_df = ns_db.get_ns_df(nsId) current_il = ns_db.get_ns_il(nsId) # first get the ns and vnfs descriptors nsd_json = nsd_db.get_nsd_json(nsdId, None) # for each vnf in the NSD, get its json descriptor vnfdIds = nsd_json["nsd"]["vnfdId"] vnfds_json = {} for vnfdId in vnfdIds: vnfds_json[vnfdId] = vnfd_db.get_vnfd_json(vnfdId, None) #request RO sap_info_pre_scaling = ns_db.get_ns_sap_info(nsId) log_queue.put([ "INFO", "*****Time measure for nsId: %s: SOEc SOEc-ROE prepared info for scaling" % (nsId) ]) rooe.scale_ns(nsId, nsd_json, vnfds_json, body, current_df, current_il, nestedInfo) log_queue.put([ "INFO", "*****Time measure for nsId: %s: SOEc SOEc-ROE updated DBs scaling a NS" % (nsId) ]) # checks the result of scaling, maybe it has not be done due to lack of resources operationId = operation_db.get_operationId(nsId, "INSTANTIATION") if ((operation_db.get_operation_status(operationId) == "SUCCESSFULLY_DONE") and ns_db.get_ns_status(nsId) == "INSTANTIATED"): # maybe we have to update the monitoring jobs: we assume that new performance monitoring jobs # will be similar to one already present sap_info = ns_db.get_ns_sap_info(nsId) log_queue.put(["INFO", "new sapInfo after scaling: %s" % (sap_info)]) monitoring.update_ns_monitoring(nsId, nsd_json, vnfds_json, sap_info) log_queue.put([ "INFO", "*****Time measure for nsId: %s: SOEc SOEc updated monitoring info" % nsId ]) log_queue.put([ "DEBUG", "monitoring exporters updated after scaling for nsId %s" % (nsId) ]) # update alerts: it is not needed # however, in the case of aiml_scaling it is needed, to restart the spark job else: if ns_db.get_ns_status(nsId) == "INSTANTIATED": log_queue.put( ["DEBUG", "Scaling operation failed due to lack of resources"]) elif ns_db.get_ns_status(nsId) == "FAILED": log_queue.put( ["DEBUG", "Scaling operation failed at the MANO platform"]) aiml_scaling_info = ns_db.get_aiml_info(nsId, "scaling") if (aiml_scaling_info and (ns_db.get_ns_status(nsId) == "INSTANTIATED")): log_queue.put( ["DEBUG", "The AIML platform is triggering the scaling operation"]) alert_configure.update_ns_aiml_scale_work(nsId, aiml_scaling_info) log_queue.put([ "INFO", "*****Time measure for nsId: %s: SOEc SOEc updated AIML alert job" % nsId ]) log_queue.put(["INFO", "scale_ns_process finished for nsId %s" % (nsId)]) log_queue.put([ "INFO", "*****Time measure for nsId: %s: SOEc SOEc finished scaling a nested/regular NS" % (nsId) ]) notification_db.create_notification_record({ "nsId": nsId, "type": "fa-gears", "text": nsId + " SCALED", "time": datetime.now().strftime("%d/%m/%Y %H:%M:%S.%f") })