def terminate_ns(self, nsi_id): """ Terminates the network service identified by nsi_id. Parameters ---------- nsi_id: string identifier of the network service instance Returns ------- To be defined """ #logger.info("Deleting ns_name: %s", nsi_id) try: self.client.ns.delete(nsi_id) return "OK" except ClientException as inst: log_queue.put(["INFO", "%s" % inst.message]) return None
def onboard_vnfd(body): """ Function to onboard the VNFD, including the downloading from the url specified in the input. Parameters ---------- body: dict IFA013 request to onboard a vnfd. Returns ------- info: dict Dictionary with the IFA013 answer to the vnfd onboarding process """ log_queue.put(["INFO", "vnf_package_path: %s"% body.vnf_package_path]) filename=wget.download(body.vnf_package_path) tf=tarfile.open(filename) tf.extractall() with tf as _tar: for member in _tar: if member.isdir(): continue print (member.name) if member.name.find("json"): fname = member.name break # upload it in the vnfd_db if (fname): with open(fname) as vnfd_json: vnfd_json = load(vnfd_json) vnfd_record = {"vnfdId": vnfd_json["vnfdId"], "vnfdVersion": vnfd_json["vnfdVersion"], "vnfdName": vnfd_json["vnfProductName"], "vnfdJson": vnfd_json} if vnfd_db.exists_vnfd(vnfd_json["vnfdId"], vnfd_json["vnfdVersion"]): vnfd_db.delete_vnfd_json(vnfd_json["vnfdId"]) # then insert it again (creation or "update") vnfd_db.insert_vnfd(vnfd_record) # upload the descriptor in the MANO platform onboard_vnfd_mano(vnfd_json) # create the answer info = {"onboardedVnfPkgInfoId": vnfd_record["vnfdId"], "vnfId": vnfd_record["vnfdId"]} # remove the tar package and the json file os.remove(fname) return info
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 scale_ns(nsId, body): # noqa: E501 """Scales the Network Service referenced by nsId # noqa: E501 :param nsId: Identifier of the NS to be scaled :type nsId: str :param body: Scale information :type body: dict | bytes :rtype: InlineResponse200 """ notification_db.create_notification_record({ "nsId": nsId, "type": "fa-gears", "text": "SCALING Request for " + nsId, "time": datetime.now().strftime("%d/%m/%Y %H:%M:%S.%f") }) log_queue.put([ "INFO", "*****Time measure for nsId: %s: NBI NBI starting scaling ns at SM" % nsId ]) if connexion.request.is_json: body = NsScaleRequest.from_dict( connexion.request.get_json()) # noqa: E501 # SCALING is done with requester = connexion.request.remote_addr operationId = soep.scale_ns(nsId, body, requester) # process errors if operationId == 400: return error400("network service is not in NOT_INSTANTIATED state") if operationId == 404: return error404("nsId not found or network service cannot be scaled") log_queue.put([ "INFO", "*****Time measure for nsId: %s: NBI NBI returning operation ID scaling ns at SM" % nsId ]) return {"operationId": operationId}
def onboard_appd(body): """ Function to onboard the APPD, including the downloading from the url specified in the input. Parameters ---------- body: dict IFA013 request to onboard an appd. Returns ------- info: dict Dictionary with the IFA013 answer to the appd onboarding process """ log_queue.put(["INFO", "app_package_path: %s"% body.app_package_path]) filename=wget.download(body.app_package_path) tf=tarfile.open(filename) tf.extractall() with tf as _tar: for member in _tar: if member.isdir(): continue print (member.name) if member.name.find("json"): fname = member.name break # upload it in the vnfd_db if (fname): with open(fname) as appd_json: appd_json = load(appd_json) appd_record = {"appdId": appd_json["appDId"], "appdVersion": appd_json["appDVersion"], "appdName": appd_json["appName"], "appdJson": appd_json} if appd_db.exists_appd(appd_json["appDId"], appd_json["appDVersion"]): appd_db.delete_appd_json(appd_json["appDId"]) # then insert it again (creation or "update") appd_db.insert_appd(appd_record) # create the answer info = {"onboardedAppPkgId": appd_record["appdId"], "appDId": appd_record["appdId"]} # remove the tar package and the json file os.remove(filename) os.remove(fname) return info
def convert_expresion(performance_metric, job_id, ns_id, vnfd_id): performance_metric_parts = performance_metric.split(".") try: return_expresion = expressions[(performance_metric_parts[0].lower())] except KeyError as er: exception_msg = "Error to create expressions for the Monitoring platform \n" exception_msg += "Can't find key expressions for " + str(er) log_queue.put(["ERROR", exception_msg]) raise Exception(exception_msg) return_expresion = return_expresion.replace("{job_id}", 'job="' + str(job_id) + '"') return_expresion = return_expresion.replace("{nsId}", 'nsId="' + str(ns_id) + '"') return_expresion = return_expresion.replace( "{vnfdId}", 'vnfdId="' + str(vnfd_id) + '"') if performance_metric_parts[0] == "ByteIncoming": return_expresion = return_expresion.replace( "{port}", 'device="' + str(performance_metric_parts[2]) + '"') return return_expresion
def create_prometheus_scraper(nsid, kafka_topic, vnfid, performance_metric, expression, collectionPeriod): """ Parameters ---------- operationId: dict Object for creating Returns ------- name: type return prometheus scraper """ header = {'Accept': 'application/json', 'Content-Type': 'application/json'} body = { "performanceMetric": performance_metric, "nsid": nsid, "vnfid": vnfid, "interval": collectionPeriod, "kafkaTopic": kafka_topic, "expression": expression } monitoring_uri = "http://" + monitoring_ip + ":" + monitoring_port + monitoring_base_path + "/prometheus_scraper" try: conn = HTTPConnection(monitoring_ip, monitoring_port) conn.request("POST", monitoring_uri, body=dumps(body), headers=header) rsp = conn.getresponse() resources = rsp.read() resp_prometheus_scraper = resources.decode("utf-8") log_queue.put(["DEBUG", "Prometheus Scraper from Config Manager are:"]) log_queue.put(["DEBUG", resp_prometheus_scraper]) resp_prometheus_scraper = loads(resp_prometheus_scraper) log_queue.put(["DEBUG", "Prometheus Scraper from Config Manager are:"]) log_queue.put(["DEBUG", dumps(resp_prometheus_scraper, indent=4)]) conn.close() except ConnectionRefusedError: # the Config Manager is not running or the connection configuration is wrong log_queue.put([ "ERROR", "the Config Manager is not running or the connection configuration is wrong" ]) return resp_prometheus_scraper
def get_mtp_resources(): """ Function description Parameters ---------- param1: type param1 description Returns ------- name: type return description """ # read mtp properties config = RawConfigParser() config.read("../../mtp.properties") mtp_ip = config.get("MTP", "mtp.ip") mtp_port = config.get("MTP", "mtp.port") mtp_path = config.get("MTP", "mtp.path") mtp_uri = "http://" + mtp_ip + ":" + mtp_port + mtp_path + "/resources" # connect to MTP aznd make the request header = {'Content-Type': 'application/json', 'Accept': 'application/json'} resources = {} # code below commented until MTP is ready try: conn = HTTPConnection(mtp_ip, mtp_port) conn.request("GET", mtp_uri, None, header) rsp = conn.getresponse() resources = rsp.read() resources = resources.decode("utf-8") log_queue.put(["DEBUG", "Resources from MTP are:"]) log_queue.put(["DEBUG", resources]) resources = json.loads(resources) log_queue.put(["DEBUG", "Resources from MTP are:"]) log_queue.put(["DEBUG", json.dumps(resources, indent=4)]) conn.close() except ConnectionRefusedError: # the MTP server is not running or the connection configuration is wrong log_queue.put([ "ERROR", "the MTP server is not running or the connection configuration is wrong" ]) return resources
def get_pm_jobs(nsd, deployed_vnfs_info, nsId): """ Parses the nsd and vnfd descriptors to find possible monitoring jobs Parameters ---------- nsd: json Network service descriptor deployed_vnfs_info: json dictionary with connection points of the differents vnfs after instantiating nsId: String with the Network Service Id Returns ------- List List of dictionaries with info of the monitoring jobs """ monitoring_jobs = [] if "monitoredInfo" in nsd["nsd"].keys(): monitored_params = nsd["nsd"]["monitoredInfo"] for param in monitored_params: vnf = param["monitoringParameter"]["performanceMetric"] for sap in deployed_vnfs_info: for elem in deployed_vnfs_info[sap]: for key in elem.keys(): if (vnf.find(key) != -1): # this is the vnf that has a external IP to connect and we can establish an exporter pm_job = {} pm_job['name'] = "NS-" + nsId + "-VNF-" + key pm_job['address'] = elem[key] pm_job[ 'port'] = 9100 # assuming that it is always a VM exporter pm_job[ 'collectionPeriod'] = 15 # agreed 15 seconds as default pm_job['monitoringParameterId'] = param[ "monitoringParameter"]["monitoringParameterId"] pm_job['performanceMetric'] = param[ "monitoringParameter"]["performanceMetric"] pm_job['vnfdId'] = key pm_job['nsId'] = nsId monitoring_jobs.append(pm_job) log_queue.put(["INFO", "monitoring jobs are: %s" % monitoring_jobs]) return monitoring_jobs
def wait_execution(self, execution): """ Holds the execution until a task finishes in cloudify. Parameters ---------- execution: string identifier of the execution Returns ------- To be defined """ log_queue.put(["DEBUG", "CLOUDIFY_WRAPPER: wait_execution:%s" % execution]) execution_data = self.get_execution(execution) while execution_data["status"] not in ["terminated"]: time.sleep(5) execution_data = self.get_execution(execution) if execution_data["status"] == "failed": log_queue.put(["ERROR", "CLOUDIFY_WRAPPER: wait_execution:%s" % execution]) return False return True
def get_execution(self, execution): """ Retrieves the execution information from cloudify ---------- execution: string identifier of the execution Returns ------- Dictionary with the execution status """ url = 'http://%s/api/v3.1/executions/%s' % (self.nfvo_ip, execution) log_queue.put(["DEBUG", "CLOUDIFY_WRAPPER: get_execution:%s" % url]) headers = {'Tenant': self.tenant} response = requests.get( url, auth=HTTPBasicAuth(self.user, self.password), headers=headers, ) return response.json()
def update_federated_connections_paths(nsId, body): # noqa: E501 """Query towards the federated/provider domain to update connections towards the local and other federate domains after a scaling operation # noqa: E501 :param nsId: nsId of the nested federated network service in federated domain :type nsId: str :param body: Set of pairs of interconnections between VNFs to be established or removed :type body: dict | bytes :rtype: None """ if connexion.request.is_json: body = UpdateInterconnectionPaths.from_dict(connexion.request.get_json()) # noqa: E501 requester = connexion.request.remote_addr pathInfo = crooe.update_federated_internested_connections_reply(nsId, body, requester) if pathInfo == 404: return error404("The update requests coming from the federated domain are not returning valid information") log_queue.put(["DEBUG", "EWBI UPDATED pathInfo: %s"%pathInfo]) return {"updatedPathInfo": pathInfo}
def federated_instance_info(nsId, body): # noqa: E501 """Query towards the federated/provider domain to know info about: CIDR/pools that have to be used/not used in the federated domain # noqa: E501 :param nsId: nsId of the nested federated network service in federated domain :type nsId: str :param body: Identifier of the descriptor in the federated domain :type body: dict | bytes :rtype: InlineResponse2002 """ if connexion.request.is_json: body = FederatedInfo.from_dict(connexion.request.get_json()) # noqa: E501 requester = connexion.request.remote_addr instanceInfo = crooe.get_federated_network_instance_info_reply(nsId, body.nsd_id, requester) if instanceInfo == 404: return error404("The requests coming from the local domain is not returning valid information") log_queue.put(["DEBUG", "EWBI instance_info: %s"%instanceInfo]) return {"instanceInfo": instanceInfo}
def delete_element(): if request.method == 'POST': table_to_choose = request.form['table_to_choose'] id_to_be_deleted = request.form['id'] if table_to_choose == "user": user_db.remove_user_by_id(id_to_be_deleted) elif table_to_choose == "vnfd": vnfd_db.remove_vnfd_by_id(id_to_be_deleted) elif table_to_choose == "nsd": nsd_db.remove_nsd_by_id(id_to_be_deleted) elif table_to_choose == "ns": ns_db.remove_ns_by_id(id_to_be_deleted) elif table_to_choose == "nsir": nsir_db.remove_nsir_by_id(id_to_be_deleted) elif table_to_choose == "operation": operation_db.remove_operation_by_id(id_to_be_deleted) message = {'Success': 'Deleted "{}" from "{}" table'.format(id_to_be_deleted, table_to_choose)} log_queue.put(["INFO", message['Success']]) flash(message['Success'], 'success') return redirect(request.referrer)
def federated_network_info(nsId, body): # noqa: E501 """Query towards the consumer/local domain about the information: CIDR/pools that have to be used/not used in the federated domain # noqa: E501 :param nsId: nsId of the composite in consumer domain :type nsId: str :param body: Identifier of the descriptor in the federated domain :type body: dict | bytes :rtype: InlineResponse2001 """ if connexion.request.is_json: body = FederatedInfo.from_dict(connexion.request.get_json()) # noqa: E501 requester = connexion.request.remote_addr networkInfo = crooe.get_federated_network_info_reply(nsId, body.nsd_id,requester) if networkInfo == 404: return error404("The requests coming from the federated domain are not returning valid information") log_queue.put(["DEBUG", "EWBI network_info: %s"%networkInfo]) return {"networkInfo": networkInfo}
def federated_connection_paths(nsId, body): # noqa: E501 """Query towards the federated/provider domain to perform connections towards the local and other federate domains # noqa: E501 :param nsId: nsId of the nested federated network service in federated domain :type nsId: str :param body: Identifier of the descriptor in the federated domain :type body: dict | bytes :rtype: None """ if connexion.request.is_json: body = InterconnectionPaths.from_dict(connexion.request.get_json()) # noqa: E501 requester = connexion.request.remote_addr pathInfo = crooe.set_federated_internested_connections_reply(nsId, body, requester) if pathInfo == 404: return error404("The requests coming from the federated domain is not returning valid information") log_queue.put(["DEBUG", "EWBI pathInfo: %s"%pathInfo]) return {"pathInfo": pathInfo}
def create_osm_files(osm_json, directory): """ Create the tar.gz file containing the YAML descriptor (in OSM format) to be onboarded on configured OSM :param osm_json: json representing the nsd/vnfd descriptor in OSM format :param directory: directory where tar.gz file is created :return: yaml_filename, yaml_root: name of tar.gz file (with corresponding path) and directory """ if 'vnfd:vnfd-catalog' in osm_json: name_osm_descriptor = osm_json['vnfd:vnfd-catalog']['vnfd'][0]['name'] # in order to osm to upload this package name_osm_descriptor = name_osm_descriptor + '_vnfd' else: name_osm_descriptor = osm_json['nsd:nsd-catalog']['nsd'][0]['name'] # in order to osm to upload this package name_osm_descriptor = name_osm_descriptor + '_nsd' yaml_root = os.path.join(directory, name_osm_descriptor) # create the directory of yaml if os.path.exists(yaml_root): log_queue.put([ "INFO", " '{}' directory existing. Going to erase it.".format(yaml_root) ]) shutil.rmtree(yaml_root) os.makedirs(yaml_root) with open(os.path.join(yaml_root, "{}.yaml".format(name_osm_descriptor)), 'w') as ex: yaml.dump(osm_json, ex, default_flow_style=False) # set the type of Descriptor (NSD, VNFD or not valid) # create the 'icons' sub-directory (no logo inserted so far) os.makedirs(os.path.join(yaml_root, 'icons')) # # create a tar.gz of the yaml (and related folder)) yaml_filename = yaml_root + '.tar.gz' if os.path.exists(yaml_filename): log_queue.put([ "INFO", " '{}' directory existing. Going to erase it.".format(yaml_root) ]) os.remove(yaml_filename) with tarfile.open(yaml_filename, "w:gz") as tar: tar.add(yaml_root, arcname=os.path.basename(yaml_root)) return yaml_filename, yaml_root
def set_install_rvm_agent(self, install_rvm_agent, agent_id = None): self.__install_rvm_agent = install_rvm_agent if self.__install_rvm_agent == "yes": body = { "agent_id": agent_id, "install_method": "cloud_init", "description": self.__name , "daemon_user": self.__user_image } agent_info = self.create_rvm_agent(**body) if agent_info is None: log_queue.put( ["ERROR", "the Monitoring platform is not running or the connection configuration is wrong"]) agent_id = agent_info['agent_id'] user_data_content = agent_info['cloud_init_script'] user_data_content = self.add_spaces(12, user_data_content) self.__user_data_content = user_data_content else: self.__user_data_content = "" return agent_id
def get_service_status(self, ns_name): log_queue.put(["INFO", "In OSM Wrapper, get service status"]) resp = self.client.ns.get(ns_name) if self.release == "3": nsopdata = self.client.ns.get_opdata(resp['id']) nsr = nsopdata['nsr:nsr'] # #logger.info("evaluando servicio: %s", nsopdata) if (nsr['name-ref'] == ns_name): # #logger.info("He encontrado el servicio: %s", ns_name) if ((nsr['operational-status'] == 'running') and (nsr['config-status'] == 'configured')): return resp['nsd'] else: return None else: if ((resp['operational-status'] == 'running') and (resp['config-status'] == 'configured')): # #logger.info("resssssppp: %s", resp) return resp['nsd'] else: return None
def terminate_ns_process(nsId, aux): """ Function description Parameters ---------- param1: type param1 description Returns ------- name: type return description """ #first terminate the alert/monitoring jobs log_queue.put(["INFO", "SOEc eliminating service with nsId: %s" % nsId]) if (nsId.find("_") == -1): alert_configure.delete_ns_alerts(nsId) #terminate monitoring jobs monitoring.stop_ns_monitoring(nsId) #terminate alerts rooe.terminate_ns(nsId) ns_db.delete_ns_record(nsId)
def scale_ns_process(nsId, body): """ 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", "scale_ns_process with nsId %s, body %s" % (nsId, body)]) # get the nsdId that corresponds to nsId 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) rooe.scale_ns(nsId, nsd_json, vnfds_json, body, current_df, current_il) # 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(["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 aiml_scaling_info = ns_db.get_aiml_info(nsId, "scaling") if (aiml_scaling_info): 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", "scale_ns_process finished for nsId %s" % (nsId)])
def terminate_ns(): """ This function terminate a ns :return: redirect to the previous page """ if request.method == 'POST': nsId = request.form['nsId'] # attacking directly the REST API rest_api_path_ns = "/5gt/so/v1/ns" headers = { "Content-type": "application/json" } try: response_terminate = requests.put(url="http://localhost:{}{}/{}/terminate".format(so_port, rest_api_path_ns, nsId), headers=headers) if response_terminate.status_code == 200: operationId = json.loads(response_terminate.content.decode('utf-8'))['operationId'] message = {'Success': "Terminated NS with operationId: '{}'".format(operationId)} log_queue.put(["INFO", message['Success']]) flash(message['Success'], 'success') else: log_queue.put(["ERROR", "Error :{}, {}".format(response_terminate.status_code, response_terminate.content)]) raise ConnectionError("Error :{}, {}".format(response_terminate.status_code, response_terminate.content)) except(ConnectionError, TypeError) as e: log_queue.put(["ERROR", str(e)]) flash("Instantiation Failed: {}".format(e), 'danger') return redirect(request.referrer)
def configure_ns_alerts(nsId, nsdId, nsd, vnfds, deployed_vnfs_info): """ """ # parse NSD / VNFDs to get the list of monitoring jobs to be configured and its information # ! we need the input of the vnfds, to have the endpoints! alerts_dict = {} alert_db_entity = {} # 5Growth I4 R1: AIML scaling rules have prevalence over autoscaling rules auto_scaling = True if "aimlRules" in nsd["nsd"].keys(): for rule in nsd["nsd"]["aimlRules"]: if (rule["problem"] == "scaling"): auto_scaling = False log_queue.put(["DEBUG", "Scaling operation driven by AIML"]) else: auto_scaling = True log_queue.put( ["DEBUG", "Scaling operation driven by Autoscaling rules"]) if (auto_scaling): log_queue.put(["DEBUG", "Configuring Alerts"]) alerts = get_pm_alerts(nsd, deployed_vnfs_info, nsId) # for each job request the Monitoring Configuration Manager to configure the alert and save the alert_id for alert_idx, alert in enumerate(alerts): alert_request = { "alertName": alert['rule_id'], 'query': alert['query'], "labels": [ # { # "key": "string", # "value": "string" # } ], 'severity': alert['severity'], 'value': alert['value'], 'kind': alert['kind'], 'for': str(alert['thresholdTime']) + "s", 'target': alert['target'] } result_alert = create_alert(alert_request) # send alert request alert_id = result_alert['alertId'] alerts[alert_idx].update({'alertId': alert_id}) alerts[alert_idx].update({'nsId': nsId}) alerts_dict[alert_id] = alerts[alert_idx] # create object to save in db alerts alert_db_entity = {} alert_db_entity['alert_id'] = alert_id alert_db_entity['status'] = "" alert_db_entity['nsd_id'] = nsdId alert_db_entity['ns_id'] = nsId alert_db_entity['rule_id'] = alert['rule_id'] alert_db_entity['thresholdTime'] = alert['thresholdTime'] alert_db_entity['cooldownTime'] = alert['cooldownTime'] alert_db_entity['enabled'] = alert['enabled'] alert_db_entity['ruleActions'] = alert['ruleActions'] alert_db_entity['target'] = alert['target'] alert_db_entity['timestamp'] = "" alert_db.create_alert_record(alert_db_entity) # save the list of alerts in the database ns_db.set_alert_info(nsId, alerts_dict)
def terminate_ns(nsId): # noqa: E501 """Terminates the Network Service identified by nsId. # noqa: E501 :param nsId: ID of the network service :type nsId: str :rtype: InlineResponse200 """ notification_db.create_notification_record({ "nsId": nsId, "type": "fa-trash-o", "text": "TERMINATION Request for " + nsId, "time": datetime.now().strftime("%d/%m/%Y %H:%M:%S.%f") }) log_queue.put([ "INFO", "*****Time measure for nsId: %s: NBI NBI starting termination ns at SM" % (nsId) ]) requester = connexion.request.remote_addr operationId = soep.terminate_ns(nsId, requester) if operationId == 400: return error400( "network service is not in INSTANTIATED or INSTANTIATING state") if operationId == 404: return error404( "nsId not found or the requester has not authorization to perform this operation" ) log_queue.put([ "INFO", "*****Time measure for nsId: %s: NBI NBI returning operation ID termination ns at SM" % (nsId) ]) return {"operationId": operationId}
def terminate_ns_process(nsId, aux): """ Function description Parameters ---------- param1: type param1 description Returns ------- name: type return description """ #first terminate the alert/monitoring jobs # When alert rest API will be ready uncomment log_queue.put(["INFO", "SOEc eliminating service with nsId: %s" % nsId]) if (nsId.find("_") == -1): # terminate alerts alert_configure.delete_ns_alerts(nsId) # terminate monitoring jobs monitoring.stop_ns_monitoring(nsId) log_queue.put([ "INFO", "*****Time measure: SOEc terminated monitoring exporters and alerts" ]) #terminate the service rooe.terminate_ns(nsId) log_queue.put( ["INFO", "*****Time measure: SOEc updated databases terminating"])
def is_problem_resolved(alert): str_starts_at = str(alert['startsAt']) alertname = alert["labels"]["alertname"] curent_time = datetime.now(pytz.utc) try: time_stamp = iso8601.parse_date(alert_db.get_timestamp(alertname)) except iso8601.iso8601.ParseError: log_queue.put(["ERROR", "Error during parse timestamp"]) time_stamp = datetime.now(pytz.utc) alert_db.set_timestamp(alertname, str(datetime.now(pytz.utc))) db_alert = alert_db.get_alert(alertname) if db_alert == None: log_queue.put( ["DEBUG", "Alert: " + alertname + " not found in database"]) return True str_timeout = db_alert['cooldownTime'] timeout = timedelta(seconds=int(str_timeout)) if curent_time - time_stamp > timeout: log_queue.put([ "DEBUG", "Timeout unresolved alert = " + alertname + " start date = " + str_starts_at ]) alert_db.set_timestamp(alertname, str(datetime.now(pytz.utc))) return False else: return True
def get_ns_sap_info(nsi_id, nsd_saps): log_queue.put( ["DEBUG", "get_ns_sap_info nsi_id:%s nsd_sap:%s" % (nsi_id, nsd_saps)]) sap_list = [] nsi_sap_info = ns_db.get_ns_sap_info(nsi_id) if nsi_sap_info is None: return None log_queue.put([ "DEBUG", "get_ns_sap_info nsi_id:%s nsi_sap:%s" % (nsi_id, nsi_sap_info) ]) for current_sap in nsd_saps: if current_sap["cpdId"] in nsi_sap_info: sap_address = nsi_sap_info[current_sap["cpdId"]] user_access_info = { "sapdId": current_sap["cpdId"], "address": sap_address } new_sap = { "sapInstanceId": "0", "sapdId": current_sap["cpdId"], "sapName": current_sap["cpdId"], "description": current_sap["description"], "address": sap_address, "userAccessInfo": [user_access_info] } sap_list.append(new_sap) log_queue.put([ "DEBUG", "get_ns_sap_info output nsi_id:%s nsi_sap:%s" % (nsi_id, sap_list) ]) return sap_list
def register(): """ Register a new user for the SO platform. Allowed GET and POST methods. :return: rendering of the corresponding html page """ # enter in the page by the GET method, only render the register.html page if request.method == 'GET': return render_template('register.html') # enter in the page by a POST method (filled the register page) else: username = request.form['username'] password = request.form['password'] password_confirmed = request.form['password_confirmed'] if password != password_confirmed: logger.debug("Confirmed password is not the same!") flash('Confirmed password is not the same!', 'danger') return render_template("register.html") # hashing the password with md5 user = user_db.get_specific_user({"username": username}) # check if the entered 'user' is already in the db if user: log_queue.put( ["DEBUG", "Username already in database".format(username)]) flash('Username already registered', 'danger') return render_template("register.html") else: hash_object = hashlib.md5(password.encode()) # insert the new user (and hashed password) in the db user_db.insert_user({ "username": username, "password": hash_object.hexdigest(), "role": "Admin" }) log_queue.put( ["INFO", 'User "{}" successfully registered'.format(username)]) flash('User "{}" successfully registered'.format(username), 'success') return render_template("login.html")
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", "*****Time measure for nsId: %s: SOEc SOEc scaling a nested/regular NS" % (nsId) ]) 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, "SCALING") operationId = create_operation_identifier(nsId, "INSTANTIATION") ps = Process(target=scale_ns_process, args=(nsId, body)) ps.start() # save process processes[operationId] = ps # log_queue.put(["INFO", "*****Time measure for nsId: %s: SOEc SOEc returned scaling operation ID at SOEc" % (nsId)]) 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