Skip to content

Commit

Permalink
feat(ACI): Delete endpoint for a detector
Browse files Browse the repository at this point in the history
  • Loading branch information
ceorourke committed Jan 29, 2025
1 parent 0745e6a commit 8920d82
Show file tree
Hide file tree
Showing 3 changed files with 105 additions and 7 deletions.
60 changes: 58 additions & 2 deletions src/sentry/workflow_engine/endpoints/project_detector_details.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,12 +11,20 @@
from sentry.apidocs.constants import (
RESPONSE_BAD_REQUEST,
RESPONSE_FORBIDDEN,
RESPONSE_NO_CONTENT,
RESPONSE_NOT_FOUND,
RESPONSE_UNAUTHORIZED,
)
from sentry.apidocs.parameters import DetectorParams, GlobalParams
from sentry.deletions.models.scheduleddeletion import RegionScheduledDeletion
from sentry.models.project import Project
from sentry.workflow_engine.endpoints.serializers import DetectorSerializer
from sentry.workflow_engine.models import Detector
from sentry.workflow_engine.models import (
DataConditionGroup,
DataSource,
DataSourceDetector,
Detector,
)


@region_silo_endpoint
Expand Down Expand Up @@ -57,7 +65,7 @@ def convert_args(self, request: Request, detector_id, *args, **kwargs):
404: RESPONSE_NOT_FOUND,
},
)
def get(self, request: Request, project, detector):
def get(self, request: Request, project: Project, detector: Detector):
"""
Fetch a detector
`````````````````````````
Expand All @@ -69,3 +77,51 @@ def get(self, request: Request, project, detector):
DetectorSerializer(),
)
return Response(serialized_detector)

@extend_schema(
operation_id="Delete a Detector",
parameters=[
GlobalParams.ORG_ID_OR_SLUG,
GlobalParams.PROJECT_ID_OR_SLUG,
DetectorParams.DETECTOR_ID,
],
responses={
204: RESPONSE_NO_CONTENT,
403: RESPONSE_FORBIDDEN,
404: RESPONSE_NOT_FOUND,
},
)
def delete(self, request: Request, project: Project, detector: Detector):
"""
Delete a detector
"""
try:
data_condition_group = DataConditionGroup.objects.get(
id=detector.workflow_condition_group.id
)
except DataConditionGroup.DoesNotExist:
pass

if data_condition_group:
RegionScheduledDeletion.schedule(data_condition_group, days=0, actor=request.user)

try:
data_source_detector = DataSourceDetector.objects.get(detector_id=detector.id)
except DataSourceDetector.DoesNotExist:
pass

if data_source_detector:
RegionScheduledDeletion.schedule(data_source_detector, days=0, actor=request.user)

try:
data_sources = DataSource.objects.filter(detector=detector.id)
except DataSource.DoesNotExist:
pass

if data_sources:
for data_source in data_sources:
RegionScheduledDeletion.schedule(data_source, days=0, actor=request.user)

RegionScheduledDeletion.schedule(detector, days=0, actor=request.user)
# TODO add audit log entry
return Response(status=204)
1 change: 0 additions & 1 deletion src/sentry/workflow_engine/endpoints/urls.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@
# - GET /detector w/ filters
# - GET /detector/:id
# - PUT /detector/:id
# - DELETE /detector/:id

# Remaining Workflows Endpoints
# - GET /workflow w/ filters
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,10 @@
from sentry.api.serializers import serialize
from sentry.deletions.models.scheduleddeletion import RegionScheduledDeletion
from sentry.incidents.grouptype import MetricAlertFire
from sentry.testutils.cases import APITestCase
from sentry.testutils.outbox import outbox_runner
from sentry.testutils.silo import region_silo_test
from sentry.workflow_engine.models import DataConditionGroup, DataSource, DataSourceDetector


class ProjectDetectorDetailsBaseTest(APITestCase):
Expand All @@ -10,16 +13,56 @@ class ProjectDetectorDetailsBaseTest(APITestCase):
def setUp(self):
super().setUp()
self.login_as(user=self.user)
self.data_condition_group = self.create_data_condition_group()
self.detector = self.create_detector(
project_id=self.project.id,
name="Test Detector",
type=MetricAlertFire.slug,
workflow_condition_group=self.data_condition_group,
)
data_source = DataSource.objects.filter(
id__in=[data_source.id for data_source in self.detector.data_sources.all()]
).first()
self.create_data_source_detector(data_source=data_source, detector=self.detector)


@region_silo_test
class ProjectDetectorIndexGetTest(ProjectDetectorDetailsBaseTest):
def test_simple(self):
detector = self.create_detector(
project_id=self.project.id, name="Test Detector", type=MetricAlertFire.slug
response = self.get_success_response(
self.organization.slug, self.project.slug, self.detector.id
)
response = self.get_success_response(self.organization.slug, self.project.slug, detector.id)
assert response.data == serialize(detector)
assert response.data == serialize(self.detector)

def test_does_not_exist(self):
self.get_error_response(self.organization.slug, self.project.slug, 3, status_code=404)


@region_silo_test
class ProjectDetectorIndexDeleteTest(ProjectDetectorDetailsBaseTest):
method = "DELETE"

def test_simple(self):
detector_id = self.detector.id
data_condition_group = DataConditionGroup.objects.get(
id=self.detector.workflow_condition_group.id
)
data_source_detector = DataSourceDetector.objects.get(detector_id=detector_id)
data_source = DataSource.objects.get(detector=detector_id)

with outbox_runner():
self.get_success_response(self.organization.slug, self.project.slug, self.detector.id)

self.detector.refresh_from_db()
assert RegionScheduledDeletion.objects.filter(
model_name="Detector", object_id=detector_id
).exists()
assert RegionScheduledDeletion.objects.filter(
model_name="DataConditionGroup", object_id=data_condition_group.id
).exists()
assert RegionScheduledDeletion.objects.filter(
model_name="DataSourceDetector", object_id=data_source_detector.id
).exists()
assert RegionScheduledDeletion.objects.filter(
model_name="DataSource", object_id=data_source.id
).exists()

0 comments on commit 8920d82

Please sign in to comment.