views.py 3.4 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091
  1. from django.db.models import OuterRef, Prefetch, Subquery
  2. from django.shortcuts import get_object_or_404
  3. from django.utils import timezone
  4. from rest_framework import exceptions, permissions, viewsets
  5. from rest_framework.generics import CreateAPIView
  6. from organizations_ext.models import Organization
  7. from .models import Monitor, MonitorCheck
  8. from .serializers import (
  9. HeartBeatCheckSerializer,
  10. MonitorCheckSerializer,
  11. MonitorSerializer,
  12. )
  13. from .tasks import send_monitor_notification
  14. class HeartBeatCheckView(CreateAPIView):
  15. permission_classes = [permissions.AllowAny]
  16. serializer_class = HeartBeatCheckSerializer
  17. def perform_create(self, serializer):
  18. monitor = get_object_or_404(
  19. Monitor.objects.with_check_annotations(),
  20. organization__slug=self.kwargs.get("organization_slug"),
  21. endpoint_id=self.kwargs.get("endpoint_id"),
  22. )
  23. monitor_check = serializer.save(monitor=monitor, is_up=True)
  24. if monitor.latest_is_up is False:
  25. send_monitor_notification.delay(
  26. monitor_check.pk, False, monitor.last_change
  27. )
  28. class MonitorViewSet(viewsets.ModelViewSet):
  29. queryset = Monitor.objects.with_check_annotations()
  30. serializer_class = MonitorSerializer
  31. def get_queryset(self):
  32. if not self.request.user.is_authenticated:
  33. return self.queryset.none()
  34. queryset = self.queryset.filter(organization__users=self.request.user)
  35. organization_slug = self.kwargs.get("organization_slug")
  36. if organization_slug:
  37. queryset = queryset.filter(organization__slug=organization_slug)
  38. subqueryset = Subquery(
  39. MonitorCheck.objects.filter(
  40. monitor=OuterRef("monitor")
  41. ).order_by("-start_check").values_list("id", flat=True)[:60]
  42. )
  43. # Optimization hack, we know the checks will be recent. No need to sort all checks ever.
  44. hours_ago = timezone.now() - timezone.timedelta(hours=12)
  45. queryset = queryset.prefetch_related(
  46. Prefetch(
  47. "checks",
  48. queryset=MonitorCheck.objects.filter(
  49. id__in=subqueryset, start_check__gt=hours_ago
  50. ).order_by("-start_check"),
  51. )
  52. ).select_related("project").distinct()
  53. return queryset
  54. def perform_create(self, serializer):
  55. try:
  56. organization = Organization.objects.get(
  57. slug=self.kwargs.get("organization_slug"), users=self.request.user
  58. )
  59. except Organization.DoesNotExist:
  60. raise exceptions.ValidationError("Organization not found")
  61. serializer.save(organization=organization)
  62. class MonitorCheckViewSet(viewsets.ReadOnlyModelViewSet):
  63. queryset = MonitorCheck.objects.all()
  64. serializer_class = MonitorCheckSerializer
  65. def get_queryset(self):
  66. if not self.request.user.is_authenticated:
  67. return self.queryset.none()
  68. queryset = self.queryset.filter(monitor__organization__users=self.request.user)
  69. organization_slug = self.kwargs.get("organization_slug")
  70. if organization_slug:
  71. queryset = queryset.filter(monitor__organization__slug=organization_slug)
  72. monitor_pk = self.kwargs.get("monitor_pk")
  73. if monitor_pk:
  74. queryset = queryset.filter(monitor__pk=monitor_pk)
  75. return queryset