101 lines
4.9 KiB
Python
101 lines
4.9 KiB
Python
import uuid
|
|
from django.conf import settings
|
|
from django.db import models
|
|
from django.db.models import Q
|
|
class Segment(models.Model):
|
|
name=models.CharField(max_length=100,unique=True)
|
|
cidr=models.CharField(max_length=100,blank=True)
|
|
def __str__(self): return self.name
|
|
class Server(models.Model):
|
|
id=models.UUIDField(primary_key=True,default=uuid.uuid4,editable=False)
|
|
name=models.CharField(max_length=150,unique=True)
|
|
segment=models.ForeignKey(Segment,on_delete=models.PROTECT)
|
|
address=models.CharField(max_length=255,blank=True)
|
|
enabled=models.BooleanField(default=True)
|
|
maintenance=models.BooleanField(default=False)
|
|
last_seen=models.DateTimeField(null=True,blank=True)
|
|
latest_sample_at=models.DateTimeField(null=True,blank=True)
|
|
latest=models.JSONField(default=dict,blank=True)
|
|
created_at=models.DateTimeField(auto_now_add=True)
|
|
def __str__(self): return self.name
|
|
class AgentCredential(models.Model):
|
|
server=models.ForeignKey(Server,on_delete=models.CASCADE)
|
|
digest=models.CharField(max_length=64,unique=True)
|
|
label=models.CharField(max_length=100,default='agent')
|
|
active=models.BooleanField(default=True)
|
|
created_at=models.DateTimeField(auto_now_add=True)
|
|
class AccessToken(models.Model):
|
|
user=models.ForeignKey(settings.AUTH_USER_MODEL,on_delete=models.CASCADE)
|
|
digest=models.CharField(max_length=64,unique=True)
|
|
expires_at=models.DateTimeField(db_index=True)
|
|
class Event(models.Model):
|
|
id=models.UUIDField(primary_key=True)
|
|
server=models.ForeignKey(Server,on_delete=models.CASCADE)
|
|
kind=models.CharField(max_length=50,db_index=True)
|
|
occurred_at=models.DateTimeField(db_index=True)
|
|
received_at=models.DateTimeField(auto_now_add=True,db_index=True)
|
|
payload=models.JSONField(default=dict)
|
|
class Meta:
|
|
indexes=[models.Index(fields=['server','occurred_at']),models.Index(fields=['server','kind','occurred_at'])]
|
|
class Metric(models.Model):
|
|
event=models.OneToOneField(Event,on_delete=models.CASCADE,primary_key=True)
|
|
server=models.ForeignKey(Server,on_delete=models.CASCADE)
|
|
at=models.DateTimeField(db_index=True)
|
|
cpu=models.FloatField()
|
|
ram=models.FloatField()
|
|
disk=models.FloatField()
|
|
class Meta:
|
|
indexes=[models.Index(fields=['server','at'])]
|
|
class Worker(models.Model):
|
|
server=models.ForeignKey(Server,on_delete=models.CASCADE)
|
|
hostname=models.CharField(max_length=255)
|
|
last_seen=models.DateTimeField()
|
|
online=models.BooleanField(default=True)
|
|
active=models.IntegerField(default=0)
|
|
processed=models.BigIntegerField(default=0)
|
|
class Meta:
|
|
constraints=[models.UniqueConstraint(fields=['server','hostname'],name='unique_worker_per_collector')]
|
|
class Task(models.Model):
|
|
server=models.ForeignKey(Server,on_delete=models.CASCADE)
|
|
task_id=models.CharField(max_length=200)
|
|
name=models.CharField(max_length=255,blank=True)
|
|
worker=models.CharField(max_length=255,blank=True)
|
|
state=models.CharField(max_length=30)
|
|
first_at=models.DateTimeField()
|
|
last_at=models.DateTimeField(db_index=True)
|
|
runtime=models.FloatField(null=True,blank=True)
|
|
retries=models.IntegerField(default=0)
|
|
class Meta:
|
|
constraints=[models.UniqueConstraint(fields=['server','task_id'],name='unique_task_per_collector')]
|
|
indexes=[models.Index(fields=['server','last_at'])]
|
|
class Alarm(models.Model):
|
|
server=models.ForeignKey(Server,on_delete=models.CASCADE)
|
|
code=models.CharField(max_length=80)
|
|
severity=models.CharField(max_length=20,default='warning')
|
|
message=models.CharField(max_length=400)
|
|
opened_at=models.DateTimeField(auto_now_add=True)
|
|
resolved_at=models.DateTimeField(null=True,blank=True)
|
|
acknowledged_at=models.DateTimeField(null=True,blank=True)
|
|
acknowledged_by=models.ForeignKey(settings.AUTH_USER_MODEL,null=True,blank=True,on_delete=models.SET_NULL)
|
|
class Meta:
|
|
constraints=[models.UniqueConstraint(fields=['server','code'],condition=Q(resolved_at__isnull=True),name='one_open_alarm')]
|
|
class Notification(models.Model):
|
|
alarm=models.OneToOneField(Alarm,on_delete=models.CASCADE)
|
|
sent_at=models.DateTimeField(null=True,blank=True)
|
|
attempts=models.IntegerField(default=0)
|
|
next_attempt=models.DateTimeField()
|
|
last_error=models.CharField(max_length=100,blank=True)
|
|
class Configuration(models.Model):
|
|
id=models.PositiveSmallIntegerField(primary_key=True,default=1,editable=False)
|
|
retention_days=models.PositiveIntegerField(default=90)
|
|
heartbeat_timeout=models.PositiveIntegerField(default=60)
|
|
cpu_warning=models.PositiveIntegerField(default=85)
|
|
ram_warning=models.PositiveIntegerField(default=90)
|
|
disk_warning=models.PositiveIntegerField(default=90)
|
|
updated_at=models.DateTimeField(auto_now=True)
|
|
class Audit(models.Model):
|
|
at=models.DateTimeField(auto_now_add=True)
|
|
actor=models.CharField(max_length=150)
|
|
action=models.CharField(max_length=200)
|
|
details=models.JSONField(default=dict)
|