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)
Beispiel #3
0
    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)
Beispiel #5
0
    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)
Beispiel #6
0
    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)
Beispiel #7
0
    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)
Beispiel #8
0
    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)