Пример #1
0
def silence(request, incident_id):
    try:
        incident = Incident.objects.get(id=incident_id)
        silence_for = request.POST.get('silence_for')
        url = request.POST.get("url")
        if IncidentSilenced.objects.filter(incident=incident).count() < 1:
            silenced_incident = IncidentSilenced()
            silenced_incident.incident = incident
            silenced_incident.silenced_until = timezone.now(
            ) + timezone.timedelta(hours=int(silence_for))
            silenced_incident.silenced = True
            silenced_incident.save()
            event_log_message = "%s silenced incident %s for %s hours" % (
                request.user.username, incident.incident_key, silence_for)
            event_log = EventLog()
            event_log.incident_key = incident
            event_log.action = 'silence_incident'
            event_log.user = request.user
            event_log.service_key = incident.service_key
            event_log.data = event_log_message
            event_log.occurred_at = timezone.now()
            event_log.save()
            ScheduledNotification.remove_all_for_incident(incident)
            incident.event_type = Incident.ACKNOWLEDGE
            incident.save()
            unsilence_incident.apply_async(
                (incident_id,), eta=silenced_incident.silenced_until)
        return HttpResponseRedirect(url)
    except Service.DoesNotExist:
        raise Http404
Пример #2
0
def forward_incident(request):
    try:
        with transaction.atomic():
            incident = Incident.objects.get(id=request.POST['id'])
            user = User.objects.get(id=request.POST['user_id'])
            ScheduledNotification.remove_all_for_incident(incident)
            NotificationHelper.notify_user_about_incident(incident, user)
            event_log_message = "%s  changed assignee of incident :  %s  to %s" % (
                request.user.username, incident.incident_key, user.username)
            event_log = EventLog()
            event_log.user = request.user
            event_log.action = "forward"
            event_log.incident_key = incident
            event_log.service_key = incident.service_key
            event_log.data = event_log_message
            event_log.occurred_at = timezone.now()
            event_log.save()

    except Incident.DoesNotExist:
        messages.error(request, 'Incident not found')
        return HttpResponseRedirect(request.POST['url'])
    except User.DoesNotExist:
        messages.error(request, 'Incident not found')
        return HttpResponseRedirect(request.POST['url'])
    except ValidationError as e:
        messages.error(request, e.messages)
    return HttpResponseRedirect(request.POST['url'])
Пример #3
0
def _update_type(user, ids, event_type):
    for incident_id in ids:
        with transaction.atomic():
            incident = Incident.objects.get(id=int(incident_id))
            unesc = False
            if incident.service_to_escalate_to is not None:
                incident.service_to_escalate_to = None
                unesc = True
            logmessage = EventLog()
            logmessage.service_key = incident.service_key
            logmessage.user = user
            logmessage.action = event_type
            logmessage.data = "%s changed %s from %s to %s" % (
                user.username,
                incident.incident_key,
                incident.event_type,
                event_type)
            if unesc:
                logmessage.data += ", unescalated"
            logmessage.occurred_at = timezone.now()

            incident.event_type = event_type
            incident.occurred_at = timezone.now()
            incident.save()

            logmessage.incident_key = incident
            logmessage.save()
            if incident.event_type == Incident.RESOLVE or incident.event_type == Incident.ACKNOWLEDGE:
                ScheduledNotification.remove_all_for_incident(incident)
Пример #4
0
    def escalate(self, request, *args, **kwargs):
        #get arguments
        try:
            token = Token.objects.get(key=request.data["service_key"])
            serviceToken = ServiceTokens.objects.get(token_id=token)
            service = serviceToken.service_id
        except ServiceTokens.DoesNotExist:
            return Response({"Service key does not exist"}, status=status.HTTP_404_NOT_FOUND)
        except Token.DoesNotExist:
            return Response({"No service key"}, status=status.HTTP_403_FORBIDDEN)

        try:
            token2 = Token.objects.get(key=request.data["service_key_to_escalate_to"])
            serviceToken2 = ServiceTokens.objects.get(token_id=token2)
            service2 = serviceToken2.service_id
        except ServiceTokens.DoesNotExist:
            return Response({"Service to escalate to key does not exist"}, status=status.HTTP_404_NOT_FOUND)
        except Token.DoesNotExist:
            return Response({"No service to escalate to key"}, status=status.HTTP_403_FORBIDDEN)

        #modify incident
        with transaction.atomic():
            try:
                # get service_to_escalate to and modify incident object
                incident = Incident.objects.get(incident_key=request.data["incident_key"],service_key=service)
                incident.service_to_escalate_to = service2
                incident.event_type = "escalated"
                if request.data["incident_details"]:
                    incident.details = request.data["incident_details"]
                #                incident.description = "[escalated] " + incident.description
                incident.save()

                event_log_message = "%s escalated to service escalation policy :  %s  to %s" % (request.user.username, incident.incident_key, service2.name)
                event_log = EventLog()
                event_log.user = request.user
                event_log.action = "escalate"
                event_log.incident_key = incident
                event_log.service_key = incident.service_key
                event_log.data = event_log_message
                event_log.occurred_at = timezone.now()
                event_log.save()

            except (Incident.DoesNotExist, KeyError):
                return Response({"Incident does not exist"}, status=status.HTTP_404_NOT_FOUND)
            except (Service.DoesNotExist, KeyError):
                return Response({"Service does not exist"}, status=status.HTTP_400_BAD_REQUEST)
        # remove all planned notifs
        ScheduledNotification.remove_all_for_incident(incident)
        # notify anew, this time notify_incident will detect the service_to_escalate to and notify its escalation rule
        NotificationHelper.notify_incident(incident)

        headers = self.get_success_headers(request.POST)

        return Response({"Incident successfully escalated to service " + service2.name + " escalation policy"},status=status.HTTP_200_OK,headers=headers)
Пример #5
0
def unsilence(request, incident_id):
    try:
        incident = Incident.objects.get(id = incident_id)
        url = request.POST.get("url")
        try:
            IncidentSilenced.objects.filter(incident=incident).delete()
            event_log_message = "%s removed silence from incident %s" % (request.user.username, incident.incident_key)
            event_log = EventLog()
            event_log.action = 'unsilence_incident'
            event_log.user = request.user
            event_log.incident_key = incident
            event_log.service_key = incident.service_key
            event_log.data = event_log_message
            event_log.occurred_at = timezone.now()
            event_log.save()
        except IncidentSilenced.DoesNotExist:
            # No need to delete
            pass
        return HttpResponseRedirect(url)
    except Service.DoesNotExist:
        raise Http404
Пример #6
0
def send_notifications(notification_id):
    try:
        notification = ScheduledNotification.objects.get(id = notification_id)
        # if notification.notifier == UserNotificationMethod.METHOD_XMPP:
        #     notifier = XmppNotifier(settings.XMPP_SETTINGS)
        if notification.notifier == UserNotificationMethod.METHOD_EMAIL:
            notifier = EmailNotifier(settings.EMAIL_SETTINGS)
        if notification.notifier == UserNotificationMethod.METHOD_TWILIO_SMS:
            notifier = TwilioSmsNotifier(settings.TWILIO_SETTINGS)
        if notification.notifier == UserNotificationMethod.METHOD_TWILIO_CALL:
            notifier = TwilioCallNotifier(settings.TWILIO_SETTINGS)
        if notification.notifier == UserNotificationMethod.METHOD_SLACK:
            notifier = SlackNotifier(settings.SLACK_SETTINGS)
        elif notification.notifier == UserNotificationMethod.METHOD_PUSHOVER:
            notifier = PushoverNotifier()
        elif notification.notifier == UserNotificationMethod.METHOD_PROWL:
            notifier = ProwlNotifier(settings.PROWL_SETTINGS)
        elif notification.notifier == UserNotificationMethod.METHOD_ROCKET:
            notifier = RocketNotifier()
        elif notification.notifier == UserNotificationMethod.METHOD_HIPCHAT:
            notifier = HipchatNotifier(settings.HIPCHAT_SETTINGS)

        notifier.notify(notification)
        # Log successful notification
        logmessage = EventLog()
        if notification.incident:
            logmessage.service_key = notification.incident.service_key
            logmessage.incident_key = notification.incident
            logmessage.user = notification.user_to_notify
            logmessage.action = 'notified'
            logmessage.data = "Notification sent to %s about %s service via %s" % (notification.user_to_notify, logmessage.service_key, notification.notifier, )
            logmessage.occurred_at = timezone.now()
            logmessage.save()
            return (logmessage.data)
        if notification.notifier != UserNotificationMethod.METHOD_TWILIO_CALL:
            # In case of a twilio call, we need the object for TWiml generation
            notification.delete()
    except ScheduledNotification.DoesNotExist:
        pass #Incident was resolved. NOP.
    except Exception as e:
                # Log successful notification
        logmessage = EventLog()
        if notification.incident:
            logmessage.service_key = notification.incident.service_key
            logmessage.incident_key = notification.incident
            logmessage.user = notification.user_to_notify
            logmessage.action = 'notification_failed'
            logmessage.data = "Sending notification failed to %s about %s service because %s" % (notification.user_to_notify, logmessage.service_key, e,)
            logmessage.occurred_at = timezone.now()
            logmessage.save()
            return (logmessage.data)
        raise
Пример #7
0
    def create(self, request, *args, **kwargs):
        try:
            token = Token.objects.get(key=request.data["service_key"])
            serviceToken = ServiceTokens.objects.get(token_id=token)
            service = serviceToken.service_id
        except ServiceTokens.DoesNotExist:
            return Response({"Service key does not exist"}, status=status.HTTP_404_NOT_FOUND)
        except Token.DoesNotExist:
            return Response({"No service key"}, status=status.HTTP_403_FORBIDDEN)

        with transaction.atomic():
            try:
                esc = False
                incident = Incident.objects.get(incident_key=request.data["incident_key"],service_key=service)
                print("Received %s for %s on service %s" % (request.data['event_type'],request.data['incident_key'],serviceToken.name))
                #check if type is ACK or resolve and if there's an escalation to a different escalation policy, remove it
                if request.data['event_type'] == Incident.ACKNOWLEDGE or request.data['event_type'] == Incident.RESOLVE:
                    print("ACK or Resolve, removing specific escalation")
                    esc = True
                    incident.service_to_escalate_to = None
                    incident.save()
                # check if incident is resolved and refuse to ACK
                if not (incident.event_type == Incident.RESOLVE and request.data['event_type'] == Incident.ACKNOWLEDGE):
                    event_log_message = "%s api key changed %s from %s to %s" % (
                        serviceToken.name, incident.incident_key,
                        incident.event_type, request.data['event_type'])
                    if esc:
                        event_log_message += ", unescalated"
                else:
                    response = {}
                    response["status"] = "failure"
                    response["message"] = "Can\'t ACK a resolved incident!"
                    return Response(response, status=status.HTTP_400_BAD_REQUEST)
            except (Incident.DoesNotExist, KeyError):
                incident = Incident()
                try:
                    incident.incident_key = request.data["incident_key"]
                except KeyError:
                    if request.data["event_type"] == Incident.TRIGGER:
                        incident.incident_key = base64.urlsafe_b64encode(
                            uuid.uuid1().bytes).replace(
                            '=',
                            '')
                    else:
                        response = {}
                        response["status"] = "failure"
                        response["message"] = "Mandatory parameter missing"
                        return Response(
                            response,
                            status=status.HTTP_400_BAD_REQUEST)
                incident.service_key = service

                event_log_message = "%s api key created %s with status %s" % (
                    serviceToken.name, incident.incident_key, request.data['event_type'])

            if self.is_relevant(incident, request.data['event_type']):
                event_log = EventLog()
                # Anonymous user for testing
                if request.user.is_anonymous:
                    user = None
                else:
                    user = request.user
                event_log.user = user
                event_log.service_key = incident.service_key
                event_log.data = event_log_message
                event_log.occurred_at = timezone.now()

                incident.event_type = request.data["event_type"]
                incident.description = request.data["description"][:100]
                incident.details = request.data.get("details", "")
                incident.occurred_at = timezone.now()
                try:
                    incident.full_clean()
                except ValidationError as e:
                    return Response(
                        {'errors': e.messages},
                        status=status.HTTP_400_BAD_REQUEST)
                incident.save()
                event_log.incident_key = incident
                event_log.action = incident.event_type
                event_log.save()
                servicesilenced = ServiceSilenced.objects.filter(
                    service=service).count() > 0
                if incident.event_type == Incident.TRIGGER and not servicesilenced:
                    NotificationHelper.notify_incident(incident)
                if incident.event_type == Incident.RESOLVE or incident.event_type == Incident.ACKNOWLEDGE:
                    ScheduledNotification.remove_all_for_incident(incident)
                    if incident.event_type == Incident.RESOLVE and service.send_resolve_enabled:
                        NotificationHelper.notify_incident(incident)

            headers = self.get_success_headers(request.POST)

            response = {}
            response["status"] = "success"
            response["message"] = "Event processed"
            response["incident_key"] = incident.incident_key
            return Response(response,status=status.HTTP_201_CREATED,headers=headers)
Пример #8
0
    def create(self, request, *args, **kwargs):
        try:
            assert request.data.get("event_type")
            assert request.data.get("incident_key")
            assert request.data.get("service_key")
        except AssertionError:
            response = {
                "status": "failure",
                "message": "Mandatory parameter missing"
            }
            return Response(response, status=status.HTTP_400_BAD_REQUEST)
        try:
            token = Token.objects.get(key=request.data.get("service_key"))
            service_token = ServiceTokens.objects.get(token_id=token)
            service = service_token.service_id
        except Token.DoesNotExist:
            return Response({"No service key"},
                            status=status.HTTP_403_FORBIDDEN)
        except ServiceTokens.DoesNotExist:
            return Response({"Service key does not exist"},
                            status=status.HTTP_404_NOT_FOUND)

        esc = False
        incidents = Incident.objects.filter(
            incident_key=request.data.get("incident_key"), service_key=service)
        if incidents:
            incident = incidents[0]
            print(
                f"Received {request.data.get('event_type')} for"
                f" {request.data.get('incident_key')} on service {service_token.name}"
            )
            # check if type is ACK or resolve and if there's an
            # escalation to a different escalation policy, remove it
            if request.data.get('event_type') in [
                    Incident.ACKNOWLEDGE, Incident.RESOLVE
            ]:
                print("ACK or Resolve, removing specific escalation")
                esc = True
                incident.service_to_escalate_to = None
                incident.save()
            # check if incident is resolved and refuse to ACK
            event_log_message = f"{service_token.name} api key changed {incident.incident_key} " \
                f"from {incident.event_type} to {request.data.get('event_type')}"
            if incident.event_type not in [
                    Incident.RESOLVE, Incident.ACKNOWLEDGE
            ] and esc:
                event_log_message += ", unescalated"
        else:
            event_type = request.data.get("event_type")
            incident_key = str(uuid.uuid1()) if (
                event_type
                == Incident.TRIGGER) else request.data.get("incident_key")
            incident_service_key = service
            incident = Incident.objects.create(
                event_type=event_type,
                incident_key=incident_key,
                service_key=incident_service_key,
                description=request.data.get("description", " "),
                details=request.data.get("details", " "),
                occurred_at=timezone.now())
            event_log_message = f"{service_token.name} api key created " \
                f"{incident.incident_key} with status {request.data.get('event_type')}"

        if self.is_relevant(incident, request.data.get('event_type')):
            user = None if request.user.is_anonymous else request.user
            event_log = EventLog(user=user,
                                 service_key=incident.service_key,
                                 data=event_log_message,
                                 occurred_at=timezone.now())
            event_log.incident_key = incident
            event_log.action = incident.event_type
            event_log.save()
            service_silenced = ServiceSilenced.objects.filter(
                service=service).count() > 0
            if incident.event_type == Incident.TRIGGER and not service_silenced:
                NotificationHelper.notify_incident(incident)
            if incident.event_type == Incident.RESOLVE or incident.event_type == Incident.ACKNOWLEDGE:
                ScheduledNotification.remove_all_for_incident(incident)
                if incident.event_type == Incident.RESOLVE and service.send_resolve_enabled:
                    NotificationHelper.notify_incident(incident)

        response = {
            "status": "success",
            "message": "Event processed",
            "incident_key": incident.incident_key
        }
        return Response(response, status=status.HTTP_201_CREATED)