def put(self, request, project, alert_rule): data = request.data serializer = DrfAlertRuleSerializer( context={ "organization": project.organization, "access": request.access, "user": request.user, }, instance=alert_rule, data=data, partial=True, ) if serializer.is_valid(): try: alert_rule = serializer.save() except ChannelLookupTimeoutError: # need to kick off an async job for Slack client = tasks.RedisRuleStatus() task_args = { "organization_id": project.organization_id, "uuid": client.uuid, "data": data, "alert_rule_id": alert_rule.id, } tasks.find_channel_id_for_alert_rule.apply_async( kwargs=task_args) return Response({"uuid": client.uuid}, status=202) else: return Response(serialize(alert_rule, request.user), status=status.HTTP_200_OK) return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
def get(self, request, project, task_uuid): """ Retrieve the status of the async task Return details of the rule if the task is successful """ client = tasks.RedisRuleStatus(task_uuid) result = client.get_value() status = result["status"] rule_id = result.get("rule_id") error = result.get("error") # if the status is "pending" we don't have a rule yet or error context = {"status": status, "rule": None, "error": None} if rule_id and status == "success": try: rule = Rule.objects.get( project=project, id=int(rule_id), status__in=[RuleStatus.ACTIVE, RuleStatus.INACTIVE], ) context["rule"] = serialize(rule, request.user) except Rule.DoesNotExist: raise Http404 if status == "failed": context["error"] = error return Response(context, status=200)
def get(self, request, project, task_uuid): """ Retrieve the status of the async task Return details of the alert rule if the task is successful """ client = tasks.RedisRuleStatus(task_uuid) result = client.get_value() status = result["status"] rule_id = result.get("rule_id") error = result.get("error") # if the status is "pending" we don't have a rule yet or error context = {"status": status, "alertRule": None, "error": None} if rule_id and status == "success": try: alert_rule = AlertRule.objects.get( snuba_query__subscriptions__project=project, id=rule_id) context["alertRule"] = serialize(alert_rule, request.user) except AlertRule.DoesNotExist: raise Http404 if status == "failed": context["error"] = error return Response(context, status=200)
def put(self, request, project, rule_id): """ Update a rule Update various attributes for the given rule. {method} {path} {{ "name": "My rule name", "conditions": [], "actions": [], "actionMatch": "all" }} """ rule = Rule.objects.get(project=project, id=rule_id) serializer = RuleSerializer(context={"project": project}, data=request.data, partial=True) if serializer.is_valid(): data = serializer.validated_data kwargs = { "name": data["name"], "environment": data.get("environment"), "project": project, "action_match": data["actionMatch"], "conditions": data["conditions"], "actions": data["actions"], "frequency": data.get("frequency"), } if data.get("pending_save"): client = tasks.RedisRuleStatus() kwargs.update({"uuid": client.uuid, "rule_id": rule.id}) tasks.find_channel_id_for_rule.apply_async(kwargs=kwargs) context = {"uuid": client.uuid} return Response(context, status=202) updated_rule = project_rules.Updater.run(rule=rule, request=request, **kwargs) RuleActivity.objects.create(rule=updated_rule, user=request.user, type=RuleActivityType.UPDATED.value) self.create_audit_entry( request=request, organization=project.organization, target_object=updated_rule.id, event=AuditLogEntryEvent.RULE_EDIT, data=updated_rule.get_audit_log_data(), ) return Response(serialize(updated_rule, request.user)) return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
def post(self, request, project): """ Create a rule Create a new rule for the given project. {method} {path} {{ "name": "My rule name", "conditions": [], "actions": [], "actionMatch": "all" }} """ serializer = RuleSerializer(context={"project": project}, data=request.data) if serializer.is_valid(): data = serializer.validated_data kwargs = { "name": data["name"], "environment": data.get("environment"), "project": project, "action_match": data["actionMatch"], "conditions": data["conditions"], "actions": data["actions"], "frequency": data.get("frequency"), } if data.get("pending_save"): client = tasks.RedisRuleStatus() uuid_context = {"uuid": client.uuid} kwargs.update(uuid_context) tasks.find_channel_id_for_rule.apply_async(kwargs=kwargs) return Response(uuid_context, status=202) rule = project_rules.Creator.run(request=request, **kwargs) RuleActivity.objects.create(rule=rule, user=request.user, type=RuleActivityType.CREATED.value) self.create_audit_entry( request=request, organization=project.organization, target_object=rule.id, event=AuditLogEntryEvent.RULE_ADD, data=rule.get_audit_log_data(), ) alert_rule_created.send_robust(user=request.user, project=project, rule=rule, rule_type="issue", sender=self) return Response(serialize(rule, request.user)) return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
def post(self, request, project): """ Create an alert rule """ if not features.has("organizations:incidents", project.organization, actor=request.user): raise ResourceDoesNotExist data = deepcopy(request.data) data["projects"] = [project.slug] serializer = AlertRuleSerializer( context={ "organization": project.organization, "access": request.access, "user": request.user, }, data=data, ) if serializer.is_valid(): try: alert_rule = serializer.save() except ChannelLookupTimeoutError: # need to kick off an async job for Slack client = tasks.RedisRuleStatus() task_args = { "organization_id": project.organization_id, "uuid": client.uuid, "data": data, "user_id": request.user.id, } tasks.find_channel_id_for_alert_rule.apply_async( kwargs=task_args) return Response({"uuid": client.uuid}, status=202) else: referrer = request.query_params.get("referrer") session_id = request.query_params.get("sessionId") alert_rule_created.send_robust( user=request.user, project=project, rule=alert_rule, rule_type="metric", sender=self, referrer=referrer, session_id=session_id, is_api_token=request.auth is not None, ) return Response(serialize(alert_rule, request.user), status=status.HTTP_201_CREATED) return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
def post(self, request: Request, project) -> Response: """ Create a rule Create a new rule for the given project. {method} {path} {{ "name": "My rule name", "owner": "type:id", "conditions": [], "filters": [], "actions": [], "actionMatch": "all", "filterMatch": "all" }} """ serializer = RuleSerializer(context={ "project": project, "organization": project.organization }, data=request.data) if serializer.is_valid(): data = serializer.validated_data # combine filters and conditions into one conditions criteria for the rule object conditions = data.get("conditions", []) if "filters" in data: conditions.extend(data["filters"]) kwargs = { "name": data["name"], "environment": data.get("environment"), "project": project, "action_match": data["actionMatch"], "filter_match": data.get("filterMatch"), "conditions": conditions, "actions": data.get("actions", []), "frequency": data.get("frequency"), "user_id": request.user.id, } owner = data.get("owner") if owner: try: kwargs["owner"] = owner.resolve_to_actor().id except (User.DoesNotExist, Team.DoesNotExist): return Response( "Could not resolve owner", status=status.HTTP_400_BAD_REQUEST, ) if data.get("pending_save"): client = tasks.RedisRuleStatus() uuid_context = {"uuid": client.uuid} kwargs.update(uuid_context) tasks.find_channel_id_for_rule.apply_async(kwargs=kwargs) return Response(uuid_context, status=202) created_alert_rule_ui_component = trigger_alert_rule_action_creators( kwargs.get("actions")) rule = project_rules.Creator.run(request=request, **kwargs) RuleActivity.objects.create(rule=rule, user=request.user, type=RuleActivityType.CREATED.value) self.create_audit_entry( request=request, organization=project.organization, target_object=rule.id, event=AuditLogEntryEvent.RULE_ADD, data=rule.get_audit_log_data(), ) alert_rule_created.send_robust( user=request.user, project=project, rule=rule, rule_type="issue", sender=self, is_api_token=request.auth is not None, alert_rule_ui_component=created_alert_rule_ui_component, ) return Response(serialize(rule, request.user)) return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
def put(self, request: Request, project, rule) -> Response: """ Update a rule Update various attributes for the given rule. {method} {path} {{ "name": "My rule name", "conditions": [], "filters": [], "actions": [], "actionMatch": "all", "filterMatch": "all" }} """ serializer = RuleSerializer( context={"project": project, "organization": project.organization}, data=request.data, partial=True, ) if serializer.is_valid(): data = serializer.validated_data # combine filters and conditions into one conditions criteria for the rule object conditions = data.get("conditions", []) if "filters" in data: conditions.extend(data["filters"]) kwargs = { "name": data["name"], "environment": data.get("environment"), "project": project, "action_match": data["actionMatch"], "filter_match": data.get("filterMatch"), "conditions": conditions, "actions": data["actions"], "frequency": data.get("frequency"), } owner = data.get("owner") if owner: try: kwargs["owner"] = owner.resolve_to_actor().id except (User.DoesNotExist, Team.DoesNotExist): return Response( "Could not resolve owner", status=status.HTTP_400_BAD_REQUEST, ) if data.get("pending_save"): client = tasks.RedisRuleStatus() kwargs.update({"uuid": client.uuid, "rule_id": rule.id}) tasks.find_channel_id_for_rule.apply_async(kwargs=kwargs) context = {"uuid": client.uuid} return Response(context, status=202) trigger_alert_rule_action_creators(kwargs.get("actions")) updated_rule = project_rules.Updater.run(rule=rule, request=request, **kwargs) RuleActivity.objects.create( rule=updated_rule, user=request.user, type=RuleActivityType.UPDATED.value ) self.create_audit_entry( request=request, organization=project.organization, target_object=updated_rule.id, event=AuditLogEntryEvent.RULE_EDIT, data=updated_rule.get_audit_log_data(), ) return Response(serialize(updated_rule, request.user)) return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)