diff --git a/CHANGELOG.md b/CHANGELOG.md index 0999423e..75e81488 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,12 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## Unreleased + +### Fixed + +- Fix AmazonSNS integration to handle exceptions the same as other integrations @mderynck ([#3315](https://github.com/grafana/oncall/pull/3315)) + ## v1.3.56 (2023-11-10) ## v1.3.55 (2023-11-07) diff --git a/engine/apps/integrations/views.py b/engine/apps/integrations/views.py index 359b692b..61e51bea 100644 --- a/engine/apps/integrations/views.py +++ b/engine/apps/integrations/views.py @@ -21,6 +21,7 @@ from apps.integrations.mixins import ( is_ratelimit_ignored, ) from apps.integrations.tasks import create_alert, create_alertmanager_alerts +from apps.user_management.exceptions import OrganizationDeletedException, OrganizationMovedException from common.api_helpers.utils import create_engine_url logger = logging.getLogger(__name__) @@ -31,8 +32,10 @@ class AmazonSNS(BrowsableInstructionMixin, AlertChannelDefiningMixin, Integratio def dispatch(self, *args, **kwargs): try: return super().dispatch(*args, **kwargs) + except (OrganizationMovedException, OrganizationDeletedException, PermissionDenied) as oe: + raise oe except Exception as e: - print(e) + logger.error(f"AmazonSNS - Bad Request (400) {str(e)}") return JsonResponse(status=400, data={}) def handle_message(self, message, payload): diff --git a/engine/apps/user_management/tests/test_region.py b/engine/apps/user_management/tests/test_region.py index 414396d1..6331327c 100644 --- a/engine/apps/user_management/tests/test_region.py +++ b/engine/apps/user_management/tests/test_region.py @@ -9,7 +9,7 @@ from rest_framework.test import APIClient from apps.alerts.models import AlertReceiveChannel from apps.auth_token.auth import ApiTokenAuthentication, ScheduleExportAuthentication, UserScheduleExportAuthentication from apps.auth_token.models import ScheduleExportAuthToken, UserScheduleExportAuthToken -from apps.integrations.views import AlertManagerAPIView +from apps.integrations.views import AlertManagerAPIView, AmazonSNS from apps.schedules.models import OnCallScheduleWeb from apps.user_management.exceptions import OrganizationMovedException @@ -30,19 +30,27 @@ def test_organization_region_delete( @pytest.mark.django_db +@pytest.mark.parametrize( + "integration_type,integration_view", + [ + (AlertReceiveChannel.INTEGRATION_ALERTMANAGER, AlertManagerAPIView()), + ("amazon_sns", AmazonSNS()), + ], +) def test_integration_does_not_raise_exception_organization_moved( make_organization, make_alert_receive_channel, + integration_type, + integration_view, ): organization = make_organization() alert_receive_channel = make_alert_receive_channel( organization=organization, - integration=AlertReceiveChannel.INTEGRATION_ALERTMANAGER, + integration=integration_type, ) try: - am = AlertManagerAPIView() - am.dispatch(alert_channel_key=alert_receive_channel.token) + integration_view.dispatch(alert_channel_key=alert_receive_channel.token) assert False except OrganizationMovedException: assert False @@ -51,21 +59,29 @@ def test_integration_does_not_raise_exception_organization_moved( @pytest.mark.django_db +@pytest.mark.parametrize( + "integration_type,integration_view", + [ + (AlertReceiveChannel.INTEGRATION_ALERTMANAGER, AlertManagerAPIView()), + ("amazon_sns", AmazonSNS()), + ], +) def test_integration_raises_exception_organization_moved( make_organization_and_region, make_alert_receive_channel, + integration_type, + integration_view, ): organization, region = make_organization_and_region() organization.save() alert_receive_channel = make_alert_receive_channel( organization=organization, - integration=AlertReceiveChannel.INTEGRATION_ALERTMANAGER, + integration=integration_type, ) try: - am = AlertManagerAPIView() - am.dispatch(alert_channel_key=alert_receive_channel.token) + integration_view.dispatch(alert_channel_key=alert_receive_channel.token) assert False except OrganizationMovedException as e: assert e.organization == organization @@ -73,24 +89,29 @@ def test_integration_raises_exception_organization_moved( @patch("apps.user_management.middlewares.OrganizationMovedMiddleware.make_request") @pytest.mark.django_db +@pytest.mark.parametrize( + "integration_type", + [ + AlertReceiveChannel.INTEGRATION_ALERTMANAGER, + "amazon_sns", + ], +) def test_organization_moved_middleware( - mocked_make_request, - make_organization_and_region, - make_alert_receive_channel, + mocked_make_request, make_organization_and_region, make_alert_receive_channel, integration_type ): organization, region = make_organization_and_region() organization.save() alert_receive_channel = make_alert_receive_channel( organization=organization, - integration=AlertReceiveChannel.INTEGRATION_ALERTMANAGER, + integration=integration_type, ) expected_message = bytes(f"Redirected to {region.oncall_backend_url}", "utf-8") mocked_make_request.return_value = HttpResponse(expected_message, status=status.HTTP_200_OK) client = APIClient() - url = reverse("integrations:alertmanager", kwargs={"alert_channel_key": alert_receive_channel.token}) + url = reverse(f"integrations:{integration_type}", kwargs={"alert_channel_key": alert_receive_channel.token}) data = {"value": "test"} response = client.post(url, data, format="json")