Backend (Django 4.2 + DRF): - Admin auth with SimpleJWT - Volcengine API client with HMAC-SHA256 signing - IAM user management (create/sync/import/disable/enable) - Billing query with pagination - Feishu webhook notifications (async) - APScheduler for periodic spending checks - AES-256 encrypted credential storage - API key auth for external system integration Frontend (Vue 3 + Element Plus): - Login page - Dashboard with stats overview - IAM user list with per-user threshold config - Billing view with spending progress bars - Alert history with type filtering - Settings page for global config and Volcengine account management Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
108 lines
4.5 KiB
Python
108 lines
4.5 KiB
Python
from rest_framework import serializers
|
|
from .models import IAMUser, VolcAccount, GlobalConfig, AlertRecord, SpendingRecord
|
|
|
|
|
|
class VolcAccountSerializer(serializers.ModelSerializer):
|
|
class Meta:
|
|
model = VolcAccount
|
|
fields = ['id', 'name', 'access_key_hint', 'is_active', 'created_at', 'updated_at']
|
|
read_only_fields = ['access_key_hint', 'created_at', 'updated_at']
|
|
|
|
|
|
class VolcAccountCreateSerializer(serializers.Serializer):
|
|
name = serializers.CharField(max_length=100, default='默认主账号')
|
|
access_key = serializers.CharField(write_only=True)
|
|
secret_key = serializers.CharField(write_only=True)
|
|
|
|
|
|
class IAMUserSerializer(serializers.ModelSerializer):
|
|
effective_alert_threshold = serializers.SerializerMethodField()
|
|
effective_disable_threshold = serializers.SerializerMethodField()
|
|
|
|
class Meta:
|
|
model = IAMUser
|
|
fields = [
|
|
'id', 'username', 'display_name', 'user_id', 'email', 'phone',
|
|
'project_name', 'status', 'access_key_ids',
|
|
'monitor_enabled', 'auto_disable_enabled',
|
|
'alert_threshold', 'disable_threshold',
|
|
'effective_alert_threshold', 'effective_disable_threshold',
|
|
'current_month_spending', 'spending_updated_at',
|
|
'remark', 'created_at', 'updated_at',
|
|
]
|
|
read_only_fields = ['user_id', 'access_key_ids', 'status',
|
|
'current_month_spending', 'spending_updated_at',
|
|
'created_at', 'updated_at']
|
|
|
|
def get_effective_alert_threshold(self, obj):
|
|
return str(obj.get_alert_threshold())
|
|
|
|
def get_effective_disable_threshold(self, obj):
|
|
return str(obj.get_disable_threshold())
|
|
|
|
|
|
class IAMUserCreateSerializer(serializers.Serializer):
|
|
username = serializers.CharField(max_length=200)
|
|
display_name = serializers.CharField(max_length=200, required=False, default='')
|
|
email = serializers.EmailField(required=False, default='')
|
|
phone = serializers.CharField(max_length=20, required=False, default='')
|
|
password = serializers.CharField(write_only=True, required=False, default='')
|
|
project_name = serializers.CharField(max_length=200, required=False, default='')
|
|
alert_threshold = serializers.DecimalField(max_digits=12, decimal_places=2,
|
|
required=False, allow_null=True)
|
|
disable_threshold = serializers.DecimalField(max_digits=12, decimal_places=2,
|
|
required=False, allow_null=True)
|
|
|
|
|
|
class IAMUserImportSerializer(serializers.Serializer):
|
|
username = serializers.CharField(max_length=200, help_text='已存在的 IAM 用户名')
|
|
|
|
|
|
class IAMUserThresholdSerializer(serializers.Serializer):
|
|
alert_threshold = serializers.DecimalField(max_digits=12, decimal_places=2,
|
|
required=False, allow_null=True)
|
|
disable_threshold = serializers.DecimalField(max_digits=12, decimal_places=2,
|
|
required=False, allow_null=True)
|
|
monitor_enabled = serializers.BooleanField(required=False)
|
|
auto_disable_enabled = serializers.BooleanField(required=False)
|
|
|
|
|
|
class GlobalConfigSerializer(serializers.ModelSerializer):
|
|
class Meta:
|
|
model = GlobalConfig
|
|
fields = [
|
|
'default_alert_threshold', 'default_disable_threshold',
|
|
'monitor_interval_seconds',
|
|
'feishu_webhook_url', 'feishu_alert_mobiles',
|
|
'updated_at',
|
|
]
|
|
read_only_fields = ['updated_at']
|
|
|
|
|
|
class AlertRecordSerializer(serializers.ModelSerializer):
|
|
iam_username = serializers.CharField(source='iam_user.username', default='')
|
|
|
|
class Meta:
|
|
model = AlertRecord
|
|
fields = [
|
|
'id', 'iam_user', 'iam_username', 'alert_type', 'title', 'content',
|
|
'spending_amount', 'threshold_amount', 'notified', 'created_at',
|
|
]
|
|
|
|
|
|
class SpendingRecordSerializer(serializers.ModelSerializer):
|
|
iam_username = serializers.CharField(source='iam_user.username')
|
|
|
|
class Meta:
|
|
model = SpendingRecord
|
|
fields = ['id', 'iam_user', 'iam_username', 'bill_period', 'amount', 'updated_at']
|
|
|
|
|
|
class DashboardSerializer(serializers.Serializer):
|
|
total_users = serializers.IntegerField()
|
|
active_users = serializers.IntegerField()
|
|
disabled_users = serializers.IntegerField()
|
|
monitored_users = serializers.IntegerField()
|
|
total_spending = serializers.DecimalField(max_digits=12, decimal_places=2)
|
|
recent_alerts = AlertRecordSerializer(many=True)
|