API for grafana alerting (including test fix) (#2737)
# What this PR does This PR is related to #2645. That PR was reverted in #2730. This reverts the revert + adds a fix for the test that was failing ## 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) --------- Co-authored-by: Innokentii Konstantinov <innokenty.konstantinov@grafana.com>
This commit is contained in:
parent
33c5e89299
commit
d7e2f7053d
5 changed files with 71 additions and 3 deletions
|
|
@ -227,7 +227,7 @@ class FilterAlertReceiveChannelSerializer(serializers.ModelSerializer):
|
|||
|
||||
class Meta:
|
||||
model = AlertReceiveChannel
|
||||
fields = ["value", "display_name"]
|
||||
fields = ["value", "display_name", "integration_url"]
|
||||
|
||||
def get_value(self, obj):
|
||||
return obj.public_primary_key
|
||||
|
|
|
|||
|
|
@ -33,6 +33,41 @@ def test_get_alert_receive_channel(alert_receive_channel_internal_api_setup, mak
|
|||
assert response.status_code == status.HTTP_200_OK
|
||||
|
||||
|
||||
@pytest.mark.django_db
|
||||
@pytest.mark.parametrize(
|
||||
"query_param,should_be_unpaginated",
|
||||
[
|
||||
("True", True),
|
||||
("true", True),
|
||||
("TRUE", True),
|
||||
("", False),
|
||||
("False", False),
|
||||
("false", False),
|
||||
("FALSE", False),
|
||||
],
|
||||
)
|
||||
def test_list_alert_receive_channel_skip_pagination_for_grafana_alerting(
|
||||
alert_receive_channel_internal_api_setup,
|
||||
make_user_auth_headers,
|
||||
query_param,
|
||||
should_be_unpaginated,
|
||||
):
|
||||
user, token, _ = alert_receive_channel_internal_api_setup
|
||||
client = APIClient()
|
||||
|
||||
url = reverse("api-internal:alert_receive_channel-list")
|
||||
response = client.get(f"{url}?skip_pagination={query_param}", format="json", **make_user_auth_headers(user, token))
|
||||
results = response.json()
|
||||
assert response.status_code == status.HTTP_200_OK
|
||||
|
||||
if should_be_unpaginated:
|
||||
assert type(results) == list
|
||||
assert len(results) > 0
|
||||
else:
|
||||
assert type(results["results"]) == list
|
||||
assert len(results["results"]) > 0
|
||||
|
||||
|
||||
@pytest.mark.django_db
|
||||
def test_heartbeat_data_absence_alert_receive_channel(alert_receive_channel_internal_api_setup, make_user_auth_headers):
|
||||
"""
|
||||
|
|
|
|||
|
|
@ -38,7 +38,7 @@ class AlertReceiveChannelFilter(ByTeamModelFieldFilterMixin, filters.FilterSet):
|
|||
maintenance_mode = filters.MultipleChoiceFilter(
|
||||
choices=AlertReceiveChannel.MAINTENANCE_MODE_CHOICES, method="filter_maintenance_mode"
|
||||
)
|
||||
integration = filters.ChoiceFilter(choices=AlertReceiveChannel.INTEGRATION_CHOICES)
|
||||
integration = filters.MultipleChoiceFilter(choices=AlertReceiveChannel.INTEGRATION_CHOICES)
|
||||
team = TeamModelMultipleChoiceFilter()
|
||||
|
||||
class Meta:
|
||||
|
|
@ -80,7 +80,7 @@ class AlertReceiveChannelView(
|
|||
update_serializer_class = AlertReceiveChannelUpdateSerializer
|
||||
|
||||
filter_backends = [SearchFilter, DjangoFilterBackend]
|
||||
search_fields = ("verbal_name", "integration")
|
||||
search_fields = ("verbal_name",)
|
||||
|
||||
filterset_class = AlertReceiveChannelFilter
|
||||
pagination_class = FifteenPageSizePaginator
|
||||
|
|
@ -102,6 +102,7 @@ class AlertReceiveChannelView(
|
|||
"filters": [RBACPermission.Permissions.INTEGRATIONS_READ],
|
||||
"start_maintenance": [RBACPermission.Permissions.INTEGRATIONS_WRITE],
|
||||
"stop_maintenance": [RBACPermission.Permissions.INTEGRATIONS_WRITE],
|
||||
"validate_name": [RBACPermission.Permissions.INTEGRATIONS_WRITE],
|
||||
"migrate": [RBACPermission.Permissions.INTEGRATIONS_WRITE],
|
||||
}
|
||||
|
||||
|
|
@ -144,6 +145,15 @@ class AlertReceiveChannelView(
|
|||
|
||||
return queryset
|
||||
|
||||
def paginate_queryset(self, queryset):
|
||||
"""
|
||||
If `skip_pagination` is provided and is equal to "true" (or "True"), it will return
|
||||
a non paginated list of results. This is useful for Grafana Alerting
|
||||
"""
|
||||
if self.request.query_params.get("skip_pagination", "false").lower() == "true":
|
||||
return None
|
||||
return super().paginate_queryset(queryset)
|
||||
|
||||
@action(detail=True, methods=["post"], throttle_classes=[DemoAlertThrottler])
|
||||
def send_demo_alert(self, request, pk):
|
||||
instance = self.get_object()
|
||||
|
|
@ -333,3 +343,21 @@ class AlertReceiveChannelView(
|
|||
|
||||
instance.save()
|
||||
return Response(status=status.HTTP_200_OK)
|
||||
|
||||
@action(detail=False, methods=["get"])
|
||||
def validate_name(self, request):
|
||||
"""
|
||||
Checks if verbal_name is available.
|
||||
It is needed for OnCall <-> Alerting integration.
|
||||
"""
|
||||
verbal_name = self.request.query_params.get("verbal_name")
|
||||
if verbal_name is None:
|
||||
raise BadRequest("verbal_name is required")
|
||||
organization = self.request.auth.organization
|
||||
name_used = AlertReceiveChannel.objects.filter(organization=organization, verbal_name=verbal_name).exists()
|
||||
if name_used:
|
||||
r = Response(status=status.HTTP_409_CONFLICT)
|
||||
else:
|
||||
r = Response(status=status.HTTP_200_OK)
|
||||
|
||||
return r
|
||||
|
|
|
|||
|
|
@ -10,6 +10,7 @@ FEATURE_TELEGRAM = "telegram"
|
|||
FEATURE_LIVE_SETTINGS = "live_settings"
|
||||
FEATURE_GRAFANA_CLOUD_NOTIFICATIONS = "grafana_cloud_notifications"
|
||||
FEATURE_GRAFANA_CLOUD_CONNECTION = "grafana_cloud_connection"
|
||||
FEATURE_GRAFANA_ALERTING_V2 = "grafana_alerting_v2"
|
||||
|
||||
|
||||
class FeaturesAPIView(APIView):
|
||||
|
|
@ -40,4 +41,7 @@ class FeaturesAPIView(APIView):
|
|||
if live_settings.GRAFANA_CLOUD_NOTIFICATIONS_ENABLED:
|
||||
enabled_features.append(FEATURE_GRAFANA_CLOUD_NOTIFICATIONS)
|
||||
|
||||
if settings.FEATURE_GRAFANA_ALERTING_V2_ENABLED:
|
||||
enabled_features.append(FEATURE_GRAFANA_ALERTING_V2)
|
||||
|
||||
return enabled_features
|
||||
|
|
|
|||
|
|
@ -65,6 +65,7 @@ FEATURE_MULTIREGION_ENABLED = getenv_boolean("FEATURE_MULTIREGION_ENABLED", defa
|
|||
FEATURE_INBOUND_EMAIL_ENABLED = getenv_boolean("FEATURE_INBOUND_EMAIL_ENABLED", default=False)
|
||||
FEATURE_PROMETHEUS_EXPORTER_ENABLED = getenv_boolean("FEATURE_PROMETHEUS_EXPORTER_ENABLED", default=False)
|
||||
FEATURE_SHIFT_SWAPS_ENABLED = getenv_boolean("FEATURE_SHIFT_SWAPS_ENABLED", default=False)
|
||||
FEATURE_GRAFANA_ALERTING_V2_ENABLED = getenv_boolean("FEATURE_GRAFANA_ALERTING_V2_ENABLED", default=False)
|
||||
GRAFANA_CLOUD_ONCALL_HEARTBEAT_ENABLED = getenv_boolean("GRAFANA_CLOUD_ONCALL_HEARTBEAT_ENABLED", default=True)
|
||||
GRAFANA_CLOUD_NOTIFICATIONS_ENABLED = getenv_boolean("GRAFANA_CLOUD_NOTIFICATIONS_ENABLED", default=True)
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue