AmazonSNS integration exception handling (#3315)

# What this PR does
Handle OrganizationMoved, OrganizationDeleted and PermissionDenied
exceptions same as other integration API views instead of converting to
BadRequest.

## Which issue(s) this PR fixes

## Checklist

- [x] Unit, integration, and e2e (if applicable) tests updated
- [x] Documentation added (or `pr:no public docs` PR label added if not
required)
- [x] `CHANGELOG.md` updated (or `pr:no changelog` PR label added if not
required)
This commit is contained in:
Michael Derynck 2023-11-10 06:45:12 -07:00 committed by GitHub
parent d0a86a3105
commit ad1f63dbe9
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
3 changed files with 43 additions and 13 deletions

View file

@ -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)

View file

@ -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):

View file

@ -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")