+ return self._format_out(problem_details, None)
+
+ @staticmethod
+ def _format_login(token_info):
+ """
+ Changes cherrypy.request.login to include username/project_name;session so that cherrypy access log will
+ log this information
+ :param token_info: Dictionary with token content
+ :return: None
+ """
+ cherrypy.request.login = token_info.get("username", "-")
+ if token_info.get("project_name"):
+ cherrypy.request.login += "/" + token_info["project_name"]
+ if token_info.get("id"):
+ cherrypy.request.login += ";session=" + token_info["id"][0:12]
+
+ # 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":
+ 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
+ )
+
+ self.authenticator.authorize(
+ role_permission, query_string_operations, None
+ )
+
+ # to handle get request
+ if cherrypy.request.method == "GET":
+ # if request is on basis of uuid
+ 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.update(alarm_action)
+ 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":
+ # if request is on basis of ns_id
+ try:
+ 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.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}
+ )
+ 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
+ ]
+ for alrm in alarm_list:
+ 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":
+ data = yaml.safe_load(cherrypy.request.body)
+ try:
+ # check if uuid is valid
+ self.engine.db.get_one("alarms", {"uuid": data.get("uuid")})
+ except Exception:
+ 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"
+ else:
+ 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")},
+ )
+ return self._format_out("Alarm updated")
+ except Exception as e:
+ 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
+ cherrypy.log("CRITICAL: Exception {}".format(e), traceback=True)
+ http_code_name = HTTPStatus.BAD_REQUEST.name
+ problem_details = {
+ "code": http_code_name,
+ "status": http_code_value,
+ "detail": str(e),
+ }
+ return self._format_out(problem_details)
+
+ @cherrypy.expose
+ def token(self, method, token_id=None, kwargs=None):
+ token_info = None
+ # self.engine.load_dbase(cherrypy.request.app.config)
+ indata = self._format_in(kwargs)
+ if not isinstance(indata, dict):
+ raise NbiException(
+ "Expected application/yaml or application/json Content-Type",
+ HTTPStatus.BAD_REQUEST,
+ )
+
+ if method == "GET":
+ token_info = self.authenticator.authorize()
+ # for logging
+ self._format_login(token_info)
+ if token_id:
+ outdata = self.authenticator.get_token(token_info, token_id)
+ else:
+ outdata = self.authenticator.get_token_list(token_info)
+ elif method == "POST":
+ try:
+ token_info = self.authenticator.authorize()
+ except Exception:
+ token_info = None
+ if kwargs:
+ indata.update(kwargs)
+ # This is needed to log the user when authentication fails
+ cherrypy.request.login = "{}".format(indata.get("username", "-"))
+ outdata = token_info = self.authenticator.new_token(
+ token_info, indata, cherrypy.request.remote
+ )
+ 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"],
+ }
+ # 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"]
+ elif not token_id:
+ token_info = self.authenticator.authorize()
+ # 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:
+ raise NbiException(
+ "Method {} not allowed for token".format(method),
+ HTTPStatus.METHOD_NOT_ALLOWED,
+ )
+ return self._format_out(outdata, token_info)