X-Git-Url: https://osm.etsi.org/gitweb/?a=blobdiff_plain;f=osm_nbi%2Fnbi.py;h=fed3205137440e70dc08733bda0c3f4104e8d756;hb=ea3a2c2766d6d6c652c758b8b5c3a90b004f157a;hp=d78379f77103b8b70629183333300361acf35944;hpb=c528d882fea9761b256f920e7305a5c60aead3e1;p=osm%2FNBI.git diff --git a/osm_nbi/nbi.py b/osm_nbi/nbi.py index d78379f7..fed32051 100644 --- a/osm_nbi/nbi.py +++ b/osm_nbi/nbi.py @@ -32,6 +32,7 @@ from osm_nbi.validation import ValidationError from osm_common.dbbase import DbException from osm_common.fsbase import FsException from osm_common.msgbase import MsgException +from osm_common.wftemporal import WFTemporal from http import HTTPStatus from codecs import getreader from os import environ, path @@ -463,8 +464,8 @@ valid_url_methods = { }, "verticalscale": { "METHODS": ("POST",), - "ROLE_PERMISSION": "ns_instances:id:verticalscale:" - }, + "ROLE_PERMISSION": "ns_instances:id:verticalscale:", + }, }, }, "ns_lcm_op_occs": { @@ -497,33 +498,42 @@ valid_url_methods = { }, "vnflcm": { "v1": { - "vnf_instances": {"METHODS": ("GET", "POST"), - "ROLE_PERMISSION": "vnflcm_instances:", - "": {"METHODS": ("GET", "DELETE"), - "ROLE_PERMISSION": "vnflcm_instances:id:", - "scale": {"METHODS": ("POST",), - "ROLE_PERMISSION": "vnflcm_instances:id:scale:" - }, - "terminate": {"METHODS": ("POST",), - "ROLE_PERMISSION": "vnflcm_instances:id:terminate:" - }, - "instantiate": {"METHODS": ("POST",), - "ROLE_PERMISSION": "vnflcm_instances:id:instantiate:" - }, - } - }, - "vnf_lcm_op_occs": {"METHODS": ("GET",), - "ROLE_PERMISSION": "vnf_instances:opps:", - "": {"METHODS": ("GET",), - "ROLE_PERMISSION": "vnf_instances:opps:id:" - }, - }, - "subscriptions": {"METHODS": ("GET", "POST"), - "ROLE_PERMISSION": "vnflcm_subscriptions:", - "": {"METHODS": ("GET", "DELETE"), - "ROLE_PERMISSION": "vnflcm_subscriptions:id:" - } - }, + "vnf_instances": { + "METHODS": ("GET", "POST"), + "ROLE_PERMISSION": "vnflcm_instances:", + "": { + "METHODS": ("GET", "DELETE"), + "ROLE_PERMISSION": "vnflcm_instances:id:", + "scale": { + "METHODS": ("POST",), + "ROLE_PERMISSION": "vnflcm_instances:id:scale:", + }, + "terminate": { + "METHODS": ("POST",), + "ROLE_PERMISSION": "vnflcm_instances:id:terminate:", + }, + "instantiate": { + "METHODS": ("POST",), + "ROLE_PERMISSION": "vnflcm_instances:id:instantiate:", + }, + }, + }, + "vnf_lcm_op_occs": { + "METHODS": ("GET",), + "ROLE_PERMISSION": "vnf_instances:opps:", + "": { + "METHODS": ("GET",), + "ROLE_PERMISSION": "vnf_instances:opps:id:", + }, + }, + "subscriptions": { + "METHODS": ("GET", "POST"), + "ROLE_PERMISSION": "vnflcm_subscriptions:", + "": { + "METHODS": ("GET", "DELETE"), + "ROLE_PERMISSION": "vnflcm_subscriptions:id:", + }, + }, } }, "nst": { @@ -620,12 +630,14 @@ valid_url_methods = { }, "nsfm": { "v1": { - "alarms": {"METHODS": ("GET", "PATCH"), - "ROLE_PERMISSION": "alarms:", - "": {"METHODS": ("GET", "PATCH"), - "ROLE_PERMISSION": "alarms:id:", - }, - } + "alarms": { + "METHODS": ("GET", "PATCH"), + "ROLE_PERMISSION": "alarms:", + "": { + "METHODS": ("GET", "PATCH"), + "ROLE_PERMISSION": "alarms:id:", + }, + } }, }, } @@ -648,6 +660,7 @@ class Server(object): self.engine = Engine(self.authenticator) def _format_in(self, kwargs): + error_text = "" # error_text must be initialized outside try try: indata = None if cherrypy.request.body.length: @@ -884,54 +897,87 @@ class Server(object): # NS Fault Management @cherrypy.expose - def nsfm(self, version=None, topic=None, uuid=None, project_name=None, ns_id=None, *args, **kwargs): - if topic == 'alarms': + def nsfm( + self, + version=None, + topic=None, + uuid=None, + project_name=None, + ns_id=None, + *args, + **kwargs, + ): + if topic == "alarms": try: method = cherrypy.request.method - role_permission = self._check_valid_url_method(method, "nsfm", version, topic, None, None, *args) - query_string_operations = self._extract_query_string_operations(kwargs, method) + role_permission = self._check_valid_url_method( + method, "nsfm", version, topic, None, None, *args + ) + query_string_operations = self._extract_query_string_operations( + kwargs, method + ) - self.authenticator.authorize(role_permission, query_string_operations, None) + self.authenticator.authorize( + role_permission, query_string_operations, None + ) # to handle get request - if cherrypy.request.method == 'GET': + if cherrypy.request.method == "GET": # if request is on basis of uuid - if uuid and uuid != 'None': + if uuid and uuid != "None": try: alarm = self.engine.db.get_one("alarms", {"uuid": uuid}) - alarm_action = self.engine.db.get_one("alarms_action", {"uuid": uuid}) + alarm_action = self.engine.db.get_one( + "alarms_action", {"uuid": uuid} + ) alarm.update(alarm_action) - vnf = self.engine.db.get_one("vnfrs", {"nsr-id-ref": alarm["tags"]["ns_id"]}) + vnf = self.engine.db.get_one( + "vnfrs", {"nsr-id-ref": alarm["tags"]["ns_id"]} + ) alarm["vnf-id"] = vnf["_id"] return self._format_out(str(alarm)) except Exception: return self._format_out("Please provide valid alarm uuid") - elif ns_id and ns_id != 'None': + elif ns_id and ns_id != "None": # if request is on basis of ns_id try: - alarms = self.engine.db.get_list("alarms", {"tags.ns_id": ns_id}) + alarms = self.engine.db.get_list( + "alarms", {"tags.ns_id": ns_id} + ) for alarm in alarms: - alarm_action = self.engine.db.get_one("alarms_action", {"uuid": alarm['uuid']}) + alarm_action = self.engine.db.get_one( + "alarms_action", {"uuid": alarm["uuid"]} + ) alarm.update(alarm_action) return self._format_out(str(alarms)) except Exception: return self._format_out("Please provide valid ns id") else: # to return only alarm which are related to given project - project = self.engine.db.get_one("projects", {"name": project_name}) - project_id = project.get('_id') - ns_list = self.engine.db.get_list("nsrs", {"_admin.projects_read": project_id}) + project = self.engine.db.get_one( + "projects", {"name": project_name} + ) + project_id = project.get("_id") + ns_list = self.engine.db.get_list( + "nsrs", {"_admin.projects_read": project_id} + ) ns_ids = [] for ns in ns_list: ns_ids.append(ns.get("_id")) alarms = self.engine.db.get_list("alarms") - alarm_list = [alarm for alarm in alarms if alarm["tags"]["ns_id"] in ns_ids] + alarm_list = [ + alarm + for alarm in alarms + if alarm["tags"]["ns_id"] in ns_ids + ] for alrm in alarm_list: - action = self.engine.db.get_one("alarms_action", {"uuid": alrm.get("uuid")}) + action = self.engine.db.get_one( + "alarms_action", {"uuid": alrm.get("uuid")} + ) alrm.update(action) return self._format_out(str(alarm_list)) # to handle patch request for alarm update - elif cherrypy.request.method == 'PATCH': + elif cherrypy.request.method == "PATCH": data = yaml.load(cherrypy.request.body, Loader=yaml.SafeLoader) try: # check if uuid is valid @@ -940,24 +986,42 @@ class Server(object): return self._format_out("Please provide valid alarm uuid.") if data.get("is_enable") is not None: if data.get("is_enable"): - alarm_status = 'ok' + alarm_status = "ok" else: - alarm_status = 'disabled' - self.engine.db.set_one("alarms", {"uuid": data.get("uuid")}, - {"alarm_status": alarm_status}) + alarm_status = "disabled" + self.engine.db.set_one( + "alarms", + {"uuid": data.get("uuid")}, + {"alarm_status": alarm_status}, + ) else: - self.engine.db.set_one("alarms", {"uuid": data.get("uuid")}, - {"threshold": data.get("threshold")}) + self.engine.db.set_one( + "alarms", + {"uuid": data.get("uuid")}, + {"threshold": data.get("threshold")}, + ) return self._format_out("Alarm updated") except Exception as e: - cherrypy.response.status = e.http_code.value - if isinstance(e, (NbiException, EngineException, DbException, FsException, MsgException, AuthException, - ValidationError, AuthconnException)): + if isinstance( + e, + ( + NbiException, + EngineException, + DbException, + FsException, + MsgException, + AuthException, + ValidationError, + AuthconnException, + ), + ): http_code_value = cherrypy.response.status = e.http_code.value http_code_name = e.http_code.name cherrypy.log("Exception {}".format(e)) else: - http_code_value = cherrypy.response.status = HTTPStatus.BAD_REQUEST.value # INTERNAL_SERVER_ERROR + http_code_value = ( + cherrypy.response.status + ) = HTTPStatus.BAD_REQUEST.value # INTERNAL_SERVER_ERROR cherrypy.log("CRITICAL: Exception {}".format(e), traceback=True) http_code_name = HTTPStatus.BAD_REQUEST.name problem_details = { @@ -998,16 +1062,17 @@ class Server(object): outdata = token_info = self.authenticator.new_token( token_info, indata, cherrypy.request.remote ) - cherrypy.session["Authorization"] = outdata["_id"] + cherrypy.session["Authorization"] = outdata["_id"] # pylint: disable=E1101 self._set_location_header("admin", "v1", "tokens", outdata["_id"]) # for logging self._format_login(token_info) # password expiry check if self.authenticator.check_password_expiry(outdata): - outdata = {"id": outdata["id"], - "message": "change_password", - "user_id": outdata["user_id"] - } + outdata = { + "id": outdata["id"], + "message": "change_password", + "user_id": outdata["user_id"], + } # cherrypy.response.cookie["Authorization"] = outdata["id"] # cherrypy.response.cookie["Authorization"]['expires'] = 3600 elif method == "DELETE": @@ -1020,7 +1085,7 @@ class Server(object): token_id = token_info["_id"] outdata = self.authenticator.del_token(token_id) token_info = None - cherrypy.session["Authorization"] = "logout" + cherrypy.session["Authorization"] = "logout" # pylint: disable=E1101 # cherrypy.response.cookie["Authorization"] = token_id # cherrypy.response.cookie["Authorization"]['expires'] = 0 else: @@ -1048,7 +1113,8 @@ class Server(object): elif args and args[0] == "init": try: # self.engine.load_dbase(cherrypy.request.app.config) - self.engine.create_admin() + pid = self.authenticator.create_admin_project() + self.authenticator.create_admin_user(pid) return "Done. User 'admin', password 'admin' created" except Exception: cherrypy.response.status = HTTPStatus.FORBIDDEN.value @@ -1126,10 +1192,12 @@ class Server(object): + " headers: {}\n".format(cherrypy.request.headers) + " path_info: {}\n".format(cherrypy.request.path_info) + " query_string: {}\n".format(cherrypy.request.query_string) - + " session: {}\n".format(cherrypy.session) + + " session: {}\n".format(cherrypy.session) # pylint: disable=E1101 + " cookie: {}\n".format(cherrypy.request.cookie) + " method: {}\n".format(cherrypy.request.method) - + " session: {}\n".format(cherrypy.session.get("fieldname")) + + " session: {}\n".format( + cherrypy.session.get("fieldname") # pylint: disable=E1101 + ) + " body:\n" ) return_text += " length: {}\n".format(cherrypy.request.body.length) @@ -1318,7 +1386,7 @@ class Server(object): _id=None, item=None, *args, - **kwargs + **kwargs, ): token_info = None outdata = None @@ -1453,7 +1521,9 @@ class Server(object): filter_q = None if "vcaStatusRefresh" in kwargs: filter_q = {"vcaStatusRefresh": kwargs["vcaStatusRefresh"]} - outdata = self.engine.get_item(engine_session, engine_topic, _id, filter_q, True) + outdata = self.engine.get_item( + engine_session, engine_topic, _id, filter_q, True + ) elif method == "POST": cherrypy.response.status = HTTPStatus.CREATED.value @@ -1560,8 +1630,12 @@ class Server(object): elif topic == "vnf_instances" and item: indata["lcmOperationType"] = item indata["vnfInstanceId"] = _id - _id, _ = self.engine.new_item(rollback, engine_session, "vnflcmops", indata, kwargs) - self._set_location_header(main_topic, version, "vnf_lcm_op_occs", _id) + _id, _ = self.engine.new_item( + rollback, engine_session, "vnflcmops", indata, kwargs + ) + self._set_location_header( + main_topic, version, "vnf_lcm_op_occs", _id + ) outdata = {"id": _id} cherrypy.response.status = HTTPStatus.ACCEPTED.value else: @@ -1716,7 +1790,6 @@ class Server(object): self.engine.db.del_list( rollback_item["topic"], rollback_item["filter"], - fail_on_empty=False, ) else: self.engine.db.del_one( @@ -1782,7 +1855,7 @@ def _start_service(): update_dict["server.socket_host"] = v elif k1 in ("server", "test", "auth", "log"): update_dict[k1 + "." + k2] = v - elif k1 in ("message", "database", "storage", "authentication"): + elif k1 in ("message", "database", "storage", "authentication", "temporal"): # k2 = k2.replace('_', '.') if k2 in ("port", "db_port"): engine_config[k1][k2] = int(v) @@ -1792,7 +1865,9 @@ def _start_service(): except ValueError as e: cherrypy.log.error("Ignoring environ '{}': " + str(e)) except Exception as e: - cherrypy.log.warn("skipping environ '{}' on exception '{}'".format(k, e)) + cherrypy.log( + "WARNING: skipping environ '{}' on exception '{}'".format(k, e) + ) if update_dict: cherrypy.config.update(update_dict) @@ -1866,6 +1941,10 @@ def _start_service(): subscription_thread.start() # Do not capture except SubscriptionException + WFTemporal.temporal_api = ( + f'{engine_config["temporal"]["host"]}:{engine_config["temporal"]["port"]}' + ) + backend = engine_config["authentication"]["backend"] cherrypy.log.error( "Starting OSM NBI Version '{} {}' with '{}' authentication backend".format(