X-Git-Url: https://osm.etsi.org/gitweb/?a=blobdiff_plain;f=osm_nbi%2Fnbi.py;h=8f87135a02d5530794c7fd73db78a8f187b06746;hb=refs%2Fchanges%2F33%2F14133%2F1;hp=8fa61522bac0388a227189339e7192e674c53560;hpb=4cd875d2a38488b5e717258d548eeb8e557ec9a8;p=osm%2FNBI.git diff --git a/osm_nbi/nbi.py b/osm_nbi/nbi.py index 8fa6152..8f87135 100644 --- a/osm_nbi/nbi.py +++ b/osm_nbi/nbi.py @@ -28,6 +28,7 @@ from osm_nbi.authconn import AuthException, AuthconnException from osm_nbi.auth import Authenticator from osm_nbi.engine import Engine, EngineException from osm_nbi.subscriptions import SubscriptionThread +from osm_nbi.utils import cef_event, cef_event_builder from osm_nbi.validation import ValidationError from osm_common.dbbase import DbException from osm_common.fsbase import FsException @@ -46,6 +47,7 @@ database_version = "1.2" auth_database_version = "1.0" nbi_server = None # instance of Server class subscription_thread = None # instance of SubscriptionThread class +cef_logger = None """ North Bound Interface (O: OSM specific; 5,X: SOL005 not implemented yet; O5: SOL005 implemented) @@ -90,7 +92,7 @@ URL: /osm GET POST heal O5 /ns_lcm_op_occs 5 5 / 5 5 5 - TO BE COMPLETED 5 5 + cancel 05 /vnf_instances (also vnfrs for compatibility) O / O /subscriptions 5 5 @@ -473,6 +475,10 @@ valid_url_methods = { "": { "METHODS": ("GET",), "ROLE_PERMISSION": "ns_instances:opps:id:", + "cancel": { + "METHODS": ("POST",), + "ROLE_PERMISSION": "ns_instances:opps:cancel:", + }, }, }, "vnfrs": { @@ -1070,6 +1076,17 @@ class Server(object): } # cherrypy.response.cookie["Authorization"] = outdata["id"] # cherrypy.response.cookie["Authorization"]['expires'] = 3600 + cef_event( + cef_logger, + { + "name": "User Login", + "sourceUserName": token_info.get("username"), + "message": "User Logged In, Project={} Outcome=Success".format( + token_info.get("project_name") + ), + }, + ) + cherrypy.log("{}".format(cef_logger)) elif method == "DELETE": if not token_id and "id" in kwargs: token_id = kwargs["id"] @@ -1078,9 +1095,27 @@ class Server(object): # for logging self._format_login(token_info) token_id = token_info["_id"] + if current_backend != "keystone": + token_details = self.engine.db.get_one("tokens", {"_id": token_id}) + current_user = token_details.get("username") + current_project = token_details.get("project_name") + else: + current_user = "keystone backend" + current_project = "keystone backend" outdata = self.authenticator.del_token(token_id) token_info = None cherrypy.session["Authorization"] = "logout" # pylint: disable=E1101 + cef_event( + cef_logger, + { + "name": "User Logout", + "sourceUserName": current_user, + "message": "User Logged Out, Project={} Outcome=Success".format( + current_project + ), + }, + ) + cherrypy.log("{}".format(cef_logger)) # cherrypy.response.cookie["Authorization"] = token_id # cherrypy.response.cookie["Authorization"]['expires'] = 0 else: @@ -1384,12 +1419,20 @@ class Server(object): **kwargs ): token_info = None - outdata = None + outdata = {} _format = None method = "DONE" engine_topic = None rollback = [] engine_session = None + url_id = "" + log_mapping = { + "POST": "Creating", + "GET": "Fetching", + "DELETE": "Deleting", + "PUT": "Updating", + "PATCH": "Updating", + } try: if not main_topic or not version or not topic: raise NbiException( @@ -1416,6 +1459,8 @@ class Server(object): "URL version '{}' not supported".format(version), HTTPStatus.METHOD_NOT_ALLOWED, ) + if _id is not None: + url_id = _id if ( kwargs @@ -1633,6 +1678,13 @@ class Server(object): ) outdata = {"id": _id} cherrypy.response.status = HTTPStatus.ACCEPTED.value + elif topic == "ns_lcm_op_occs" and item == "cancel": + indata["nsLcmOpOccId"] = _id + self.engine.cancel_item( + rollback, engine_session, "nslcmops", indata, None + ) + self._set_location_header(main_topic, version, topic, _id) + cherrypy.response.status = HTTPStatus.ACCEPTED.value else: _id, op_id = self.engine.new_item( rollback, @@ -1744,6 +1796,36 @@ class Server(object): ): self.authenticator.remove_token_from_cache() + if item is not None: + cef_event( + cef_logger, + { + "name": "User Operation", + "sourceUserName": token_info.get("username"), + "message": "Performing {} operation on {} {}, Project={} Outcome=Success".format( + item, + topic, + url_id, + token_info.get("project_name"), + ), + }, + ) + cherrypy.log("{}".format(cef_logger)) + else: + cef_event( + cef_logger, + { + "name": "User Operation", + "sourceUserName": token_info.get("username"), + "message": "{} {} {}, Project={} Outcome=Success".format( + log_mapping[method], + topic, + url_id, + token_info.get("project_name"), + ), + }, + ) + cherrypy.log("{}".format(cef_logger)) return self._format_out(outdata, token_info, _format) except Exception as e: if isinstance( @@ -1806,6 +1888,38 @@ class Server(object): "status": http_code_value, "detail": error_text, } + if item is not None and token_info is not None: + cef_event( + cef_logger, + { + "name": "User Operation", + "sourceUserName": token_info.get("username", None), + "message": "Performing {} operation on {} {}, Project={} Outcome=Failure".format( + item, + topic, + url_id, + token_info.get("project_name", None), + ), + "severity": "2", + }, + ) + cherrypy.log("{}".format(cef_logger)) + elif token_info is not None: + cef_event( + cef_logger, + { + "name": "User Operation", + "sourceUserName": token_info.get("username", None), + "message": "{} {} {}, Project={} Outcome=Failure".format( + item, + topic, + url_id, + token_info.get("project_name", None), + ), + "severity": "2", + }, + ) + cherrypy.log("{}".format(cef_logger)) return self._format_out(problem_details, token_info) # raise cherrypy.HTTPError(e.http_code.value, str(e)) finally: @@ -1828,12 +1942,17 @@ def _start_service(): """ global nbi_server global subscription_thread + global cef_logger + global current_backend cherrypy.log.error("Starting osm_nbi") # update general cherrypy configuration update_dict = {} engine_config = cherrypy.tree.apps["/osm"].config for k, v in environ.items(): + if k == "OSMNBI_USER_MANAGEMENT": + feature_state = eval(v.title()) + engine_config["authentication"]["user_management"] = feature_state if not k.startswith("OSMNBI_"): continue k1, _, k2 = k[7:].lower().partition("_") @@ -1929,6 +2048,8 @@ def _start_service(): target_version=auth_database_version ) + cef_logger = cef_event_builder(engine_config["authentication"]) + # start subscriptions thread: subscription_thread = SubscriptionThread( config=engine_config, engine=nbi_server.engine @@ -1937,6 +2058,7 @@ def _start_service(): # Do not capture except SubscriptionException backend = engine_config["authentication"]["backend"] + current_backend = backend cherrypy.log.error( "Starting OSM NBI Version '{} {}' with '{}' authentication backend".format( nbi_version, nbi_version_date, backend