@@ -0,0 +1,56 @@
|
||||
import math
|
||||
from datetime import timedelta
|
||||
from django.utils import timezone
|
||||
from rest_framework import serializers
|
||||
KINDS=['metric','flower-status','collector-status','worker-online','worker-offline','worker-heartbeat','task-sent','task-received','task-started','task-succeeded','task-failed','task-retried','task-revoked','task-rejected']
|
||||
class MetricPayload(serializers.Serializer):
|
||||
cpu=serializers.FloatField(min_value=0,max_value=100)
|
||||
ram=serializers.FloatField(min_value=0,max_value=100)
|
||||
disk=serializers.FloatField(min_value=0,max_value=100)
|
||||
boot_id=serializers.CharField(max_length=100,required=False)
|
||||
services=serializers.DictField(child=serializers.BooleanField(),required=False)
|
||||
outbox=serializers.IntegerField(min_value=0,required=False)
|
||||
class WorkerPayload(serializers.Serializer):
|
||||
hostname=serializers.CharField(max_length=255)
|
||||
active=serializers.IntegerField(min_value=0,required=False,default=0)
|
||||
processed=serializers.IntegerField(min_value=0,required=False,default=0)
|
||||
class TaskPayload(serializers.Serializer):
|
||||
uuid=serializers.CharField(max_length=200)
|
||||
name=serializers.CharField(max_length=255,required=False,allow_blank=True)
|
||||
hostname=serializers.CharField(max_length=255,required=False,allow_blank=True)
|
||||
runtime=serializers.FloatField(min_value=0,required=False,allow_null=True)
|
||||
retries=serializers.IntegerField(min_value=0,required=False,default=0)
|
||||
class StatusPayload(serializers.Serializer):
|
||||
online=serializers.BooleanField()
|
||||
checked_at=serializers.DateTimeField(required=False)
|
||||
class Envelope(serializers.Serializer):
|
||||
id=serializers.UUIDField()
|
||||
kind=serializers.ChoiceField(choices=KINDS)
|
||||
occurred_at=serializers.DateTimeField()
|
||||
payload=serializers.DictField()
|
||||
def validate(self,data):
|
||||
if data['occurred_at']>timezone.now()+timedelta(minutes=5):
|
||||
raise serializers.ValidationError('Zeitstempel liegt zu weit in der Zukunft')
|
||||
cls=MetricPayload if data['kind']=='metric' else WorkerPayload if data['kind'].startswith('worker-') else TaskPayload if data['kind'].startswith('task-') else StatusPayload
|
||||
s=cls(data=data['payload']); s.is_valid(raise_exception=True)
|
||||
for field in ('cpu','ram','disk','runtime'):
|
||||
value=s.validated_data.get(field)
|
||||
if value is not None and not math.isfinite(value):
|
||||
raise serializers.ValidationError('Messwerte müssen endlich sein')
|
||||
services=s.validated_data.get('services',{})
|
||||
if len(services)>20 or any(len(k)>50 for k in services):
|
||||
raise serializers.ValidationError('Maximal 20 Dienste mit Namen bis 50 Zeichen')
|
||||
# Use normalized validated values, never the original loosely typed input.
|
||||
normalized=dict(s.data)
|
||||
if any(isinstance(v,float) and not math.isfinite(v) for v in normalized.values()):
|
||||
raise serializers.ValidationError('Messwerte müssen endlich sein')
|
||||
data['payload']={key:value for key,value in normalized.items() if key in data['payload']}
|
||||
return data
|
||||
class Batch(serializers.Serializer):
|
||||
events=Envelope(many=True,allow_empty=False,max_length=500)
|
||||
class ConfigurationSerializer(serializers.Serializer):
|
||||
retention_days=serializers.IntegerField(min_value=7,max_value=3650)
|
||||
heartbeat_timeout=serializers.IntegerField(min_value=30,max_value=3600)
|
||||
cpu_warning=serializers.IntegerField(min_value=1,max_value=100)
|
||||
ram_warning=serializers.IntegerField(min_value=1,max_value=100)
|
||||
disk_warning=serializers.IntegerField(min_value=1,max_value=100)
|
||||
Reference in New Issue
Block a user