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 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({}, status=status.HTTP_404_NOT_FOUND) except Token.DoesNotExist: return Response({}, status=status.HTTP_403_FORBIDDEN) with transaction.atomic(): try: incident = Incident.objects.get(incident_key = request.DATA["incident_key"], service_key = service) event_log_message = "%s api key changed %s from %s to %s" % (serviceToken.name, incident.incident_key, incident.event_type, request.DATA['event_type']) 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 incident.event_type != Incident.ACKNOWLEDGE or (incident.event_type == Incident.ACKNOWLEDGE and request.DATA["event_type"] == Incident.RESOLVE ): event_log = EventLog() event_log.service_key = incident.service_key event_log.data = event_log_message event_log.occurred_at = datetime.now() event_log.save() incident.event_type = request.DATA["event_type"] incident.description = request.DATA["description"][:100] incident.details =request.DATA["details"] incident.occurred_at = datetime.now() try: incident.full_clean() except ValidationError as e: return Response({'errors': e.messages}, status=status.HTTP_400_BAD_REQUEST) incident.save() if incident.event_type == Incident.TRIGGER: NotificationHelper.notify_incident(incident) if incident.event_type == "resolve" or incident.event_type == Incident.ACKNOWLEDGE: ScheduledNotification.remove_all_for_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 update_type(request): try: with transaction.atomic(): incident = Incident.objects.get(id=request.POST['id']) logmessage = EventLog() logmessage.service_key = incident.service_key logmessage.data = "%s changed %s from %s to %s" % ( request.user.username, incident.incident_key, incident.event_type, request.POST['event_type']) logmessage.occurred_at = datetime.now() logmessage.save() incident.event_type = request.POST['event_type'] incident.occurred_at = datetime.now() incident.save() if incident.event_type == "resolve" or incident.event_type == Incident.ACKNOWLEDGE: ScheduledNotification.remove_all_for_incident(incident) except Incident.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 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 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 generate_notifications_for_user(incident, user, delay=None, preparedmsg = None): now = timezone.make_aware(datetime.now(), timezone.get_current_timezone()) current_time = now notifications = [] methods = user.notification_methods.order_by('position').all() method_index = 0 for method in methods: if delay is None: notification_time = incident.service_key.retry * method_index + incident.service_key.escalate_after else: notification_time = method_index * delay notify_at = current_time + timedelta(minutes=notification_time) notification = ScheduledNotification() notification.incident = incident notification.user_to_notify = user notification.notifier = method.method notification.send_at = notify_at if preparedmsg is None: uri = settings.BASE_URL + "/incidents/details/" + str(incident.id) notification.message = "A Service is experiencing a problem: " + incident.incident_key + " " + incident.description + ". Handle at: " + uri else: notification.message = preparedmsg notifications.append(notification) if notification.incident: print "[%s] Notify %s at %s with method: %s" % (notification.incident.event_type, user.username, notify_at, notification.notifier) method_index += 1 # todo: error handling return notifications
def generate_notifications_for_user(incident, user, delay=None, preparedmsg = None): now = timezone.make_aware(datetime.now(), timezone.get_current_timezone()) current_time = now notifications = [] methods = user.notification_methods.order_by('position').all() method_index = 0 for method in methods: if delay is None: notification_time = incident.service_key.retry * method_index + incident.service_key.escalate_after else: notification_time = method_index * delay notify_at = current_time + timedelta(minutes=notification_time) notification = ScheduledNotification() notification.incident = incident notification.user_to_notify = user notification.notifier = method.method notification.send_at = notify_at if preparedmsg is None: uri = settings.BASE_URL + "/incidents/details/" + str(incident.id) notification.message = "A Service is experiencing a problem: " + incident.incident_key + " " + incident.description + ". Handle at: " + uri else: notification.message = preparedmsg notifications.append(notification) print "Notify %s at %s with method: %s" % (user.username, notify_at, notification.notifier) method_index += 1 # todo: error handling return notifications
def generate_notifications_for_incident(incident): now = timezone.make_aware(datetime.now(), timezone.get_current_timezone()) duty_officers = [] # if incident has been escalated, notify according to the escalated service's escalation rule if hasattr(incident, 'service_to_escalate_to') and incident.service_to_escalate_to is not None: print "escalation rule in place to " + incident.service_to_escalate_to.name duty_officers = get_escalation_for_service(incident.service_to_escalate_to) with transaction.atomic(): incident.description = "[escalated] " + incident.description incident.save() else: duty_officers = get_escalation_for_service(incident.service_key) current_time = now notifications = [] group_index = {} user_method_index = {} for officer_index, duty_officer in enumerate(duty_officers): if incident.event_type == Incident.RESOLVE and not duty_officer.profile.send_resolve_enabled: print "Skipping notification for %s because type is RESOLVE and user %s has send_resolve_enabled OFF" % (incident.incident_key, duty_officer.username) continue index = 0 if hasattr(duty_officer ,'came_from_group' ): if not duty_officer.came_from_group in group_index: group_index[duty_officer.came_from_group] = officer_index index = group_index[duty_officer.came_from_group] else: index = officer_index escalation_time = incident.service_key.escalate_after * (index + 1) escalate_at = current_time + timedelta(minutes=escalation_time) user_method_index[duty_officer.username] = 0 methods = duty_officer.notification_methods.order_by('position').all() for method in methods: notification_time = incident.service_key.retry * user_method_index[duty_officer.username] + incident.service_key.escalate_after * index notify_at = current_time + timedelta(minutes=notification_time) if notify_at < escalate_at: notification = ScheduledNotification() notification.incident = incident notification.user_to_notify = duty_officer notification.notifier = method.method notification.send_at = notify_at uri = settings.BASE_URL + "/incidents/details/" + str(incident.id) notification.message = incident.description + ". Handle at: " + uri + " Details: " + incident.details notifications.append(notification) print "[%s] Notify %s about %s at %s with method: %s" % (notification.incident.event_type, duty_officer.username, notification.incident.incident_key, notify_at, notification.notifier) else: break user_method_index[duty_officer.username] += 1 # todo: error handling return notifications
def update_type(request): try: with transaction.atomic(): incident = Incident.objects.get(id = request.POST['id']) logmessage = EventLog() logmessage.service_key = incident.service_key logmessage.data = "%s changed %s from %s to %s" % (request.user.username, incident.incident_key, incident.event_type, request.POST['event_type']) logmessage.occurred_at = datetime.now() logmessage.save() incident.event_type = request.POST['event_type'] incident.occurred_at = datetime.now() incident.save() if incident.event_type == "resolve" or incident.event_type == Incident.ACKNOWLEDGE: ScheduledNotification.remove_all_for_incident(incident) except Incident.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)) 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) 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 generate_notifications_for_incident(incident): now = timezone.make_aware(datetime.now(), timezone.get_current_timezone()) duty_officers = get_escalation_for_service(incident.service_key) current_time = now notifications = [] for officer_index, duty_officer in enumerate(duty_officers): escalation_time = incident.service_key.escalate_after * ( officer_index + 1) escalate_at = current_time + timedelta(minutes=escalation_time) methods = duty_officer.notification_methods.order_by( 'position').all() method_index = 0 for method in methods: notification_time = incident.service_key.retry * method_index + incident.service_key.escalate_after * officer_index notify_at = current_time + timedelta(minutes=notification_time) if notify_at < escalate_at: notification = ScheduledNotification() notification.incident = incident notification.user_to_notify = duty_officer notification.notifier = method.method notification.send_at = notify_at uri = settings.BASE_URL + "/incidents/details/" + str( incident.id) notification.message = "A Service is experiencing a problem: " + incident.incident_key + " " + incident.description + ". Handle at: " + uri + " Details: " + str( incident.details) notifications.append(notification) print "Notify %s at %s with method: %s" % ( duty_officer.username, notify_at, notification.notifier) else: break method_index += 1 # todo: error handling return notifications
def generate_notifications_for_incident(incident): now = timezone.make_aware(datetime.now(), timezone.get_current_timezone()) duty_officers = get_escalation_for_service(incident.service_key) current_time = now notifications = [] for officer_index, duty_officer in enumerate(duty_officers): escalation_time = incident.service_key.escalate_after * (officer_index + 1) escalate_at = current_time + timedelta(minutes=escalation_time) methods = duty_officer.notification_methods.all() method_index = 0 for method in methods: notification_time = incident.service_key.retry * method_index + incident.service_key.escalate_after * officer_index notify_at = current_time + timedelta(minutes=notification_time) if notify_at < escalate_at: notification = ScheduledNotification() notification.incident = incident notification.user_to_notify = duty_officer notification.notifier = method.method notification.send_at = notify_at uri = settings.BASE_URL + "/incidents/details/" + str(incident.id) notification.message = "A Service is experiencing a problem: " + incident.incident_key + " " + incident.description + ". Handle at: " + uri notifications.append(notification) print "Notify %s at %s with method: %s" % (duty_officer.username, notify_at, notification.notifier) else: break method_index += 1 # todo: error handling return notifications
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 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: token = Token.objects.get(key=request.DATA["service_key"]) service_token = ServiceTokens.objects.get(token_id=token) service = service_token.service_id police = service.policy if not police: return Response({}, status=status.HTTP_403_FORBIDDEN) schedule_police_rule = SchedulePolicyRule.objects.get( schedule_policy=police) calendar = schedule_police_rule.schedule event = Event.objects.filter(start__lte=timezone.now(), calendar=calendar) if not event: return Response({}, status=status.HTTP_403_FORBIDDEN) # except except Event.DoesNotExist: return Response({}, status=status.HTTP_404_NOT_FOUND) except SchedulePolicyRule.DoesNotExist: return Response({}, status=status.HTTP_404_NOT_FOUND) except ServiceTokens.DoesNotExist: return Response({}, status=status.HTTP_404_NOT_FOUND) except Token.DoesNotExist: return Response({}, status=status.HTTP_403_FORBIDDEN) with transaction.atomic(): try: incident = Incident.objects.get( incident_key=request.DATA["incident_key"], service_key=service) event_log_message = "%s api key changed %s from %s to %s" % ( service_token.name, incident.incident_key, incident.event_type, request.DATA['event_type']) 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" % ( service_token.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["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 == "resolve" or incident.event_type == Incident.ACKNOWLEDGE: ScheduledNotification.remove_all_for_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)