132 lines
6.1 KiB
Python
132 lines
6.1 KiB
Python
import logging
|
|
import uuid
|
|
|
|
from django.contrib.auth.models import User
|
|
from django.db import models
|
|
from django.urls import reverse
|
|
from django.utils import timezone
|
|
from django.utils.translation import gettext_lazy, pgettext_lazy
|
|
from django_celery_beat.models import PeriodicTask
|
|
from rest_framework.authtoken.models import Token
|
|
from sequences import get_next_value
|
|
from solo.models import SingletonModel
|
|
|
|
from console.models import SensorConnectedMixin, UniqueNameDescriptionModel
|
|
from core.fields import IntegerField
|
|
|
|
_log = logging.getLogger(__name__)
|
|
|
|
|
|
class IncidentCategory(UniqueNameDescriptionModel):
|
|
""" Category of incident """
|
|
pass
|
|
|
|
|
|
class IncidentEffect(UniqueNameDescriptionModel):
|
|
""" Possible incident effect """
|
|
pass
|
|
|
|
class Meta:
|
|
verbose_name = gettext_lazy('Incident effect')
|
|
|
|
|
|
class IncidentRecommendations(UniqueNameDescriptionModel):
|
|
""" Recommendations how to close incident """
|
|
pass
|
|
|
|
class Meta:
|
|
verbose_name = gettext_lazy('Incident recommendation')
|
|
|
|
|
|
class Incident(SensorConnectedMixin):
|
|
""" Incident model """
|
|
|
|
IMPORTANCE_MIN = 0
|
|
IMPORTANCE_MAX = 100
|
|
|
|
class Status(models.IntegerChoices):
|
|
NOT_ASSIGNED = 0, gettext_lazy('Not assigned')
|
|
ASSIGNED = 1, gettext_lazy('Assigned')
|
|
DELAYED = 2, gettext_lazy('Delayed')
|
|
RESOLVED = 3, gettext_lazy('Resolved')
|
|
FALSE_ALARM = 4, gettext_lazy('False alarm')
|
|
|
|
user_friendly_id = IntegerField(blank=True, null=True)
|
|
timestamp = models.DateTimeField(default=timezone.now,
|
|
verbose_name=gettext_lazy('Timestamp'),
|
|
help_text=gettext_lazy('Date and time, when incident occurs'))
|
|
incident_id = models.UUIDField(primary_key=True,
|
|
default=uuid.uuid4,
|
|
verbose_name=gettext_lazy('ID'),
|
|
help_text=gettext_lazy('ID of incident'))
|
|
title = models.CharField(max_length=128,
|
|
verbose_name=gettext_lazy('Title'),
|
|
help_text=gettext_lazy('Title'))
|
|
category = models.ForeignKey(IncidentCategory,
|
|
on_delete=models.SET_NULL,
|
|
verbose_name=gettext_lazy('Category'),
|
|
help_text=gettext_lazy("Incident's category"),
|
|
null=True,
|
|
blank=True)
|
|
importance = IntegerField(min_value=IMPORTANCE_MIN,
|
|
max_value=IMPORTANCE_MAX,
|
|
verbose_name=gettext_lazy('Importance'),
|
|
help_text=gettext_lazy('Hazard level of incident'))
|
|
status = IntegerField(choices=Status.choices,
|
|
verbose_name=gettext_lazy('Status'),
|
|
help_text=gettext_lazy('Incident status'),
|
|
default=Status.NOT_ASSIGNED)
|
|
assigned_to = models.ForeignKey(User,
|
|
on_delete=models.SET_NULL,
|
|
verbose_name=gettext_lazy('Assigned'),
|
|
help_text=gettext_lazy('User assigned to resolve incident'),
|
|
null=True,
|
|
blank=True)
|
|
event_count = IntegerField(min_value=1,
|
|
verbose_name=gettext_lazy("Event's number"),
|
|
help_text=gettext_lazy("Amount of events in the incident"))
|
|
created = models.DateTimeField(auto_now_add=True,
|
|
verbose_name=gettext_lazy('Created'),
|
|
help_text=gettext_lazy('Date and time, when incident was created'))
|
|
updated = models.DateTimeField(auto_now=True,
|
|
verbose_name=gettext_lazy('Updated'),
|
|
help_text=gettext_lazy('Date and time, when incident was updated'))
|
|
description = models.TextField(verbose_name=gettext_lazy('Description'),
|
|
help_text=gettext_lazy('Incident description'),
|
|
null=True,
|
|
blank=True)
|
|
deadline = models.DateField(verbose_name=gettext_lazy('Deadline'),
|
|
help_text=gettext_lazy("Deadline when incident must be resolved"),
|
|
null=True,
|
|
blank=True)
|
|
comment = models.TextField(verbose_name=gettext_lazy('Comment'),
|
|
help_text=gettext_lazy('Incident comment'),
|
|
null=True,
|
|
blank=True)
|
|
close_recommendations = models.ManyToManyField(IncidentRecommendations,
|
|
verbose_name=gettext_lazy('Resolve recommendations'),
|
|
help_text=gettext_lazy('How to resolve the incident'),
|
|
blank=True)
|
|
effects = models.ManyToManyField(IncidentEffect,
|
|
verbose_name=pgettext_lazy('as consequences', 'Effects'),
|
|
help_text=gettext_lazy('Consequences of the incident'),
|
|
blank=True)
|
|
events = models.JSONField(verbose_name=gettext_lazy("Events"),
|
|
help_text=gettext_lazy("List of events, related to incident"))
|
|
|
|
def save(self, *args, **kwargs):
|
|
if self._state.adding:
|
|
self.user_friendly_id = get_next_value('incidents_user_friendly_id')
|
|
else:
|
|
self.user_friendly_id = self.user_friendly_id
|
|
if self.assigned_to is not None and self.status < self.Status.ASSIGNED:
|
|
self.status = self.Status.ASSIGNED
|
|
if self.assigned_to is None and self.status <= self.Status.ASSIGNED:
|
|
self.status = self.Status.NOT_ASSIGNED
|
|
super(Incident, self).save(*args, **kwargs)
|
|
|
|
def get_absolute_url(self):
|
|
return reverse('incident_view', kwargs={'incident_id': self.incident_id})
|
|
|
|
class Meta:
|
|
ordering = ['-timestamp']
|