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
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'])
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)
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)
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
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
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)
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)