def get_app_all_features(app_id): application = appstate.get_app_by_id(app_id) if application is None: return util.ensure_document_found(None) if "management_features" not in application: return util.error_response(f"management_features are not found", 400) return util.ensure_document_found(application['management_features'])
def get_app_incidents(app_id): incidents = resultstate.get_last_app_incident(app_id) for doc in incidents: return util.ensure_document_found(doc) return util.ensure_document_found(None)
def get_app_slo(app_id): application = appstate.get_app_by_id(app_id) if application is None: return util.ensure_document_found(None) if "slo" not in application: return util.error_response(f"SLO is not found", 400) return util.ensure_document_found(application['slo'])
def interference_scores(app_id, service_name): application = appstate.get_app_by_id(app_id) if application is None: return util.ensure_document_found(None) cursor = metricdb[profiling_collection].find( {"appName": application["name"], "serviceInTest": service_name} ).sort("_id", DESCENDING).limit(1) try: profiling = next(cursor) data = util.get_radar_dataframe(profiling) del profiling["testResult"] return jsonify(data) except StopIteration: return util.ensure_document_found(None)
def update_app_state(app_id): app = appstate.get_app_by_id(app_id) if app is None: return util.ensure_document_found(None) state_json = request.get_json() state = state_json["state"] if state != APP_STATE["REGISTERED"] and state != APP_STATE["UNREGISTERED"] and state != APP_STATE["ACTIVE"]: return util.error_response(f"{state} is not valid state", 400) previous_state = app["state"] app["state"] = state updated_doc = appstate.update_and_get_app(app_id, app) if not updated_doc: return util.error_response(f"Could not update app {app_id}.", 404) # NOTE: Currently the UI is only calling this generic update API to update SLO and k8s objects. # Therefore we have to intercept here to start the diagnosis flow, since we need app SLO # to start it. # TODO: We should only try to start the diagnosis flow once, and also it's not gurantee we # have all the information we need already.... if "slo" in updated_doc: if updated_doc["state"] == APP_STATE["ACTIVE"]: Analyzer().diagnosis.run_new_app(app_id, updated_doc) elif previous_state == APP_STATE["ACTIVE"] and updated_doc["state"] != APP_STATE["ACTIVE"]: Analyzer().diagnosis.stop_app(app_id) result = jsonify(data=updated_doc) result.status_code = 200 return result
def update_app_features(app_id, feature_name): application = appstate.get_app_by_id(app_id) if application is None: return util.ensure_document_found(None) if feature_name != FEATURE_NAME["INTERFERENCE"] and feature_name != FEATURE_NAME["BOTTLENECK"] and feature_name != \ FEATURE_NAME["EFFICIENCY"]: return util.error_response(f"{feature_name} is not valid feature name", 400) if "management_features" not in application: return util.error_response(f"management features do not exist in application {app_id}", 400) new_feature = request.get_json() if "name" not in new_feature: return util.error_response(f"name field is not exist in update feature", 400) new_feature_name = new_feature["name"] if new_feature_name != feature_name: return util.error_response(f"Input json does not have the correct feature name", 400) for idx, feature in enumerate(application['management_features']): if feature["name"] == feature_name: break else: idx = -1 if idx == -1: application['management_features'].append(new_feature) else: application['management_features'][idx] = new_feature return util.update_and_return_doc(app_id, application)
def service_profiling(app_id, service_name): application = appstate.get_app_by_id(app_id) if app is None: return util.ensure_document_found(None) cursor = metricdb[profiling_collection].find( {"appName": application["name"], "serviceInTest": service_name}, {"appName": 0, "_id": 0}, ).sort("_id", DESCENDING).limit(1) try: profiling = next(cursor) data = util.get_profiling_dataframe(profiling) del profiling["testResult"] profiling["results"] = data return jsonify(profiling) except StopIteration: return util.ensure_document_found(None)
def app_calibration(app_id): application = appstate.get_app_by_id(app_id) if app is None: return util.ensure_document_found(None) cursor = metricdb[calibration_collection].find( {"appName": application["name"]}, {"appName": 0, "_id": 0}, ).sort("_id", DESCENDING).limit(1) try: calibration = next(cursor) data = util.get_calibration_dataframe(calibration) del calibration["testResult"] calibration["results"] = data return jsonify(calibration) except StopIteration: return util.ensure_document_found(None)
def add_app_slo(app_id): application = appstate.get_app_by_id(app_id) if application is None: return util.ensure_document_found(None) if "slo" in application: return util.error_response(f"SLO already set", 400) slo = request.get_json() return util.update_and_return_doc(app_id, {"slo": slo})
def update_app_slo(app_id): application = appstate.get_app_by_id(app_id) if application is None: return util.ensure_document_found(None) if "slo" not in application: return util.error_response(f"SLO is not added in application: {app_id}", 400) application['slo'] = request.get_json() return util.update_and_return_doc(app_id, application)
def add_app_features(app_id): application = appstate.get_app_by_id(app_id) if application is None: return util.ensure_document_found(None) if "management_features" in application: return util.error_response(f"management features already exist in application {app_id}", 400) features = request.get_json() return util.update_and_return_doc(app_id, {"management_features": features})
def get_app_one_feature(app_id, feature_name): application = appstate.get_app_by_id(app_id) if application is None: return util.ensure_document_found(None) if feature_name != FEATURE_NAME["INTERFERENCE"] and feature_name != FEATURE_NAME["BOTTLENECK"] and feature_name != \ FEATURE_NAME["EFFICIENCY"]: return util.error_response(f"{feature_name} is not valid feature name", 400) if "management_features" not in application: return util.error_response(f"management_features is not exist", 400) for idx, feature in enumerate(application['management_features']): if feature["name"] == feature_name: break else: idx = -1 if idx == -1: return util.error_response(f'{feature_name} is not found', 400) else: return util.ensure_document_found(feature)
def get_app_diagnosis(app_id): request_json = request.get_json() query_type = check_diagnosis_input(request_json) if query_type == 0: # query by name diagnosis = resultstate.get_last_app_diagnosis(app_Id) if diagnosis.count() == 0: return util.ensure_document_found(None) elif query_type == 1: # query by name & incident_id diagnosis = resultstate.get_incident_diagnosis(app_id, request_json["incident_id"]) elif query_type == 2: # query by name & interval start_ts = request_json["start_time"] end_ts = request_json["end_time"] if end_ts < start_ts: return util.error_response(f"end_time is before the start_time", 400) diagnosis = resultstate.get_diagnosis_between_time(app_id, start_ts, end_ts) return util.ensure_document_found(diagnosis)
def add_opportunities(): opportunity_json = request.get_json() if opportunity_json is None: return util.error_response(f"opportunities data is no available", 400) if "id" not in opportunity_json: return util.error_response(f"opportunity id is not found", 400) opportunities = resultdb[opportunities_collection].find_one( {"id": opportunity_json["id"]}, {"_id": 0} ) opportunity_id = opportunity_json["id"] if opportunities is not None: return util.error_response(f"opportunity with id {opportunity_id} already exist", 400) try: resultdb[opportunities_collection].insert_one(opportunity_json) return util.ensure_document_found({"opportunity_id": opportunity_id}) except InvalidOperation: return util.error_response(f"Could not create opportunity {opportunity_id}.", 400) return util.ensure_document_found(None)
def get_pod_names(app_id): app = appstate.get_app_by_id(app_id) if app is None: return util.ensure_document_found(None) pod_names = [] for microservice in app["microservices"]: service_id = microservice["service_id"] microservice_doc = k8sservicestate.get_service(service_id) if microservice_doc is None: return util.error_response("Microservice with id %s not found" % service_id, 400) pod_names += microservice_doc["pods"] return jsonify(pod_names)
def get_problems_interval(): req = request.get_json() if req is None or ("start_time" not in req or "end_time" not in req): end_ts = round(time.time()) * 1000000000 start_ts = end_ts - 5 * 60 * 1000000000 else: start_ts = req["start_time"] end_ts = req["end_time"] if end_ts < start_ts: return util.error_response(f"end_time is before start_time", 400) problems = resultstate.get_problems_between_time(start_ts, end_ts) return util.ensure_document_found(problems)
def add_problem(): problem_json = request.get_json() if problem_json is None: return util.error_response(f"No body found in request", 400) if "problem_id" not in problem_json: return util.error_response(f"problem id is not found", 400) problem_id = problem_json["problem_id"] problem = resultstate.get_problem(problem_id) if problem is not None: return util.error_response(f"problem with id {problem_id} already exist", 400) try: resultstate.create_problem(problem_json) except InvalidOperation: return util.error_response(f"Could not create problem {problem_id}.", 400) return util.ensure_document_found({"problem_id": problem_id})
def get_opportunities(): req = request.get_json() if req is None or ("start_time" not in req or "end_time" not in req): end_ts = round(time.time()) * 1000000000 start_ts = end_ts - 5 * 60 * 1000000000 else: start_ts = req["start_time"] end_ts = req["end_time"] if end_ts < start_ts: return util.error_response(f"end_time is before the start_time", 400) opportunities = resultdb[opportunities_collection]. \ find({"$and": [{"timestamp": {"$gte": start_ts}}, {"timestamp": {"$lte": end_ts}}]}, {"_id": 0} ) return util.ensure_document_found(opportunities)
def add_risks(): req = request.get_json() if req is None: return util.error_response(f"risk data is no available", 400) if "id" not in req: return util.error_response(f"risk id is not found", 400) risks = resultdb[risks_collection].find_one( {"id": req["id"]}, {"_id": 0} ) risk_id = req["id"] if risks is not None: return util.error_response(f"risk with id {risk_id} already exist", 400) try: resultdb[risks_collection].insert_one(req) return util.ensure_document_found({"risk_id": risk_id}) except InvalidOperation: return util.error_response(f"Could not create risk {risk_id}.", 400)
def add_diagnosis(app_id): diagnosis_json = request.get_json() if diagnoses_json is None: return util.error_response(f"No body found in request", 400) if "incident_id" not in diagnosis_json: return util.error_response(f"incident id is not found", 400) incident_id = diagnosis_json["incident_id"] diagnosis = resultstate.get_incident_diagnosis(app_id, incident_id) if diagnosis is not None: return util.error_response(f"diagnosis of app ({app_id}) with incident ({incident_id}) already exist", 400) try: resultstate.create_diagnosis(diagnosis_json) except InvalidOperation: return util.error_response( f"Could not create diagnosis of app id ({app_id}) with incident ({incident_id}) already exist", 400) return util.ensure_document_found({"app_id": app_id, "incident_id": incident_id})
def get_app_info_by_id(app_id): application = appstate.get_app_by_id(app_id) return util.ensure_document_found(application)
def get_k8s_service(service_id): service = k8sservicestate.get_service(service_id) service.pop("_id") return util.ensure_document_found(service)
def get_app_state(app_id): app = appstate.get_app_by_id(app_id) if app is None: return util.ensure_document_found(None) return util.ensure_document_found({"state": app["state"]})
def get_app_info(app_name): application = appstate.get_app_by_name(app_name) return util.ensure_document_found(application)
def get_problems(problem_id): problem = resultstate.get_problem(problem_id) return util.ensure_document_found(problem)