-
-
Notifications
You must be signed in to change notification settings - Fork 4.6k
feat(ACI): Make ProjectRuleDetailsEndpoint PUT method backwards compatible #110381
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
Changes from all commits
0c8846c
d53264f
74179cd
5733fec
e4efdb4
f0d9305
d8d6f23
b51d164
b3e3f66
a71f63d
d46138b
f045e97
6b89d11
a120555
e26a0c3
344a669
48801a0
0a8f963
f95e878
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,5 +1,7 @@ | ||
| from __future__ import annotations | ||
|
|
||
| from typing import cast | ||
|
|
||
| import sentry_sdk | ||
| from django.db import router, transaction | ||
| from drf_spectacular.utils import extend_schema | ||
|
|
@@ -12,7 +14,11 @@ | |
| from sentry.api.api_publish_status import ApiPublishStatus | ||
| from sentry.api.base import region_silo_endpoint | ||
| from sentry.api.bases.rule import WorkflowEngineRuleEndpoint | ||
| from sentry.api.endpoints.project_rules import find_duplicate_rule | ||
| from sentry.api.endpoints.project_rules import ( | ||
| ProjectRulePostData, | ||
| find_duplicate_rule, | ||
| format_request_data, | ||
| ) | ||
| from sentry.api.fields.actor import OwnerActorField | ||
| from sentry.api.serializers import serialize | ||
| from sentry.api.serializers.models.rule import RuleSerializer, WorkflowEngineRuleSerializer | ||
|
|
@@ -39,8 +45,10 @@ | |
| from sentry.sentry_apps.utils.errors import SentryAppBaseError | ||
| from sentry.signals import alert_rule_edited | ||
| from sentry.types.actor import Actor | ||
| from sentry.workflow_engine.endpoints.validators.base.workflow import WorkflowValidator | ||
| from sentry.workflow_engine.models.alertrule_workflow import AlertRuleWorkflow | ||
| from sentry.workflow_engine.models.workflow import Workflow | ||
| from sentry.workflow_engine.models.workflow_data_condition_group import WorkflowDataConditionGroup | ||
| from sentry.workflow_engine.utils.legacy_metric_tracking import ( | ||
| report_used_legacy_models, | ||
| track_alert_endpoint_execution, | ||
|
|
@@ -131,12 +139,13 @@ def get(self, request: Request, project: Project, rule: Rule | Workflow) -> Resp | |
| - Actions - specify what should happen when the trigger conditions are met and the filters match. | ||
| """ | ||
| if isinstance(rule, Workflow): | ||
| workflow = rule | ||
| workflow_engine_rule_serializer = WorkflowEngineRuleSerializer( | ||
| expand=request.GET.getlist("expand", []), | ||
| prepare_component_fields=True, | ||
| project_slug=project.slug, | ||
| ) | ||
| serialized_rule = serialize(rule, request.user, workflow_engine_rule_serializer) | ||
| serialized_rule = serialize(workflow, request.user, workflow_engine_rule_serializer) | ||
| else: | ||
| # Serialize Rule object | ||
| rule_serializer = RuleSerializer( | ||
|
|
@@ -193,13 +202,45 @@ def put(self, request: Request, project: Project, rule: Rule | Workflow) -> Resp | |
| - Actions - specify what should happen when the trigger conditions are met and the filters match. | ||
| """ | ||
| if isinstance(rule, Workflow): | ||
| return Response( | ||
| { | ||
| "rule": [ | ||
| "Passing a workflow through this endpoint is not yet supported", | ||
| ] | ||
| workflow = rule | ||
| organization = project.organization | ||
|
|
||
| data = request.data.copy() | ||
|
|
||
| if not data.get("filterMatch"): | ||
| # if filterMatch is not passed, don't overwrite it with default value, use the saved dcg type | ||
| wdcg = WorkflowDataConditionGroup.objects.filter(workflow=workflow).first() | ||
| if wdcg: | ||
| data["filterMatch"] = wdcg.condition_group.logic_type | ||
|
|
||
| request_data = format_request_data(cast(ProjectRulePostData, data)) | ||
| if not request_data.get("config", {}).get("frequency"): | ||
| request_data["config"] = workflow.config | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Falsy frequency check silently ignores invalid valuesLow Severity The check |
||
|
|
||
| validator = WorkflowValidator( | ||
| data=request_data, | ||
| context={ | ||
| "organization": organization, | ||
| "request": request, | ||
| "workflow": workflow, | ||
| }, | ||
| status=status.HTTP_400_BAD_REQUEST, | ||
| ) | ||
| validator.is_valid(raise_exception=True) | ||
|
|
||
| with transaction.atomic(router.db_for_write(Workflow)): | ||
| validator.update(workflow, validator.validated_data) | ||
| self.create_audit_entry( | ||
| request=request, | ||
| organization=organization, | ||
| target_object=workflow.id, | ||
| event=audit_log.get_event_id("WORKFLOW_EDIT"), | ||
| data=workflow.get_audit_log_data(), | ||
| ) | ||
|
|
||
| workflow.refresh_from_db() | ||
| return Response( | ||
| serialize(workflow, request.user, WorkflowEngineRuleSerializer()), | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. PUT response serializer missing
|
||
| status=200, | ||
cursor[bot] marked this conversation as resolved.
Show resolved
Hide resolved
|
||
| ) | ||
sentry[bot] marked this conversation as resolved.
Show resolved
Hide resolved
Comment on lines
+241
to
244
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Bug: Updating a workflow rule with an empty Suggested FixAdd a check in the Prompt for AI Agent |
||
|
|
||
| rule_data_before = dict(rule.data) | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -635,12 +635,27 @@ def get_attrs(self, item_list: Sequence[Workflow], user, **kwargs): | |
| if action.data.get("notes") == "": | ||
| action_data.pop("notes", None) | ||
|
|
||
| # XXX: workspace needs to be returned as a string | ||
| if action_data.get("workspace"): | ||
| action_data["workspace"] = str(action_data["workspace"]) | ||
|
|
||
| serialized_actions.append(action_data) | ||
|
|
||
| # Generate conditions and filters | ||
| conditions, filters = self._generate_rule_conditions_filters( | ||
| workflow, result[workflow]["projects"][0], workflow_dcg | ||
| ) | ||
| for f in filters: | ||
| # IssueCategoryFilter stores numeric string choices and must stay as str | ||
| if ( | ||
| f.get("value") | ||
| and f.get("id") != "sentry.rules.filters.issue_category.IssueCategoryFilter" | ||
|
Member
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This is sort of hacky but outside of changing the value type of one of these it's the only way for the tests to pass and the serializers to be in sync. |
||
| ): | ||
| try: | ||
| f["value"] = int(f["value"]) | ||
| except (ValueError, TypeError): | ||
| continue | ||
cursor[bot] marked this conversation as resolved.
Show resolved
Hide resolved
sentry[bot] marked this conversation as resolved.
Show resolved
Hide resolved
cursor[bot] marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
|
||
| result[workflow]["conditions"] = conditions | ||
| result[workflow]["filters"] = filters | ||
|
|
||
|
|
||


Uh oh!
There was an error while loading. Please reload this page.