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 unsilence_incident(incident_id): incident = Incident.objects.get(id=incident_id) if incident.event_type == Incident.ACKNOWLEDGE: incident.event_type = Incident.TRIGGER incident.save() NotificationHelper.notify_incident(incident) silenced_incident = IncidentSilenced.objects.filter(incident=incident) silenced_incident.delete()
def testnotification(request): if not request.user.is_staff and int(request.user.id) != int( request.POST['id']): raise PermissionDenied("User " + str(request.user.id) + " isn't staff") user = User.objects.get(id=request.POST['id']) NotificationHelper.notify_user_about_incident( None, user, 1, "This is a notification test message, just ignore it") return HttpResponseRedirect(reverse('openduty.users.list'))
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 forward_incident(request): url = reverse('IncidentsListView') request_url = request.POST.get('url', url) try: incident = Incident.objects.get(id=request.POST.get('id')) user = User.objects.get(id=request.POST.get('user_id')) ScheduledNotification.remove_all_for_incident(incident) NotificationHelper.notify_user_about_incident(incident, user) event_log_message = f"{request.user.username} changed assignee of " \ f"incident : {incident.incident_key} to {user.username}" EventLog.objects.create(user=request.user, action="forward", incident_key=incident, service_key=incident.service_key, data=event_log_message, occurred_at=timezone.now()) except Incident.DoesNotExist: messages.error(request, 'Incident not found') return HttpResponseRedirect(request_url) except User.DoesNotExist: messages.error(request, 'Incident not found') return HttpResponseRedirect(request_url) return HttpResponseRedirect(request_url)
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)
def escalate(self, request, *args, **kwargs): """ escalate an incident to another service's escalation rule; persists until ACK """ 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 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.get("service_key_to_escalate_to")) service_token2 = ServiceTokens.objects.get(token_id=token2) service2 = service_token2.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) try: # get service_to_escalate to and modify incident object incident = Incident.objects.get( incident_key=request.data.get("incident_key"), service_key=service) except (Incident.DoesNotExist, KeyError): return Response({"Incident does not exist"}, status=status.HTTP_404_NOT_FOUND) incident.service_to_escalate_to = service2 incident.event_type = "escalated" if request.data.get("IncidentDetailView"): incident.details = request.data.get("IncidentDetailView") incident.save() username = '******' if request.user.is_anonymous else request.user.username event_log_message = f"{username} escalated to " \ f"service escalation policy : {incident.incident_key} to {service2.name}" EventLog.objects.create(user=request.user, action="escalate", incident_key=incident, service_key=incident.service_key, data=event_log_message, occurred_at=timezone.now()) # 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( { f"Incident successfully escalated to service {service2.name} escalation policy" }, status=status.HTTP_200_OK, headers=headers)