views.py 3.6 KB

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