""" Serializers for Automation & Orchestration models """ from rest_framework import serializers from django.contrib.auth import get_user_model from ..models import ( Runbook, RunbookExecution, Integration, ChatOpsIntegration, ChatOpsCommand, AutoRemediation, AutoRemediationExecution, MaintenanceWindow, WorkflowTemplate, WorkflowExecution, ) User = get_user_model() class RunbookSerializer(serializers.ModelSerializer): """Serializer for Runbook model""" created_by_username = serializers.CharField(source='created_by.username', read_only=True) last_modified_by_username = serializers.CharField(source='last_modified_by.username', read_only=True) can_trigger = serializers.SerializerMethodField() class Meta: model = Runbook fields = [ 'id', 'name', 'description', 'version', 'trigger_type', 'trigger_conditions', 'steps', 'estimated_duration', 'category', 'tags', 'status', 'is_public', 'created_by', 'created_by_username', 'last_modified_by', 'last_modified_by_username', 'execution_count', 'success_rate', 'created_at', 'updated_at', 'last_executed_at', 'can_trigger' ] read_only_fields = [ 'id', 'created_by_username', 'last_modified_by_username', 'execution_count', 'success_rate', 'created_at', 'updated_at', 'last_executed_at', 'can_trigger' ] def get_can_trigger(self, obj): """Check if current user can trigger this runbook""" request = self.context.get('request') if request and request.user: return obj.can_be_triggered_by(request.user) return False def validate_steps(self, value): """Validate runbook steps""" if not isinstance(value, list): raise serializers.ValidationError("Steps must be a list") for i, step in enumerate(value): if not isinstance(step, dict): raise serializers.ValidationError(f"Step {i+1} must be a dictionary") required_fields = ['name', 'action', 'timeout'] for field in required_fields: if field not in step: raise serializers.ValidationError(f"Step {i+1} missing required field: {field}") return value class RunbookExecutionSerializer(serializers.ModelSerializer): """Serializer for RunbookExecution model""" runbook_name = serializers.CharField(source='runbook.name', read_only=True) triggered_by_username = serializers.CharField(source='triggered_by.username', read_only=True) incident_title = serializers.CharField(source='incident.title', read_only=True) is_running = serializers.BooleanField(read_only=True) is_completed = serializers.BooleanField(read_only=True) class Meta: model = RunbookExecution fields = [ 'id', 'runbook', 'runbook_name', 'triggered_by', 'triggered_by_username', 'trigger_type', 'trigger_data', 'incident', 'incident_title', 'status', 'current_step', 'total_steps', 'execution_log', 'error_message', 'output_data', 'started_at', 'completed_at', 'duration', 'is_running', 'is_completed' ] read_only_fields = [ 'id', 'runbook_name', 'triggered_by_username', 'incident_title', 'is_running', 'is_completed', 'started_at', 'completed_at', 'duration' ] class IntegrationSerializer(serializers.ModelSerializer): """Serializer for Integration model""" created_by_username = serializers.CharField(source='created_by.username', read_only=True) is_healthy = serializers.BooleanField(read_only=True) class Meta: model = Integration fields = [ 'id', 'name', 'integration_type', 'description', 'configuration', 'authentication_config', 'status', 'last_health_check', 'health_status', 'error_message', 'request_count', 'last_used_at', 'created_by', 'created_by_username', 'created_at', 'updated_at', 'is_healthy' ] read_only_fields = [ 'id', 'created_by_username', 'last_health_check', 'health_status', 'error_message', 'request_count', 'last_used_at', 'created_at', 'updated_at', 'is_healthy' ] def validate_configuration(self, value): """Validate integration configuration""" if not isinstance(value, dict): raise serializers.ValidationError("Configuration must be a dictionary") return value def validate_authentication_config(self, value): """Validate authentication configuration""" if not isinstance(value, dict): raise serializers.ValidationError("Authentication configuration must be a dictionary") return value class ChatOpsIntegrationSerializer(serializers.ModelSerializer): """Serializer for ChatOpsIntegration model""" created_by_username = serializers.CharField(source='created_by.username', read_only=True) class Meta: model = ChatOpsIntegration fields = [ 'id', 'name', 'platform', 'webhook_url', 'bot_token', 'channel_id', 'command_prefix', 'available_commands', 'allowed_users', 'allowed_channels', 'is_active', 'last_activity', 'created_by', 'created_by_username', 'created_at', 'updated_at' ] read_only_fields = [ 'id', 'created_by_username', 'last_activity', 'created_at', 'updated_at' ] def validate_available_commands(self, value): """Validate available commands""" if not isinstance(value, list): raise serializers.ValidationError("Available commands must be a list") for i, command in enumerate(value): if not isinstance(command, dict): raise serializers.ValidationError(f"Command {i+1} must be a dictionary") required_fields = ['name', 'description'] for field in required_fields: if field not in command: raise serializers.ValidationError(f"Command {i+1} missing required field: {field}") return value class ChatOpsCommandSerializer(serializers.ModelSerializer): """Serializer for ChatOpsCommand model""" chatops_integration_name = serializers.CharField(source='chatops_integration.name', read_only=True) triggered_runbook_name = serializers.CharField(source='triggered_runbook.name', read_only=True) related_incident_title = serializers.CharField(source='related_incident.title', read_only=True) class Meta: model = ChatOpsCommand fields = [ 'id', 'chatops_integration', 'chatops_integration_name', 'command', 'arguments', 'user_id', 'channel_id', 'triggered_runbook', 'triggered_runbook_name', 'related_incident', 'related_incident_title', 'status', 'response_message', 'execution_log', 'error_message', 'executed_at', 'completed_at' ] read_only_fields = [ 'id', 'chatops_integration_name', 'triggered_runbook_name', 'related_incident_title', 'executed_at', 'completed_at' ] class AutoRemediationSerializer(serializers.ModelSerializer): """Serializer for AutoRemediation model""" created_by_username = serializers.CharField(source='created_by.username', read_only=True) approval_users_usernames = serializers.SerializerMethodField() success_rate = serializers.FloatField(read_only=True) class Meta: model = AutoRemediation fields = [ 'id', 'name', 'description', 'remediation_type', 'trigger_conditions', 'trigger_condition_type', 'remediation_config', 'timeout_seconds', 'requires_approval', 'approval_users', 'approval_users_usernames', 'max_executions_per_incident', 'is_active', 'created_by', 'created_by_username', 'created_at', 'updated_at', 'execution_count', 'success_count', 'last_executed_at', 'success_rate' ] read_only_fields = [ 'id', 'created_by_username', 'approval_users_usernames', 'created_at', 'updated_at', 'execution_count', 'success_count', 'last_executed_at', 'success_rate' ] def get_approval_users_usernames(self, obj): """Get usernames of approval users""" return [user.username for user in obj.approval_users.all()] class AutoRemediationExecutionSerializer(serializers.ModelSerializer): """Serializer for AutoRemediationExecution model""" auto_remediation_name = serializers.CharField(source='auto_remediation.name', read_only=True) incident_title = serializers.CharField(source='incident.title', read_only=True) approved_by_username = serializers.CharField(source='approved_by.username', read_only=True) class Meta: model = AutoRemediationExecution fields = [ 'id', 'auto_remediation', 'auto_remediation_name', 'incident', 'incident_title', 'status', 'trigger_data', 'approved_by', 'approved_by_username', 'approved_at', 'approval_notes', 'execution_log', 'output_data', 'error_message', 'triggered_at', 'started_at', 'completed_at', 'duration' ] read_only_fields = [ 'id', 'auto_remediation_name', 'incident_title', 'approved_by_username', 'triggered_at', 'started_at', 'completed_at', 'duration' ] class MaintenanceWindowSerializer(serializers.ModelSerializer): """Serializer for MaintenanceWindow model""" created_by_username = serializers.CharField(source='created_by.username', read_only=True) is_active = serializers.BooleanField(read_only=True) is_scheduled = serializers.BooleanField(read_only=True) class Meta: model = MaintenanceWindow fields = [ 'id', 'name', 'description', 'start_time', 'end_time', 'timezone', 'affected_services', 'affected_components', 'suppress_incident_creation', 'suppress_notifications', 'suppress_escalations', 'status', 'created_by', 'created_by_username', 'created_at', 'updated_at', 'incidents_suppressed', 'notifications_suppressed', 'is_active', 'is_scheduled' ] read_only_fields = [ 'id', 'created_by_username', 'created_at', 'updated_at', 'incidents_suppressed', 'notifications_suppressed', 'is_active', 'is_scheduled' ] def validate(self, data): """Validate maintenance window data""" if data.get('start_time') and data.get('end_time'): if data['start_time'] >= data['end_time']: raise serializers.ValidationError("Start time must be before end time") return data class WorkflowTemplateSerializer(serializers.ModelSerializer): """Serializer for WorkflowTemplate model""" created_by_username = serializers.CharField(source='created_by.username', read_only=True) class Meta: model = WorkflowTemplate fields = [ 'id', 'name', 'description', 'template_type', 'workflow_steps', 'input_parameters', 'output_schema', 'usage_count', 'is_public', 'created_by', 'created_by_username', 'created_at', 'updated_at' ] read_only_fields = [ 'id', 'created_by_username', 'usage_count', 'created_at', 'updated_at' ] def validate_workflow_steps(self, value): """Validate workflow steps""" if not isinstance(value, list): raise serializers.ValidationError("Workflow steps must be a list") for i, step in enumerate(value): if not isinstance(step, dict): raise serializers.ValidationError(f"Step {i+1} must be a dictionary") required_fields = ['name', 'action', 'conditions'] for field in required_fields: if field not in step: raise serializers.ValidationError(f"Step {i+1} missing required field: {field}") return value class WorkflowExecutionSerializer(serializers.ModelSerializer): """Serializer for WorkflowExecution model""" workflow_template_name = serializers.CharField(source='workflow_template.name', read_only=True) triggered_by_username = serializers.CharField(source='triggered_by.username', read_only=True) related_incident_title = serializers.CharField(source='related_incident.title', read_only=True) related_maintenance_name = serializers.CharField(source='related_maintenance.name', read_only=True) class Meta: model = WorkflowExecution fields = [ 'id', 'workflow_template', 'workflow_template_name', 'name', 'triggered_by', 'triggered_by_username', 'trigger_type', 'related_incident', 'related_incident_title', 'related_maintenance', 'related_maintenance_name', 'status', 'current_step', 'total_steps', 'input_data', 'output_data', 'execution_log', 'error_message', 'started_at', 'completed_at', 'duration' ] read_only_fields = [ 'id', 'workflow_template_name', 'triggered_by_username', 'related_incident_title', 'related_maintenance_name', 'started_at', 'completed_at', 'duration' ]