Browse Source

fix(hc): Change send_incident_alert_notification to take raw JSON (#54592)

Resolve a TODO comment to remove the use of `Mapping[str, Any]` as a
parameter. The `Any` would be a problem because it can't be cleanly
represented in a JSON schema and won't stop callers from passing
non-serializable values.

Because the incident attachment is treated as an arbitrary JSON blob,
have the RPC method take an arbitrary string containing JSON, which is
loaded on the other side. The string is presumed to contain valid JSON
syntax, and will cause a server-side exception otherwise.
Ryan Skonnord 1 year ago
parent
commit
a2d7081edf

+ 2 - 2
src/sentry/rules/actions/notify_event_service.py

@@ -21,7 +21,7 @@ from sentry.services.hybrid_cloud.app import RpcSentryAppService, app_service
 from sentry.services.hybrid_cloud.integration import integration_service
 from sentry.services.hybrid_cloud.organization.serial import serialize_rpc_organization
 from sentry.tasks.sentry_apps import notify_sentry_app
-from sentry.utils import metrics
+from sentry.utils import json, metrics
 from sentry.utils.safe import safe_execute
 
 logger = logging.getLogger("sentry.integrations.sentry_app")
@@ -72,7 +72,7 @@ def send_incident_alert_notification(
         incident_id=incident.id,
         organization=organization,
         new_status=new_status.value,
-        incident_attachment=incident_attachment,
+        incident_attachment_json=json.dumps(incident_attachment),
         metric_value=metric_value,
     )
 

+ 4 - 4
src/sentry/services/hybrid_cloud/integration/impl.py

@@ -1,7 +1,7 @@
 from __future__ import annotations
 
 import logging
-from typing import TYPE_CHECKING, Any, Dict, Iterable, List, Mapping, Optional, Tuple
+from typing import TYPE_CHECKING, Any, Dict, Iterable, List, Optional, Tuple
 
 from sentry import analytics
 from sentry.api.paginator import OffsetPaginator
@@ -28,7 +28,7 @@ from sentry.services.hybrid_cloud.integration.serial import (
 from sentry.services.hybrid_cloud.organization import RpcOrganizationSummary
 from sentry.services.hybrid_cloud.pagination import RpcPaginationArgs, RpcPaginationResult
 from sentry.shared_integrations.exceptions import ApiError
-from sentry.utils import metrics
+from sentry.utils import json, metrics
 from sentry.utils.sentry_apps import send_and_save_webhook_request
 
 if TYPE_CHECKING:
@@ -345,7 +345,7 @@ class DatabaseBackedIntegrationService(IntegrationService):
         incident_id: int,
         organization: RpcOrganizationSummary,
         new_status: int,
-        incident_attachment: Mapping[str, Any],
+        incident_attachment_json: str,
         metric_value: Optional[str] = None,
     ) -> None:
         sentry_app = SentryApp.objects.get(id=sentry_app_id)
@@ -375,7 +375,7 @@ class DatabaseBackedIntegrationService(IntegrationService):
             resource="metric_alert",
             action=INCIDENT_STATUS[IncidentStatus(new_status)].lower(),
             install=install,
-            data=incident_attachment,
+            data=json.loads(incident_attachment_json),
         )
 
         # Can raise errors if client returns >= 400

+ 2 - 2
src/sentry/services/hybrid_cloud/integration/service.py

@@ -5,7 +5,7 @@
 
 from abc import abstractmethod
 from datetime import datetime
-from typing import Any, Dict, List, Mapping, Optional, Tuple, Union, cast
+from typing import Any, Dict, List, Optional, Tuple, Union, cast
 
 from sentry.models.integrations.organization_integration import (
     OrganizationIntegration,
@@ -261,7 +261,7 @@ class IntegrationService(RpcService):
         incident_id: int,
         organization: RpcOrganizationSummary,
         new_status: int,
-        incident_attachment: Mapping[str, Any],  # TODO: Replace with object schema
+        incident_attachment_json: str,
         metric_value: Optional[str] = None,
     ) -> None:
         pass