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 delete_app(app_id): # Method to keep app in internal system but with unregistered state. # Check for existence app = appstate.get_app_by_id(app_id) if not app: return util.error_response(f"Tried to delete app {app_id} but app not found.", 404) result = appstate.update_app(app_id, {"state": APP_STATE["UNREGISTERED"]}) if result.modified_count > 0: return jsonify(status=200, deleted_id=app_id) return util.error_response(f"Could not delete app {app_id}.", 404)
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 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_microservices(app_id): microservices = appstate.get_app_microservices(app_id) if microservices is not None: response = jsonify(data=microservices) response.status_code = 200 return response return util.error_response("Could not find application microservices.", 404)
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 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_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 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 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 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 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 create_application(): app_json = request.get_json() try: app_name = app_json["name"] except KeyError: return util.error_response("App name not found in application json.", 400) if "type" not in app_json: return util.error_response("App type not found in application json.", 400) app_id = app_name + "-" + str(uuid1()) app_json["app_id"] = app_id app_json["state"] = APP_STATE["REGISTERED"] try: result = appstate.create_app(app_json) response = jsonify(data=app_json) response.status_code = 200 return response except InvalidOperation: return util.error_response(f"Could not create application {app_name}.", 404)
def create_k8s_service(): service_json = request.get_json() # TODO: Pick a better service id name service_id = "service-" + str(uuid1()) service_json["service_id"] = service_id # TODO: Validate the json? try: k8sservicestate.create_service(service_json) response = jsonify(data=service_id) response.status_code = 200 return response except InvalidOperation as e: return util.error_response(f"Could not create service: " + str(e), 500)
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 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 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)