Add endpoint for organization config checks (#4204)

Related to https://github.com/grafana/oncall-private/issues/2563
This commit is contained in:
Matias Bordese 2024-04-11 11:51:56 -03:00 committed by GitHub
parent 08ce22b59b
commit a17bd893d0
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
5 changed files with 142 additions and 1 deletions

View file

@ -2,6 +2,7 @@ from dataclasses import asdict
from rest_framework import serializers
from apps.base.messaging import get_messaging_backend_from_id
from apps.base.models import LiveSetting
from apps.phone_notifications.phone_provider import get_phone_provider
from apps.slack.models import SlackTeamIdentity
@ -107,3 +108,30 @@ class FastOrganizationSerializer(serializers.ModelSerializer):
class Meta:
model = Organization
fields = ["pk", "name"]
class CurrentOrganizationConfigChecksSerializer(serializers.ModelSerializer):
is_chatops_connected = serializers.SerializerMethodField()
is_integration_chatops_connected = serializers.SerializerMethodField()
class Meta:
model = Organization
fields = [
"is_chatops_connected",
"is_integration_chatops_connected",
]
def get_is_chatops_connected(self, obj):
msteams_backend = get_messaging_backend_from_id("MSTEAMS")
return bool(
obj.slack_team_identity_id is not None # slack is connected
or obj.telegram_channel.exists() # telegram is connected
or (msteams_backend and msteams_backend.is_configured_for_organization(obj)) # msteams is connected
)
def get_is_integration_chatops_connected(self, obj):
return (
obj.alert_receive_channels.filter(channel_filters__notify_in_slack=True).exists()
or obj.alert_receive_channels.filter(channel_filters__notify_in_telegram=True).exists()
or obj.alert_receive_channels.filter(channel_filters__notification_backends__MSTEAMS__enabled=True).exists()
)

View file

@ -230,3 +230,93 @@ def test_organization_get_channel_verification_code_invalid(
response = client.get(url, format="json", **make_user_auth_headers(tester, token))
assert response.status_code == status.HTTP_400_BAD_REQUEST
@pytest.mark.django_db
def test_get_organization_slack_config_checks(
make_organization_and_user_with_plugin_token,
make_slack_team_identity,
make_alert_receive_channel,
make_channel_filter,
make_user_auth_headers,
):
organization, user, token = make_organization_and_user_with_plugin_token()
client = APIClient()
url = reverse("api-internal:api-organization-config-checks")
expected_result = {
"is_chatops_connected": False,
"is_integration_chatops_connected": False,
}
response = client.get(url, format="json", **make_user_auth_headers(user, token))
assert response.status_code == status.HTTP_200_OK
assert response.json() == expected_result
# connect Slack
slack_team_identity = make_slack_team_identity()
organization.slack_team_identity = slack_team_identity
organization.save()
response = client.get(url, format="json", **make_user_auth_headers(user, token))
assert response.status_code == status.HTTP_200_OK
expected_result["is_chatops_connected"] = True
assert response.json() == expected_result
# create integration
integration = make_alert_receive_channel(organization)
response = client.get(url, format="json", **make_user_auth_headers(user, token))
assert response.status_code == status.HTTP_200_OK
assert response.json() == expected_result
# connect integration to Slack
make_channel_filter(integration, notify_in_slack=True)
response = client.get(url, format="json", **make_user_auth_headers(user, token))
assert response.status_code == status.HTTP_200_OK
expected_result["is_integration_chatops_connected"] = True
assert response.json() == expected_result
@pytest.mark.django_db
def test_get_organization_telegram_config_checks(
make_organization_and_user_with_plugin_token,
make_telegram_channel,
make_alert_receive_channel,
make_channel_filter,
make_user_auth_headers,
):
organization, user, token = make_organization_and_user_with_plugin_token()
client = APIClient()
url = reverse("api-internal:api-organization-config-checks")
expected_result = {
"is_chatops_connected": False,
"is_integration_chatops_connected": False,
}
response = client.get(url, format="json", **make_user_auth_headers(user, token))
assert response.status_code == status.HTTP_200_OK
assert response.json() == expected_result
# connect Telegram
make_telegram_channel(organization)
response = client.get(url, format="json", **make_user_auth_headers(user, token))
assert response.status_code == status.HTTP_200_OK
expected_result["is_chatops_connected"] = True
assert response.json() == expected_result
# create integration
integration = make_alert_receive_channel(organization)
response = client.get(url, format="json", **make_user_auth_headers(user, token))
assert response.status_code == status.HTTP_200_OK
assert response.json() == expected_result
# connect integration to Slack
make_channel_filter(integration, notify_in_telegram=True)
response = client.get(url, format="json", **make_user_auth_headers(user, token))
assert response.status_code == status.HTTP_200_OK
expected_result["is_integration_chatops_connected"] = True
assert response.json() == expected_result

View file

@ -20,6 +20,7 @@ from .views.organization import (
CurrentOrganizationView,
GetChannelVerificationCode,
GetTelegramVerificationCode,
OrganizationConfigChecksView,
SetGeneralChannel,
)
from .views.paging import DirectPagingAPIView
@ -72,6 +73,11 @@ urlpatterns = [
optional_slash_path("user", CurrentUserView.as_view(), name="api-user"),
optional_slash_path("set_general_channel", SetGeneralChannel.as_view(), name="api-set-general-log-channel"),
optional_slash_path("organization", CurrentOrganizationView.as_view(), name="api-organization"),
optional_slash_path(
"organization/config-checks",
OrganizationConfigChecksView.as_view(),
name="api-organization-config-checks",
),
# TODO: remove current_team routes in future release
optional_slash_path("current_team", CurrentOrganizationView.as_view(), name="api-current-team"),
optional_slash_path(

View file

@ -6,7 +6,7 @@ from rest_framework.response import Response
from rest_framework.views import APIView
from apps.api.permissions import RBACPermission
from apps.api.serializers.organization import CurrentOrganizationSerializer
from apps.api.serializers.organization import CurrentOrganizationConfigChecksSerializer, CurrentOrganizationSerializer
from apps.auth_token.auth import PluginAuthentication
from apps.base.messaging import get_messaging_backend_from_id
from apps.mobile_app.auth import MobileAppAuthTokenAuthentication
@ -50,6 +50,20 @@ class CurrentOrganizationView(APIView):
return Response(serializer.data)
class OrganizationConfigChecksView(APIView):
authentication_classes = (PluginAuthentication,)
permission_classes = (IsAuthenticated, RBACPermission)
rbac_permissions = {
"get": [RBACPermission.Permissions.OTHER_SETTINGS_READ],
}
def get(self, request):
organization = request.auth.organization
serializer = CurrentOrganizationConfigChecksSerializer(organization)
return Response(serializer.data)
class GetTelegramVerificationCode(APIView):
authentication_classes = (PluginAuthentication,)
permission_classes = (IsAuthenticated, RBACPermission)

View file

@ -43,6 +43,9 @@ class BaseMessagingBackend:
def is_enabled_for_organization(organization):
return True
def is_configured_for_organization(self, organization):
return True
def serialize_user(self, user):
"""Return a serialized backend user representation."""
raise NotImplementedError("serialize_user method missing implementation")