| """ |
| ATOM Enterprise Workflow Automation Service |
| Comprehensive workflow automation integrating all enterprise services with intelligent automation |
| """ |
|
|
| import asyncio |
| from collections import Counter, defaultdict |
| from dataclasses import asdict, dataclass |
| from datetime import datetime, timedelta, timezone |
| from enum import Enum |
| import hashlib |
| import json |
| import logging |
| import os |
| import time |
| from typing import Any, Callable, Dict, List, Optional, Tuple, Union |
| import aiohttp |
| import httpx |
| import numpy as np |
| import pandas as pd |
| from core.circuit_breaker import circuit_breaker |
| from core.rate_limiter import rate_limiter, should_retry, calculate_backoff |
| from core.audit_logger import log_integration_call, log_integration_error, log_integration_attempt, log_integration_complete |
| from fastapi import HTTPException |
|
|
|
|
| |
| logger = logging.getLogger(__name__) |
|
|
| |
| try: |
| from ai_enhanced_service import ( |
| AIModelType, |
| AIRequest, |
| AIResponse, |
| AIServiceType, |
| AITaskType, |
| ai_enhanced_service, |
| ) |
| except ImportError: |
| logger.debug("ai_enhanced_service not available") |
| ai_enhanced_service = None |
| AIModelType = None |
| AIRequest = None |
| AIResponse = None |
| AIServiceType = None |
| AITaskType = None |
|
|
| try: |
| from atom_ai_integration import atom_ai_integration |
| except ImportError: |
| logger.debug("atom_ai_integration not available") |
| atom_ai_integration = None |
|
|
| try: |
| from atom_discord_integration import atom_discord_integration |
| except ImportError: |
| logger.debug("atom_discord_integration not available") |
| atom_discord_integration = None |
|
|
| try: |
| from atom_enterprise_security_service import ( |
| AuditEventType, |
| ComplianceReport, |
| ComplianceStandard, |
| SecurityAudit, |
| SecurityLevel, |
| SecurityPolicy, |
| ThreatDetection, |
| ThreatType, |
| atom_enterprise_security_service, |
| ) |
| except ImportError: |
| logger.debug("atom_enterprise_security_service not available") |
| atom_enterprise_security_service = None |
| AuditEventType = None |
| ComplianceReport = None |
| ComplianceStandard = None |
| SecurityAudit = None |
| SecurityLevel = None |
| SecurityPolicy = None |
| ThreatDetection = None |
| ThreatType = None |
|
|
| try: |
| from atom_enterprise_unified_service import ( |
| AutomationTriggerType, |
| ComplianceAutomation, |
| ComplianceWorkflowType, |
| EnterpriseServiceType, |
| EnterpriseWorkflow, |
| SecurityWorkflowAction, |
| WorkflowSecurityLevel, |
| atom_enterprise_unified_service, |
| ) |
| except ImportError: |
| logger.debug("atom_enterprise_unified_service not available") |
| atom_enterprise_unified_service = None |
| AutomationTriggerType = None |
| ComplianceAutomation = None |
| ComplianceWorkflowType = None |
| EnterpriseServiceType = None |
| EnterpriseWorkflow = None |
| SecurityWorkflowAction = None |
| WorkflowSecurityLevel = None |
|
|
| try: |
| from atom_google_chat_integration import atom_google_chat_integration |
| except ImportError: |
| logger.debug("atom_google_chat_integration not available") |
| atom_google_chat_integration = None |
|
|
| try: |
| from atom_ingestion_pipeline import AtomIngestionPipeline |
| except ImportError: |
| logger.debug("AtomIngestionPipeline not available") |
| AtomIngestionPipeline = None |
|
|
| try: |
| from atom_memory_service import AtomMemoryService |
| except ImportError: |
| logger.debug("AtomMemoryService not available") |
| AtomMemoryService = None |
|
|
| try: |
| from atom_search_service import AtomSearchService |
| except ImportError: |
| logger.debug("AtomSearchService not available") |
| AtomSearchService = None |
|
|
| try: |
| from atom_slack_integration import atom_slack_integration |
| except ImportError: |
| logger.debug("atom_slack_integration not available") |
| atom_slack_integration = None |
|
|
| try: |
| from atom_teams_integration import atom_teams_integration |
| except ImportError: |
| logger.debug("atom_teams_integration not available") |
| atom_teams_integration = None |
|
|
| try: |
| from atom_workflow_service import ( |
| AtomWorkflowService, |
| Workflow, |
| WorkflowAction, |
| WorkflowStatus, |
| WorkflowStep, |
| WorkflowTrigger, |
| ) |
| except ImportError: |
| logger.debug("atom_workflow_service not available") |
| AtomWorkflowService = None |
| Workflow = None |
| WorkflowAction = None |
| WorkflowStatus = None |
| WorkflowStep = None |
| WorkflowTrigger = None |
|
|
| class WorkflowAutomationType(Enum): |
| """Workflow automation types""" |
| SECURITY = "security" |
| COMPLIANCE = "compliance" |
| GOVERNANCE = "governance" |
| MONITORING = "monitoring" |
| AUDITING = "auditing" |
| INCIDENT_RESPONSE = "incident_response" |
| RISK_MANAGEMENT = "risk_management" |
| DATA_PROTECTION = "data_protection" |
| ACCESS_CONTROL = "access_control" |
| USER_MANAGEMENT = "user_management" |
| RESOURCE_MANAGEMENT = "resource_management" |
| NOTIFICATION = "notification" |
| REPORTING = "reporting" |
| INTEGRATION = "integration" |
|
|
| class AutomationConditionType(Enum): |
| """Automation condition types""" |
| EVENT_TRIGGERED = "event_triggered" |
| SCHEDULED = "scheduled" |
| THRESHOLD_EXCEEDED = "threshold_exceeded" |
| ANOMALY_DETECTED = "anomaly_detected" |
| MANUAL = "manual" |
| WEBHOOK = "webhook" |
| API_CALLED = "api_called" |
| SYSTEM_EVENT = "system_event" |
| USER_ACTION = "user_action" |
| DATA_CHANGED = "data_changed" |
| SECURITY_ALERT = "security_alert" |
| COMPLIANCE_VIOLATION = "compliance_violation" |
|
|
| class AutomationActionType(Enum): |
| """Automation action types""" |
| NOTIFICATION = "notification" |
| WORKFLOW_EXECUTION = "workflow_execution" |
| SECURITY_ENFORCEMENT = "security_enforcement" |
| COMPLIANCE_CHECK = "compliance_check" |
| DATA_PROCESSING = "data_processing" |
| USER_ACTION = "user_action" |
| SYSTEM_CONFIG = "system_config" |
| API_CALL = "api_call" |
| EMAIL_SEND = "email_send" |
| MESSAGE_SEND = "message_send" |
| FILE_OPERATION = "file_operation" |
| DATABASE_OPERATION = "database_operation" |
| LOGGING = "logging" |
| AUDITING = "auditing" |
| REPORTING = "reporting" |
| REMEDIATION = "remediation" |
|
|
| class AutomationPriority(Enum): |
| """Automation priority levels""" |
| CRITICAL = "critical" |
| HIGH = "high" |
| MEDIUM = "medium" |
| LOW = "low" |
| INFO = "info" |
|
|
| class AutomationStatus(Enum): |
| """Automation status""" |
| ACTIVE = "active" |
| INACTIVE = "inactive" |
| PAUSED = "paused" |
| SUSPENDED = "suspended" |
| ERROR = "error" |
| COMPLETED = "completed" |
| RUNNING = "running" |
| PENDING = "pending" |
| FAILED = "failed" |
|
|
| @dataclass |
| class WorkflowAutomation: |
| """Workflow automation data model""" |
| automation_id: str |
| name: str |
| description: str |
| automation_type: WorkflowAutomationType |
| priority: AutomationPriority |
| status: AutomationStatus |
| conditions: List[Dict[str, Any]] |
| actions: List[Dict[str, Any]] |
| schedule: Optional[str] |
| created_at: datetime |
| updated_at: datetime |
| created_by: str |
| last_executed: Optional[datetime] |
| execution_count: int |
| success_count: int |
| failure_count: int |
| timeout: int |
| retry_policy: Dict[str, Any] |
| notification_rules: List[Dict[str, Any]] |
| metadata: Dict[str, Any] |
| audit_trail: List[Dict[str, Any]] |
|
|
| @dataclass |
| class AutomationExecution: |
| """Automation execution data model""" |
| execution_id: str |
| automation_id: str |
| triggered_by: str |
| trigger_context: Dict[str, Any] |
| status: AutomationStatus |
| started_at: datetime |
| completed_at: Optional[datetime] |
| execution_time: float |
| result: Dict[str, Any] |
| error: Optional[str] |
| actions_executed: List[Dict[str, Any]] |
| notifications_sent: List[Dict[str, Any]] |
| compliance_checks: List[Dict[str, Any]] |
| security_checks: List[Dict[str, Any]] |
| metadata: Dict[str, Any] |
|
|
| |
| class AtomWorkflowAutomationService: |
| """Enterprise workflow automation service with comprehensive integration""" |
| |
| def __init__(self, tenant_id: str = "default", config: Dict[str, Any] = None): |
| if config is None: |
| config = {} |
| self.config = config |
| self.db = config.get('database') |
| self.cache = config.get('cache') |
| |
| |
| self.security_service = config.get('security_service') or atom_enterprise_security_service |
| self.unified_service = config.get('unified_service') or atom_enterprise_unified_service |
| self.workflow_service = config.get('workflow_service') |
| self.ai_service = config.get('ai_service') or ai_enhanced_service |
| self.ai_integration = config.get('ai_integration') or atom_ai_integration |
| |
| |
| self.platform_integrations = { |
| 'slack': atom_slack_integration, |
| 'teams': atom_teams_integration, |
| 'google_chat': atom_google_chat_integration, |
| 'discord': atom_discord_integration |
| } |
| |
| |
| self.is_initialized = False |
| self.automations: Dict[str, WorkflowAutomation] = {} |
| self.executions: Dict[str, AutomationExecution] = {} |
| self.scheduled_automations: Dict[str, Dict[str, Any]] = {} |
| self.active_triggers: Dict[str, Dict[str, Any]] = {} |
| self.automation_templates: Dict[str, Dict[str, Any]] = {} |
| |
| |
| self.automation_metrics = { |
| 'total_automations': 0, |
| 'active_automations': 0, |
| 'executed_today': 0, |
| 'executed_this_week': 0, |
| 'executed_this_month': 0, |
| 'success_rate': 0.0, |
| 'average_execution_time': 0.0, |
| 'automations_by_type': defaultdict(int), |
| 'automations_by_priority': defaultdict(int), |
| 'executions_by_status': defaultdict(int), |
| 'error_rate': 0.0, |
| 'time_saved_hours': 0.0, |
| 'cost_savings': 0.0 |
| } |
| |
| |
| self.scheduler_running = False |
| self.scheduler_task = None |
| self.trigger_listeners = {} |
| |
| |
| self.http_sessions = {} |
| |
| logger.info("Workflow Automation Service initialized") |
| |
| async def initialize(self) -> bool: |
| """Initialize workflow automation service""" |
| try: |
| if not all([self.security_service, self.unified_service, self.ai_service]): |
| logger.error("Required services not available for workflow automation service") |
| return False |
| |
| |
| await self._initialize_automation_templates() |
| |
| |
| await self._load_automations() |
| |
| |
| await self._initialize_automation_scheduling() |
| |
| |
| await self._initialize_trigger_listeners() |
| |
| |
| await self._initialize_integration_endpoints() |
| |
| |
| await self._start_automation_monitoring() |
| |
| self.is_initialized = True |
| logger.info("Workflow Automation Service initialized successfully") |
| return True |
| |
| except Exception as e: |
| logger.error(f"Error initializing workflow automation service: {e}") |
| return False |
| |
| async def create_automation(self, automation_data: Dict[str, Any], user_id: str) -> Dict[str, Any]: |
| """Create workflow automation""" |
| |
| audit_ctx = log_integration_attempt("atom_workflow_automation", "initialize", locals()) |
| try: |
| |
| if not await circuit_breaker.is_enabled("atom_workflow_automation"): |
| logger.warning(f"Circuit breaker is open for atom_workflow_automation") |
| log_integration_complete(audit_ctx, error=Exception("Circuit breaker open")) |
| raise HTTPException( |
| status_code=503, |
| detail=f"Atom_workflow_automation integration temporarily disabled" |
| ) |
|
|
| |
| is_limited, remaining = await rate_limiter.is_rate_limited("atom_workflow_automation") |
| if is_limited: |
| logger.warning(f"Rate limit exceeded for atom_workflow_automation") |
| log_integration_complete(audit_ctx, error=Exception("Rate limit exceeded")) |
| raise HTTPException( |
| status_code=429, |
| detail=f"Rate limit exceeded for atom_workflow_automation" |
| ) |
|
|
| automation_id = f"auto_{int(time.time())}_{hashlib.md5(automation_data['name'].encode()).hexdigest()[:8]}" |
| |
| validation_result = await self._validate_automation_data(automation_data) |
| if not validation_result['valid']: |
| return { |
| 'ok': False, |
| 'error': f"Automation validation failed: {validation_result['errors']}" |
| } |
| |
| automation = WorkflowAutomation( |
| automation_id=automation_id, |
| name=automation_data['name'], |
| description=automation_data['description'], |
| automation_type=WorkflowAutomationType(automation_data['automation_type']), |
| priority=AutomationPriority(automation_data['priority']), |
| status=AutomationStatus.ACTIVE, |
| conditions=automation_data['conditions'], |
| actions=automation_data['actions'], |
| schedule=automation_data.get('schedule'), |
| created_at=datetime.utcnow(), |
| updated_at=datetime.utcnow(), |
| created_by=user_id, |
| last_executed=None, |
| execution_count=0, |
| success_count=0, |
| failure_count=0, |
| timeout=automation_data.get('timeout', 3600), |
| retry_policy=automation_data.get('retry_policy', { |
| 'max_retries': 3, |
| 'backoff': 'exponential', |
| 'max_delay': 3600 |
| }), |
| notification_rules=automation_data.get('notification_rules', []), |
| metadata=automation_data.get('metadata', {}), |
| audit_trail=[] |
| ) |
| |
| await self._setup_automation_triggers(automation) |
| |
| self.automations[automation_id] = automation |
| |
| if self.db: |
| await self.db.store_workflow_automation(asdict(automation)) |
| |
| self.automation_metrics['total_automations'] += 1 |
| self.automation_metrics['active_automations'] += 1 |
| self.automation_metrics['automations_by_type'][automation.automation_type.value] += 1 |
| self.automation_metrics['automations_by_priority'][automation.priority.value] += 1 |
| |
| await self._log_automation_event( |
| automation_id=automation_id, |
| event_type='automation_created', |
| user_id=user_id, |
| details={ |
| 'automation_name': automation.name, |
| 'automation_type': automation.automation_type.value, |
| 'priority': automation.priority.value |
| } |
| ) |
| return { |
| 'ok': True, |
| 'automation_id': automation_id, |
| 'automation': asdict(automation), |
| 'message': "Workflow automation created successfully" |
| } |
| except Exception as e: |
| logger.error(f"Operation failed: {e}") |
| log_integration_complete(audit_ctx, error=e) |
| logger.error(f"Error creating workflow automation: {e}") |
| return {'ok': False, 'error': str(e)} |
| |
| async def execute_automation(self, automation_id: str, trigger_context: Dict[str, Any], triggered_by: str) -> Dict[str, Any]: |
| """Execute workflow automation""" |
| |
| audit_ctx = log_integration_attempt("atom_workflow_automation", "create_automation", locals()) |
| |
| if not await circuit_breaker.is_enabled("atom_workflow_automation"): |
| logger.warning(f"Circuit breaker is open for atom_workflow_automation") |
| log_integration_complete(audit_ctx, error=Exception("Circuit breaker open")) |
| raise HTTPException( |
| status_code=503, |
| detail=f"Atom_workflow_automation integration temporarily disabled" |
| ) |
| |
| is_limited, remaining = await rate_limiter.is_rate_limited("atom_workflow_automation") |
| if is_limited: |
| logger.warning(f"Rate limit exceeded for atom_workflow_automation") |
| log_integration_complete(audit_ctx, error=Exception("Rate limit exceeded")) |
| raise HTTPException( |
| status_code=429, |
| detail=f"Rate limit exceeded for atom_workflow_automation" |
| ) |
| try: |
| automation = self.automations.get(automation_id) |
| if not automation: |
| return {'ok': False, 'error': 'Automation not found'} |
| |
| if automation.status != AutomationStatus.ACTIVE: |
| return {'ok': False, 'error': 'Automation is not active'} |
| |
| |
| execution_id = f"exec_{int(time.time())}_{hashlib.md5(automation_id.encode()).hexdigest()[:8]}" |
| |
| execution = AutomationExecution( |
| execution_id=execution_id, |
| automation_id=automation_id, |
| triggered_by=triggered_by, |
| trigger_context=trigger_context, |
| status=AutomationStatus.RUNNING, |
| started_at=datetime.utcnow(), |
| completed_at=None, |
| execution_time=0.0, |
| result={}, |
| error=None, |
| actions_executed=[], |
| notifications_sent=[], |
| compliance_checks=[], |
| security_checks=[], |
| metadata={'trigger_context': trigger_context} |
| ) |
| |
| self.executions[execution_id] = execution |
| |
| |
| security_check = await self._pre_execution_security_check(automation, trigger_context) |
| if not security_check['passed']: |
| execution.status = AutomationStatus.FAILED |
| execution.error = f"Security check failed: {security_check['reason']}" |
| execution.security_checks.append(security_check) |
| return { |
| 'ok': False, |
| 'error': execution.error, |
| 'security_violation': security_check |
| } |
| |
| |
| compliance_check = await self._pre_execution_compliance_check(automation, trigger_context) |
| if not compliance_check['passed']: |
| execution.status = AutomationStatus.FAILED |
| execution.error = f"Compliance check failed: {compliance_check['reason']}" |
| execution.compliance_checks.append(compliance_check) |
| return { |
| 'ok': False, |
| 'error': execution.error, |
| 'compliance_violation': compliance_check |
| } |
|
|
| |
| |
| |
| |
| for action in automation.actions: |
| if action.get('type') == 'workflow_execution' or action.get('type') == 'agent_trigger': |
| agent_id = action.get('config', {}).get('agent_id') |
|
|
| if agent_id: |
| from core.trigger_interceptor import TriggerInterceptor, TriggerSource |
|
|
| interceptor = TriggerInterceptor(self.db, self.workspace_id) |
|
|
| trigger_context = { |
| "action_type": action.get('type'), |
| "action_config": action.get('config'), |
| "automation_id": automation_id, |
| "trigger_context": trigger_context |
| } |
|
|
| decision = await interceptor.intercept_trigger( |
| agent_id=agent_id, |
| trigger_source=TriggerSource.WORKFLOW_ENGINE, |
| trigger_context=trigger_context |
| ) |
| |
| logger.info( |
| f"Workflow automation routing decision for agent {agent_id}: " |
| f"{decision.routing_decision.value} (maturity: {decision.agent_maturity}, " |
| f"confidence: {decision.confidence_score:.2f})" |
| ) |
| |
| if not decision.execute: |
| execution.status = AutomationStatus.FAILED |
| execution.error = ( |
| f"Agent action blocked by maturity guard: {decision.reason}" |
| ) |
| execution.metadata['maturity_check'] = { |
| 'agent_id': agent_id, |
| 'blocked': True, |
| 'reason': decision.reason, |
| 'routing_decision': decision.routing_decision.value |
| } |
| self.db.commit() |
| logger.warning( |
| f"Workflow automation {automation_id} action blocked: {decision.reason}" |
| ) |
| return { |
| 'ok': False, |
| 'error': execution.error, |
| 'maturity_check': execution.metadata['maturity_check'] |
| } |
| except ValueError as e: |
| |
| logger.warning( |
| f"Could not check maturity for agent {agent_id} in automation: {e}" |
| ) |
| |
| |
| |
| execution_results = [] |
| for action in automation.actions: |
| try: |
| action_result = await self._execute_automation_action(action, trigger_context, execution) |
| execution_results.append(action_result) |
| execution.actions_executed.append({ |
| 'action': action, |
| 'result': action_result, |
| 'timestamp': datetime.utcnow().isoformat() |
| }) |
| |
| if action_result.get('stop_execution', False): |
| break |
| except Exception as e: |
| logger.error(f"Operation failed: {e}") |
| log_integration_complete(audit_ctx, error=e) |
| return {'ok': False, 'error': str(e)} |
| logger.error(f"Error executing automation action: {e}") |
| execution_results.append({ |
| 'success': False, |
| 'error': str(e), |
| 'action': action |
| }) |
| |
| |
| post_security_check = await self._post_execution_security_check(automation, execution_results) |
| post_compliance_check = await self._post_execution_compliance_check(automation, execution_results) |
| |
| |
| successful_actions = [r for r in execution_results if r.get('success', False)] |
| success_rate = len(successful_actions) / len(execution_results) if execution_results else 0 |
| |
| |
| execution.status = AutomationStatus.COMPLETED if success_rate >= 0.8 else AutomationStatus.FAILED |
| execution.completed_at = datetime.utcnow() |
| execution.execution_time = (execution.completed_at - execution.started_at).total_seconds() |
| execution.result = { |
| 'success_rate': success_rate, |
| 'total_actions': len(execution_results), |
| 'successful_actions': len(successful_actions), |
| 'failed_actions': len(execution_results) - len(successful_actions) |
| } |
| execution.security_checks.append(post_security_check) |
| execution.compliance_checks.append(post_compliance_check) |
| |
| |
| automation.execution_count += 1 |
| automation.last_executed = execution.completed_at |
| |
| if execution.status == AutomationStatus.COMPLETED: |
| automation.success_count += 1 |
| else: |
| automation.failure_count += 1 |
| |
| |
| await self._send_automation_notifications(automation, execution) |
| |
| |
| await self._update_automation_metrics(automation, execution) |
| |
| |
| if self.db: |
| await self.db.store_automation_execution(asdict(execution)) |
| |
| return { |
| 'ok': True, |
| 'execution_id': execution_id, |
| 'automation_id': automation_id, |
| 'status': execution.status.value, |
| 'execution_time': execution.execution_time, |
| 'result': execution.result, |
| 'actions_executed': len(execution_results), |
| 'successful_actions': len(successful_actions), |
| 'message': "Automation executed successfully" |
| } |
| |
| except Exception as e: |
| logger.error(f"Error executing workflow automation: {e}") |
| return {'ok': False, 'error': str(e)} |
| |
| async def create_security_automation(self, security_event: Dict[str, Any], automation_config: Dict[str, Any]) -> Dict[str, Any]: |
| """Create automation from security event""" |
| |
| audit_ctx = log_integration_attempt("atom_workflow_automation", "execute_automation", locals()) |
| |
| if not await circuit_breaker.is_enabled("atom_workflow_automation"): |
| logger.warning(f"Circuit breaker is open for atom_workflow_automation") |
| log_integration_complete(audit_ctx, error=Exception("Circuit breaker open")) |
| raise HTTPException( |
| status_code=503, |
| detail=f"Atom_workflow_automation integration temporarily disabled" |
| ) |
| |
| is_limited, remaining = await rate_limiter.is_rate_limited("atom_workflow_automation") |
| if is_limited: |
| logger.warning(f"Rate limit exceeded for atom_workflow_automation") |
| log_integration_complete(audit_ctx, error=Exception("Rate limit exceeded")) |
| raise HTTPException( |
| status_code=429, |
| detail=f"Rate limit exceeded for atom_workflow_automation" |
| ) |
| try: |
| |
| threat_type = security_event.get('threat_type', 'unknown') |
| severity = security_event.get('severity', 'medium') |
| |
| automation_data = { |
| 'name': f"Security Response: {threat_type}", |
| 'description': f"Automated response for {threat_type} security events", |
| 'automation_type': WorkflowAutomationType.SECURITY, |
| 'priority': severity, |
| 'conditions': [ |
| { |
| 'type': AutomationConditionType.SECURITY_ALERT.value, |
| 'threat_type': threat_type, |
| 'severity_level': severity, |
| 'source_ip': security_event.get('source_ip'), |
| 'user_id': security_event.get('user_id') |
| } |
| ], |
| 'actions': automation_config.get('actions', [ |
| { |
| 'type': AutomationActionType.SECURITY_ENFORCEMENT.value, |
| 'config': { |
| 'action': 'block_ip', |
| 'duration': 3600, |
| 'reason': f'Security threat detected: {threat_type}' |
| } |
| }, |
| { |
| 'type': AutomationActionType.NOTIFICATION.value, |
| 'config': { |
| 'channels': ['security_team', 'management'], |
| 'message': f"Security threat {threat_type} detected with severity {severity}", |
| 'urgency': severity |
| } |
| } |
| ]), |
| 'schedule': None, |
| 'timeout': 600, |
| 'retry_policy': { |
| 'max_retries': 2, |
| 'backoff': 'exponential' |
| }, |
| 'notification_rules': [ |
| { |
| 'condition': 'always', |
| 'channels': ['security_team'], |
| 'urgency': severity |
| } |
| ], |
| 'metadata': { |
| 'security_event': security_event, |
| 'threat_type': threat_type, |
| 'severity': severity |
| } |
| } |
| |
| |
| result = await self.create_automation(automation_data, 'security_system') |
| |
| if result.get('ok'): |
| |
| execution_result = await self.execute_automation( |
| automation_id=result['automation_id'], |
| trigger_context={'security_event': security_event}, |
| triggered_by='security_event' |
| ) |
| |
| result['execution_result'] = execution_result |
| |
| return result |
| |
| except Exception as e: |
| logger.error(f"Error creating security automation: {e}") |
| return {'ok': False, 'error': str(e)} |
| |
| async def create_compliance_automation(self, compliance_violation: Dict[str, Any], automation_config: Dict[str, Any]) -> Dict[str, Any]: |
| """Create automation from compliance violation""" |
| |
| audit_ctx = log_integration_attempt("atom_workflow_automation", "create_security_automation", locals()) |
| |
| if not await circuit_breaker.is_enabled("atom_workflow_automation"): |
| logger.warning(f"Circuit breaker is open for atom_workflow_automation") |
| log_integration_complete(audit_ctx, error=Exception("Circuit breaker open")) |
| raise HTTPException( |
| status_code=503, |
| detail=f"Atom_workflow_automation integration temporarily disabled" |
| ) |
| |
| is_limited, remaining = await rate_limiter.is_rate_limited("atom_workflow_automation") |
| if is_limited: |
| logger.warning(f"Rate limit exceeded for atom_workflow_automation") |
| log_integration_complete(audit_ctx, error=Exception("Rate limit exceeded")) |
| raise HTTPException( |
| status_code=429, |
| detail=f"Rate limit exceeded for atom_workflow_automation" |
| ) |
| try: |
| |
| standard = compliance_violation.get('standard', 'unknown') |
| violation_type = compliance_violation.get('violation_type', 'unknown') |
| severity = compliance_violation.get('severity', 'medium') |
| |
| automation_data = { |
| 'name': f"Compliance Response: {standard}_{violation_type}", |
| 'description': f"Automated response for {standard} compliance violations", |
| 'automation_type': WorkflowAutomationType.COMPLIANCE, |
| 'priority': severity, |
| 'conditions': [ |
| { |
| 'type': AutomationConditionType.COMPLIANCE_VIOLATION.value, |
| 'standard': standard, |
| 'violation_type': violation_type, |
| 'severity_level': severity, |
| 'affected_resources': compliance_violation.get('affected_resources', []) |
| } |
| ], |
| 'actions': automation_config.get('actions', [ |
| { |
| 'type': AutomationActionType.COMPLIANCE_CHECK.value, |
| 'config': { |
| 'action': 'remediate', |
| 'standard': standard, |
| 'violation_type': violation_type |
| } |
| }, |
| { |
| 'type': AutomationActionType.NOTIFICATION.value, |
| 'config': { |
| 'channels': ['compliance_officer', 'management'], |
| 'message': f"Compliance violation {violation_type} detected for {standard}", |
| 'urgency': severity |
| } |
| } |
| ]), |
| 'schedule': None, |
| 'timeout': 1800, |
| 'retry_policy': { |
| 'max_retries': 3, |
| 'backoff': 'linear' |
| }, |
| 'notification_rules': [ |
| { |
| 'condition': 'always', |
| 'channels': ['compliance_officer'], |
| 'urgency': severity |
| } |
| ], |
| 'metadata': { |
| 'compliance_violation': compliance_violation, |
| 'standard': standard, |
| 'violation_type': violation_type, |
| 'severity': severity |
| } |
| } |
| |
| |
| result = await self.create_automation(automation_data, 'compliance_system') |
| |
| if result.get('ok'): |
| |
| execution_result = await self.execute_automation( |
| automation_id=result['automation_id'], |
| trigger_context={'compliance_violation': compliance_violation}, |
| triggered_by='compliance_violation' |
| ) |
| |
| result['execution_result'] = execution_result |
| |
| return result |
| |
| except Exception as e: |
| logger.error(f"Error creating compliance automation: {e}") |
| return {'ok': False, 'error': str(e)} |
| |
| async def create_integration_automation(self, platform: str, integration_config: Dict[str, Any]) -> Dict[str, Any]: |
| """Create automation for platform integration""" |
| |
| audit_ctx = log_integration_attempt("atom_workflow_automation", "create_compliance_automation", locals()) |
| |
| if not await circuit_breaker.is_enabled("atom_workflow_automation"): |
| logger.warning(f"Circuit breaker is open for atom_workflow_automation") |
| log_integration_complete(audit_ctx, error=Exception("Circuit breaker open")) |
| raise HTTPException( |
| status_code=503, |
| detail=f"Atom_workflow_automation integration temporarily disabled" |
| ) |
| |
| is_limited, remaining = await rate_limiter.is_rate_limited("atom_workflow_automation") |
| if is_limited: |
| logger.warning(f"Rate limit exceeded for atom_workflow_automation") |
| log_integration_complete(audit_ctx, error=Exception("Rate limit exceeded")) |
| raise HTTPException( |
| status_code=429, |
| detail=f"Rate limit exceeded for atom_workflow_automation" |
| ) |
| try: |
| |
| if platform not in self.platform_integrations: |
| return {'ok': False, 'error': f'Unsupported platform: {platform}'} |
| |
| automation_data = { |
| 'name': f"Integration: {platform}", |
| 'description': f"Automation for {platform} platform integration", |
| 'automation_type': WorkflowAutomationType.INTEGRATION, |
| 'priority': AutomationPriority.MEDIUM, |
| 'conditions': [ |
| { |
| 'type': AutomationConditionType.EVENT_TRIGGERED.value, |
| 'platform': platform, |
| 'events': integration_config.get('events', ['message_received', 'user_joined']) |
| } |
| ], |
| 'actions': integration_config.get('actions', [ |
| { |
| 'type': AutomationActionType.NOTIFICATION.value, |
| 'config': { |
| 'channels': ['platform_admin'], |
| 'message': f"Integration event from {platform}", |
| 'urgency': 'low' |
| } |
| } |
| ]), |
| 'schedule': None, |
| 'timeout': 300, |
| 'retry_policy': { |
| 'max_retries': 2, |
| 'backoff': 'exponential' |
| }, |
| 'notification_rules': [ |
| { |
| 'condition': 'on_error', |
| 'channels': ['platform_admin'], |
| 'urgency': 'medium' |
| } |
| ], |
| 'metadata': { |
| 'platform': platform, |
| 'integration_config': integration_config |
| } |
| } |
| |
| |
| result = await self.create_automation(automation_data, 'integration_system') |
| |
| |
| if result.get('ok'): |
| await self._setup_platform_triggers(platform, result['automation_id'], integration_config) |
| |
| return result |
| |
| except Exception as e: |
| logger.error(f"Error creating integration automation: {e}") |
| return {'ok': False, 'error': str(e)} |
| |
| async def get_automations(self, filters: Dict[str, Any] = None) -> List[Dict[str, Any]]: |
| """Get workflow automations with filters""" |
| |
| audit_ctx = log_integration_attempt("atom_workflow_automation", "create_integration_automation", locals()) |
| |
| if not await circuit_breaker.is_enabled("atom_workflow_automation"): |
| logger.warning(f"Circuit breaker is open for atom_workflow_automation") |
| log_integration_complete(audit_ctx, error=Exception("Circuit breaker open")) |
| raise HTTPException( |
| status_code=503, |
| detail=f"Atom_workflow_automation integration temporarily disabled" |
| ) |
| |
| is_limited, remaining = await rate_limiter.is_rate_limited("atom_workflow_automation") |
| if is_limited: |
| logger.warning(f"Rate limit exceeded for atom_workflow_automation") |
| log_integration_complete(audit_ctx, error=Exception("Rate limit exceeded")) |
| raise HTTPException( |
| status_code=429, |
| detail=f"Rate limit exceeded for atom_workflow_automation" |
| ) |
| try: |
| filters = filters or {} |
| automations = [] |
| |
| for automation in self.automations.values(): |
| |
| if filters.get('automation_type') and automation.automation_type.value != filters['automation_type']: |
| continue |
| if filters.get('priority') and automation.priority.value != filters['priority']: |
| continue |
| if filters.get('status') and automation.status.value != filters['status']: |
| continue |
| if filters.get('created_by') and automation.created_by != filters['created_by']: |
| continue |
| |
| |
| automation_details = { |
| 'automation_id': automation.automation_id, |
| 'name': automation.name, |
| 'description': automation.description, |
| 'automation_type': automation.automation_type.value, |
| 'priority': automation.priority.value, |
| 'status': automation.status.value, |
| 'conditions': automation.conditions, |
| 'actions': automation.actions, |
| 'schedule': automation.schedule, |
| 'created_at': automation.created_at.isoformat(), |
| 'updated_at': automation.updated_at.isoformat(), |
| 'created_by': automation.created_by, |
| 'last_executed': automation.last_executed.isoformat() if automation.last_executed else None, |
| 'execution_count': automation.execution_count, |
| 'success_count': automation.success_count, |
| 'failure_count': automation.failure_count, |
| 'success_rate': automation.success_count / automation.execution_count if automation.execution_count > 0 else 0.0, |
| 'timeout': automation.timeout, |
| 'retry_policy': automation.retry_policy, |
| 'notification_rules': automation.notification_rules, |
| 'metadata': automation.metadata |
| } |
| |
| automations.append(automation_details) |
| |
| return automations |
| |
| except Exception as e: |
| logger.error(f"Error getting automations: {e}") |
| return [] |
| |
| async def get_automation_executions(self, automation_id: str = None, filters: Dict[str, Any] = None) -> List[Dict[str, Any]]: |
| """Get automation executions""" |
| |
| audit_ctx = log_integration_attempt("atom_workflow_automation", "get_automations", locals()) |
| |
| if not await circuit_breaker.is_enabled("atom_workflow_automation"): |
| logger.warning(f"Circuit breaker is open for atom_workflow_automation") |
| log_integration_complete(audit_ctx, error=Exception("Circuit breaker open")) |
| raise HTTPException( |
| status_code=503, |
| detail=f"Atom_workflow_automation integration temporarily disabled" |
| ) |
| |
| is_limited, remaining = await rate_limiter.is_rate_limited("atom_workflow_automation") |
| if is_limited: |
| logger.warning(f"Rate limit exceeded for atom_workflow_automation") |
| log_integration_complete(audit_ctx, error=Exception("Rate limit exceeded")) |
| raise HTTPException( |
| status_code=429, |
| detail=f"Rate limit exceeded for atom_workflow_automation" |
| ) |
| try: |
| filters = filters or {} |
| executions = [] |
| |
| for execution in self.executions.values(): |
| |
| if automation_id and execution.automation_id != automation_id: |
| continue |
| |
| |
| if filters.get('status') and execution.status.value != filters['status']: |
| continue |
| if filters.get('triggered_by') and execution.triggered_by != filters['triggered_by']: |
| continue |
| if filters.get('date_from') and execution.started_at.date() < filters['date_from']: |
| continue |
| if filters.get('date_to') and execution.started_at.date() > filters['date_to']: |
| continue |
| |
| |
| execution_details = { |
| 'execution_id': execution.execution_id, |
| 'automation_id': execution.automation_id, |
| 'triggered_by': execution.triggered_by, |
| 'trigger_context': execution.trigger_context, |
| 'status': execution.status.value, |
| 'started_at': execution.started_at.isoformat(), |
| 'completed_at': execution.completed_at.isoformat() if execution.completed_at else None, |
| 'execution_time': execution.execution_time, |
| 'result': execution.result, |
| 'error': execution.error, |
| 'actions_executed': len(execution.actions_executed), |
| 'notifications_sent': len(execution.notifications_sent), |
| 'compliance_checks': len(execution.compliance_checks), |
| 'security_checks': len(execution.security_checks), |
| 'metadata': execution.metadata |
| } |
| |
| executions.append(execution_details) |
| |
| |
| executions.sort(key=lambda x: x['started_at'], reverse=True) |
| |
| return executions |
| |
| except Exception as e: |
| logger.error(f"Error getting automation executions: {e}") |
| return [] |
| |
| async def get_automation_metrics(self) -> Dict[str, Any]: |
| """Get automation metrics""" |
| |
| audit_ctx = log_integration_attempt("atom_workflow_automation", "get_automation_executions", locals()) |
| |
| if not await circuit_breaker.is_enabled("atom_workflow_automation"): |
| logger.warning(f"Circuit breaker is open for atom_workflow_automation") |
| log_integration_complete(audit_ctx, error=Exception("Circuit breaker open")) |
| raise HTTPException( |
| status_code=503, |
| detail=f"Atom_workflow_automation integration temporarily disabled" |
| ) |
| |
| is_limited, remaining = await rate_limiter.is_rate_limited("atom_workflow_automation") |
| if is_limited: |
| logger.warning(f"Rate limit exceeded for atom_workflow_automation") |
| log_integration_complete(audit_ctx, error=Exception("Rate limit exceeded")) |
| raise HTTPException( |
| status_code=429, |
| detail=f"Rate limit exceeded for atom_workflow_automation" |
| ) |
| try: |
| return { |
| 'total_automations': self.automation_metrics['total_automations'], |
| 'active_automations': self.automation_metrics['active_automations'], |
| 'executed_today': self.automation_metrics['executed_today'], |
| 'executed_this_week': self.automation_metrics['executed_this_week'], |
| 'executed_this_month': self.automation_metrics['executed_this_month'], |
| 'success_rate': self.automation_metrics['success_rate'], |
| 'average_execution_time': self.automation_metrics['average_execution_time'], |
| 'error_rate': self.automation_metrics['error_rate'], |
| 'time_saved_hours': self.automation_metrics['time_saved_hours'], |
| 'cost_savings': self.automation_metrics['cost_savings'], |
| 'automations_by_type': dict(self.automation_metrics['automations_by_type']), |
| 'automations_by_priority': dict(self.automation_metrics['automations_by_priority']), |
| 'executions_by_status': dict(self.automation_metrics['executions_by_status']), |
| 'scheduled_automations': len(self.scheduled_automations), |
| 'active_triggers': len(self.active_triggers), |
| 'automation_templates': len(self.automation_templates) |
| } |
| |
| except Exception as e: |
| logger.error(f"Error getting automation metrics: {e}") |
| return {} |
| |
| |
| async def _validate_automation_data(self, automation_data: Dict[str, Any]) -> Dict[str, Any]: |
| """Validate automation data""" |
| |
| audit_ctx = log_integration_attempt("atom_workflow_automation", "get_automation_metrics", locals()) |
| |
| if not await circuit_breaker.is_enabled("atom_workflow_automation"): |
| logger.warning(f"Circuit breaker is open for atom_workflow_automation") |
| log_integration_complete(audit_ctx, error=Exception("Circuit breaker open")) |
| raise HTTPException( |
| status_code=503, |
| detail=f"Atom_workflow_automation integration temporarily disabled" |
| ) |
| |
| is_limited, remaining = await rate_limiter.is_rate_limited("atom_workflow_automation") |
| if is_limited: |
| logger.warning(f"Rate limit exceeded for atom_workflow_automation") |
| log_integration_complete(audit_ctx, error=Exception("Rate limit exceeded")) |
| raise HTTPException( |
| status_code=429, |
| detail=f"Rate limit exceeded for atom_workflow_automation" |
| ) |
| validation_result = {'valid': True, 'errors': [], 'warnings': []} |
| |
| required_fields = ['name', 'description', 'automation_type', 'priority', 'conditions', 'actions'] |
| for field in required_fields: |
| if field not in automation_data: |
| validation_result['valid'] = False |
| validation_result['errors'].append(f"Required field missing: {field}") |
| |
| |
| if 'conditions' in automation_data: |
| for condition in automation_data['conditions']: |
| if 'type' not in condition: |
| validation_result['valid'] = False |
| validation_result['errors'].append("Condition missing type") |
| |
| |
| if 'actions' in automation_data: |
| for action in automation_data['actions']: |
| if 'type' not in action: |
| validation_result['valid'] = False |
| validation_result['errors'].append("Action missing type") |
| |
| return validation_result |
| |
| async def _setup_automation_triggers(self, automation: WorkflowAutomation): |
| """Setup automation triggers""" |
| for condition in automation.conditions: |
| condition_type = condition.get('type') |
| if condition_type == AutomationConditionType.SCHEDULED.value: |
| |
| await self._schedule_automation(automation, condition) |
| elif condition_type == AutomationConditionType.EVENT_TRIGGERED.value: |
| |
| await self._setup_event_trigger(automation, condition) |
| elif condition_type == AutomationConditionType.THRESHOLD_EXCEEDED.value: |
| |
| await self._setup_threshold_trigger(automation, condition) |
| elif condition_type == AutomationConditionType.ANOMALY_DETECTED.value: |
| |
| await self._setup_anomaly_trigger(automation, condition) |
| elif condition_type == AutomationConditionType.SECURITY_ALERT.value: |
| |
| await self._setup_security_trigger(automation, condition) |
| elif condition_type == AutomationConditionType.COMPLIANCE_VIOLATION.value: |
| |
| await self._setup_compliance_trigger(automation, condition) |
| except Exception as e: |
| logger.error(f"Operation failed: {e}") |
| log_integration_complete(audit_ctx, error=e) |
| return {'ok': False, 'error': str(e)} |
| logger.error(f"Error setting up automation triggers: {e}") |
| |
| async def _execute_automation_action(self, action: Dict[str, Any], trigger_context: Dict[str, Any], execution: AutomationExecution) -> Dict[str, Any]: |
| """Execute automation action""" |
| action_type = action.get('type') |
| action_config = action.get('config', {}) |
| |
| if action_type == AutomationActionType.NOTIFICATION.value: |
| return await self._execute_notification_action(action_config, trigger_context) |
| elif action_type == AutomationActionType.WORKFLOW_EXECUTION.value: |
| return await self._execute_workflow_action(action_config, trigger_context) |
| elif action_type == AutomationActionType.SECURITY_ENFORCEMENT.value: |
| return await self._execute_security_enforcement_action(action_config, trigger_context) |
| elif action_type == AutomationActionType.COMPLIANCE_CHECK.value: |
| return await self._execute_compliance_check_action(action_config, trigger_context) |
| elif action_type == AutomationActionType.DATA_PROCESSING.value: |
| return await self._execute_data_processing_action(action_config, trigger_context) |
| elif action_type == AutomationActionType.API_CALL.value: |
| return await self._execute_api_call_action(action_config, trigger_context) |
| elif action_type == AutomationActionType.EMAIL_SEND.value: |
| return await self._execute_email_action(action_config, trigger_context) |
| elif action_type == AutomationActionType.MESSAGE_SEND.value: |
| return await self._execute_message_action(action_config, trigger_context) |
| elif action_type == AutomationActionType.LOGGING.value: |
| return await self._execute_logging_action(action_config, trigger_context) |
| elif action_type == AutomationActionType.AUDITING.value: |
| return await self._execute_auditing_action(action_config, trigger_context) |
| elif action_type == AutomationActionType.REPORTING.value: |
| return await self._execute_reporting_action(action_config, trigger_context) |
| elif action_type == AutomationActionType.REMEDIATION.value: |
| return await self._execute_remediation_action(action_config, trigger_context) |
| else: |
| return { |
| 'success': False, |
| 'error': f"Unsupported action type: {action_type}" |
| } |
| except Exception as e: |
| logger.error(f"Operation failed: {e}") |
| log_integration_complete(audit_ctx, error=e) |
| return {'ok': False, 'error': str(e)} |
| logger.error(f"Error executing automation action: {e}") |
| return { |
| 'success': False, |
| 'error': str(e) |
| } |
| |
| |
| async def _execute_notification_action(self, config: Dict[str, Any], trigger_context: Dict[str, Any]) -> Dict[str, Any]: |
| """Execute notification action""" |
| channels = config.get('channels', []) |
| message = config.get('message', 'Automation triggered') |
| urgency = config.get('urgency', 'medium') |
| |
| notification_results = [] |
| for channel in channels: |
| if channel == 'security_team': |
| |
| await self._notify_security_team(message, urgency, trigger_context) |
| elif channel == 'compliance_officer': |
| |
| await self._notify_compliance_officer(message, urgency, trigger_context) |
| elif channel == 'management': |
| |
| await self._notify_management(message, urgency, trigger_context) |
| elif channel == 'slack': |
| |
| await self._notify_slack(message, urgency, trigger_context) |
| elif channel == 'teams': |
| |
| await self._notify_teams(message, urgency, trigger_context) |
| elif channel == 'email': |
| |
| await self._notify_email(message, urgency, trigger_context) |
| notification_results.append({ |
| 'channel': channel, |
| 'success': True, |
| 'message': message |
| }) |
| return { |
| 'success': True, |
| 'notification_results': notification_results, |
| 'channels': channels, |
| 'message': message, |
| 'urgency': urgency |
| } |
| except Exception as e: |
| logger.error(f"Operation failed: {e}") |
| log_integration_complete(audit_ctx, error=e) |
| return {'ok': False, 'error': str(e)} |
| logger.error(f"Error executing notification action: {e}") |
| return { |
| 'success': False, |
| 'error': str(e) |
| } |
| |
| async def _execute_workflow_action(self, config: Dict[str, Any], trigger_context: Dict[str, Any]) -> Dict[str, Any]: |
| """Execute workflow action""" |
| workflow_id = config.get('workflow_id') |
| workflow_data = config.get('workflow_data', {}) |
| if not workflow_id: |
| return { |
| 'success': False, |
| 'error': 'workflow_id is required for workflow action' |
| } |
| |
| if self.unified_service: |
| result = await self.unified_service.execute_enterprise_workflow( |
| workflow_id=workflow_id, |
| trigger_context={ |
| 'automation_trigger': trigger_context, |
| 'workflow_data': workflow_data |
| }, |
| user_id='automation_system' |
| ) |
| return { |
| 'success': result.get('ok', False), |
| 'result': result, |
| 'workflow_id': workflow_id |
| } |
| else: |
| return { |
| 'success': False, |
| 'error': 'Unified service not available' |
| } |
| except Exception as e: |
| logger.error(f"Operation failed: {e}") |
| log_integration_complete(audit_ctx, error=e) |
| return {'ok': False, 'error': str(e)} |
| logger.error(f"Error executing workflow action: {e}") |
| return { |
| 'success': False, |
| 'error': str(e) |
| } |
| |
| async def _execute_security_enforcement_action(self, config: Dict[str, Any], trigger_context: Dict[str, Any]) -> Dict[str, Any]: |
| """Execute security enforcement action""" |
| enforcement_action = config.get('action') |
| target = config.get('target') |
| reason = config.get('reason', 'Security policy violation') |
| if not enforcement_action: |
| return { |
| 'success': False, |
| 'error': 'action is required for security enforcement' |
| } |
| |
| if self.security_service: |
| if enforcement_action == 'block_ip': |
| await self.security_service._block_ip(target, config.get('duration', 3600)) |
| elif enforcement_action == 'lock_user': |
| await self.security_service._lock_user_account(target) |
| elif enforcement_action == 'terminate_session': |
| await self.security_service._terminate_session(target) |
| elif enforcement_action == 'quarantine': |
| await self.security_service._quarantine_resource(target) |
| return { |
| 'success': True, |
| 'enforcement_action': enforcement_action, |
| 'target': target, |
| 'reason': reason |
| } |
| else: |
| return { |
| 'success': False, |
| 'error': 'Security service not available' |
| } |
| except Exception as e: |
| logger.error(f"Operation failed: {e}") |
| log_integration_complete(audit_ctx, error=e) |
| return {'ok': False, 'error': str(e)} |
| logger.error(f"Error executing security enforcement action: {e}") |
| return { |
| 'success': False, |
| 'error': str(e) |
| } |
| |
| async def _execute_compliance_check_action(self, config: Dict[str, Any], trigger_context: Dict[str, Any]) -> Dict[str, Any]: |
| """Execute compliance check action""" |
| standard = config.get('standard') |
| check_type = config.get('check_type', 'automated') |
| if not standard: |
| return { |
| 'success': False, |
| 'error': 'standard is required for compliance check' |
| } |
| |
| if self.security_service: |
| compliance_report = await self.security_service.check_compliance( |
| ComplianceStandard(standard), |
| trigger_context.get('period', 'immediate') |
| ) |
| return { |
| 'success': compliance_report is not None, |
| 'compliance_report': asdict(compliance_report) if compliance_report else None, |
| 'standard': standard, |
| 'check_type': check_type |
| } |
| else: |
| return { |
| 'success': False, |
| 'error': 'Security service not available' |
| } |
| except Exception as e: |
| logger.error(f"Operation failed: {e}") |
| log_integration_complete(audit_ctx, error=e) |
| return {'ok': False, 'error': str(e)} |
| logger.error(f"Error executing compliance check action: {e}") |
| return { |
| 'success': False, |
| 'error': str(e) |
| } |
| |
| |
| async def _execute_data_processing_action(self, config: Dict[str, Any], trigger_context: Dict[str, Any]) -> Dict[str, Any]: |
| """Execute data processing action""" |
| return {'success': True, 'message': 'Data processing action executed'} |
| |
| async def _execute_api_call_action(self, config: Dict[str, Any], trigger_context: Dict[str, Any]) -> Dict[str, Any]: |
| """Execute API call action""" |
| return {'success': True, 'message': 'API call action executed'} |
| |
| async def _execute_email_action(self, config: Dict[str, Any], trigger_context: Dict[str, Any]) -> Dict[str, Any]: |
| """Execute email action""" |
| return {'success': True, 'message': 'Email action executed'} |
| |
| async def _execute_message_action(self, config: Dict[str, Any], trigger_context: Dict[str, Any]) -> Dict[str, Any]: |
| """Execute message action""" |
| return {'success': True, 'message': 'Message action executed'} |
| |
| async def _execute_logging_action(self, config: Dict[str, Any], trigger_context: Dict[str, Any]) -> Dict[str, Any]: |
| """Execute logging action""" |
| return {'success': True, 'message': 'Logging action executed'} |
| |
| async def _execute_auditing_action(self, config: Dict[str, Any], trigger_context: Dict[str, Any]) -> Dict[str, Any]: |
| """Execute auditing action""" |
| return {'success': True, 'message': 'Auditing action executed'} |
| |
| async def _execute_reporting_action(self, config: Dict[str, Any], trigger_context: Dict[str, Any]) -> Dict[str, Any]: |
| """Execute reporting action""" |
| return {'success': True, 'message': 'Reporting action executed'} |
| |
| async def _execute_remediation_action(self, config: Dict[str, Any], trigger_context: Dict[str, Any]) -> Dict[str, Any]: |
| """Execute remediation action""" |
| return {'success': True, 'message': 'Remediation action executed'} |
| |
| |
| async def _pre_execution_security_check(self, automation: WorkflowAutomation, trigger_context: Dict[str, Any]) -> Dict[str, Any]: |
| """Pre-execution security check""" |
| |
| if automation.automation_type == WorkflowAutomationType.SECURITY: |
| security_level = WorkflowSecurityLevel.RESTRICTED |
| else: |
| security_level = WorkflowSecurityLevel.INTERNAL |
| |
| if not trigger_context.get('authorized', True): |
| return { |
| 'passed': False, |
| 'reason': 'Trigger context not authorized' |
| } |
| return {'passed': True} |
| except Exception as e: |
| logger.error(f"Operation failed: {e}") |
| log_integration_complete(audit_ctx, error=e) |
| return {'ok': False, 'error': str(e)} |
| logger.error(f"Error in pre-execution security check: {e}") |
| return { |
| 'passed': False, |
| 'reason': str(e) |
| } |
| |
| async def _pre_execution_compliance_check(self, automation: WorkflowAutomation, trigger_context: Dict[str, Any]) -> Dict[str, Any]: |
| """Pre-execution compliance check""" |
| |
| if automation.automation_type == WorkflowAutomationType.COMPLIANCE: |
| return { |
| 'passed': True, |
| 'compliance_level': 'compliant' |
| } |
| return {'passed': True} |
| except Exception as e: |
| logger.error(f"Operation failed: {e}") |
| log_integration_complete(audit_ctx, error=e) |
| return {'ok': False, 'error': str(e)} |
| logger.error(f"Error in pre-execution compliance check: {e}") |
| return { |
| 'passed': False, |
| 'reason': str(e) |
| } |
| |
| async def _post_execution_security_check(self, automation: WorkflowAutomation, execution_results: List[Dict[str, Any]]) -> Dict[str, Any]: |
| """Post-execution security check""" |
| |
| for result in execution_results: |
| if not result.get('success', False): |
| logger.warning(f"Security action failed: {result}") |
| return {'passed': True} |
| except Exception as e: |
| logger.error(f"Operation failed: {e}") |
| log_integration_complete(audit_ctx, error=e) |
| return {'ok': False, 'error': str(e)} |
| logger.error(f"Error in post-execution security check: {e}") |
| return { |
| 'passed': False, |
| 'reason': str(e) |
| } |
| |
| async def _post_execution_compliance_check(self, automation: WorkflowAutomation, execution_results: List[Dict[str, Any]]) -> Dict[str, Any]: |
| """Post-execution compliance check""" |
| |
| return {'passed': True} |
| except Exception as e: |
| logger.error(f"Operation failed: {e}") |
| log_integration_complete(audit_ctx, error=e) |
| return {'ok': False, 'error': str(e)} |
| logger.error(f"Error in post-execution compliance check: {e}") |
| return { |
| 'passed': False, |
| 'reason': str(e) |
| } |
| |
| |
| async def _notify_security_team(self, message: str, urgency: str, context: Dict[str, Any]): |
| """Notify security team""" |
| |
| logger.info(f"Security Team Notification: {message} (Urgency: {urgency})") |
| |
| async def _notify_compliance_officer(self, message: str, urgency: str, context: Dict[str, Any]): |
| """Notify compliance officer""" |
| |
| logger.info(f"Compliance Officer Notification: {message} (Urgency: {urgency})") |
| |
| async def _notify_management(self, message: str, urgency: str, context: Dict[str, Any]): |
| """Notify management""" |
| |
| logger.info(f"Management Notification: {message} (Urgency: {urgency})") |
| |
| async def _notify_slack(self, message: str, urgency: str, context: Dict[str, Any]): |
| """Notify Slack""" |
| |
| logger.info(f"Slack Notification: {message} (Urgency: {urgency})") |
| |
| async def _notify_teams(self, message: str, urgency: str, context: Dict[str, Any]): |
| """Notify Teams""" |
| |
| logger.info(f"Teams Notification: {message} (Urgency: {urgency})") |
| |
| async def _notify_email(self, message: str, urgency: str, context: Dict[str, Any]): |
| """Notify via email""" |
| |
| logger.info(f"Email Notification: {message} (Urgency: {urgency})") |
| |
| |
| async def _initialize_automation_templates(self): |
| """Initialize automation templates with default templates""" |
| |
| default_templates = { |
| 'security_alert_response': { |
| 'name': 'Security Alert Response', |
| 'description': 'Automatically respond to security alerts based on severity', |
| 'type': WorkflowAutomationType.SECURITY.value, |
| 'conditions': [ |
| { |
| 'type': AutomationConditionType.SECURITY_ALERT.value, |
| 'severity': ['high', 'critical'] |
| } |
| ], |
| 'actions': [ |
| { |
| 'type': AutomationActionType.NOTIFICATION.value, |
| 'config': { |
| 'channels': ['security_team'], |
| 'urgency': 'high' |
| } |
| }, |
| { |
| 'type': AutomationActionType.WORKFLOW_EXECUTION.value, |
| 'config': { |
| 'workflow_id': 'security_incident_response' |
| } |
| } |
| ], |
| 'priority': AutomationPriority.HIGH.value, |
| 'enabled': True |
| }, |
| 'compliance_violation_handling': { |
| 'name': 'Compliance Violation Handling', |
| 'description': 'Handle compliance violations automatically', |
| 'type': WorkflowAutomationType.COMPLIANCEANCE.value, |
| 'conditions': [ |
| { |
| 'type': AutomationConditionType.COMPLIANCE_VIOLATION.value, |
| 'standards': ['SOC2', 'HIPAA', 'GDPR'] |
| } |
| ], |
| 'actions': [ |
| { |
| 'type': AutomationActionType.NOTIFICATION.value, |
| 'config': { |
| 'channels': ['compliance_team'], |
| 'urgency': 'critical' |
| } |
| }, |
| { |
| 'type': AutomationActionType.AUDITING.value, |
| 'config': { |
| 'audit_type': 'compliance_violation' |
| } |
| } |
| ], |
| 'priority': AutomationPriority.CRITICAL.value, |
| 'enabled': True |
| }, |
| 'daily_security_scan': { |
| 'name': 'Daily Security Scan', |
| 'description': 'Run daily security scans', |
| 'type': WorkflowAutomationType.SECURITY.value, |
| 'conditions': [ |
| { |
| 'type': AutomationConditionType.SCHEDULED.value, |
| 'schedule': '0 2 * * *' |
| } |
| ], |
| 'actions': [ |
| { |
| 'type': AutomationActionType.WORKFLOW_EXECUTION.value, |
| 'config': { |
| 'workflow_id': 'security_scan_workflow' |
| } |
| } |
| ], |
| 'priority': AutomationPriority.MEDIUM.value, |
| 'enabled': False |
| }, |
| 'user_access_review': { |
| 'name': 'User Access Review', |
| 'description': 'Review user access permissions periodically', |
| 'type': WorkflowAutomationType.ACCESS_CONTROL.value, |
| 'conditions': [ |
| { |
| 'type': AutomationConditionType.SCHEDULED.value, |
| 'schedule': '0 9 * * 1' |
| } |
| ], |
| 'actions': [ |
| { |
| 'type': AutomationActionType.NOTIFICATION.value, |
| 'config': { |
| 'channels': ['admin_team'], |
| 'urgency': 'medium' |
| } |
| }, |
| { |
| 'type': AutomationActionType.REPORTING.value, |
| 'config': { |
| 'report_type': 'user_access_report' |
| } |
| } |
| ], |
| 'priority': AutomationPriority.MEDIUM.value, |
| 'enabled': False |
| } |
| } |
| |
| if self.db: |
| try: |
| from sqlalchemy import text |
| result = self.db.execute(text("SELECT data FROM automation_templates WHERE active = :active"), {"active": True}) |
| for row in result: |
| template_data = json.loads(row[0]) if isinstance(row[0], str) else row[0] |
| if 'template_id' in template_data: |
| self.automation_templates[template_data['template_id']] = template_data |
| except Exception as e: |
| logger.error(f"Operation failed: {e}") |
| log_integration_complete(audit_ctx, error=e) |
| return {'ok': False, 'error': str(e)} |
| logger.warning(f"Could not load templates from database: {e}") |
|
|
| |
| self.automation_templates.update(default_templates) |
| logger.info(f"Initialized {len(self.automation_templates)} automation templates") |
| return True |
| except Exception as e: |
| logger.error(f"Error initializing automation templates: {e}") |
| return False |
|
|
| async def _load_automations(self): |
| """Load existing automations from database""" |
| if not self.db: |
| logger.warning("No database connection, skipping automation load") |
| return False |
| from sqlalchemy import text |
| |
| result = self.db.execute(text(""" |
| SELECT automation_id, name, description, type, conditions, actions, |
| priority, status, enabled, created_by, created_at, updated_at, |
| schedule, next_run, last_run, execution_count, success_count, |
| failure_count, last_execution_status, metadata |
| FROM workflow_automations |
| WHERE status IN (:active, :paused) |
| ORDER BY created_at DESC |
| """), { |
| "active": AutomationStatus.ACTIVE.value, |
| "paused": AutomationStatus.PAUSED.value |
| }) |
| for row in result: |
| automation = WorkflowAutomation( |
| automation_id=row[0], |
| name=row[1], |
| description=row[2], |
| type=row[3], |
| conditions=json.loads(row[4]) if row[4] else [], |
| actions=json.loads(row[5]) if row[5] else [], |
| priority=row[6], |
| status=AutomationStatus(row[7]), |
| enabled=row[8], |
| created_by=row[9], |
| created_at=datetime.fromisoformat(row[10]) if row[10] else datetime.utcnow(), |
| updated_at=datetime.fromisoformat(row[11]) if row[11] else datetime.utcnow(), |
| schedule=row[12], |
| next_run=datetime.fromisoformat(row[13]) if row[13] else None, |
| last_run=datetime.fromisoformat(row[14]) if row[14] else None, |
| execution_count=row[15] or 0, |
| success_count=row[16] or 0, |
| failure_count=row[17] or 0, |
| last_execution_status=row[18], |
| metadata=json.loads(row[19]) if row[19] else {} |
| ) |
| self.automations[automation.automation_id] = automation |
| |
| if automation.enabled and automation.schedule and automation.next_run: |
| await self._schedule_automation(automation, {'type': AutomationConditionType.SCHEDULED.value}) |
| logger.info(f"Loaded {len(self.automations)} automations from database") |
| return True |
| except Exception as e: |
| logger.error(f"Operation failed: {e}") |
| log_integration_complete(audit_ctx, error=e) |
| return {'ok': False, 'error': str(e)} |
| logger.error(f"Error loading automations: {e}") |
| return False |
|
|
| async def _initialize_automation_scheduling(self): |
| """Initialize automation scheduling system""" |
| if self.scheduler_running: |
| logger.warning("Scheduler already running") |
| return True |
| |
| self.scheduler_task = asyncio.create_task(self._scheduler_loop()) |
| self.scheduler_running = True |
| logger.info("Automation scheduling initialized") |
| return True |
| except Exception as e: |
| logger.error(f"Operation failed: {e}") |
| log_integration_complete(audit_ctx, error=e) |
| return {'ok': False, 'error': str(e)} |
| logger.error(f"Error initializing automation scheduling: {e}") |
| return False |
|
|
| async def _scheduler_loop(self): |
| """Background scheduler loop""" |
| while self.scheduler_running: |
| now = datetime.utcnow() |
| |
| for automation_id, automation in self.automations.items(): |
| if automation.enabled and automation.next_run: |
| if automation.next_run <= now: |
| logger.info(f"Running scheduled automation: {automation_id}") |
| await self.execute_automation( |
| automation_id=automation_id, |
| trigger_context={'trigger_type': 'scheduled'} |
| ) |
| |
| await asyncio.sleep(60) |
| except Exception as e: |
| logger.error(f"Operation failed: {e}") |
| log_integration_complete(audit_ctx, error=e) |
| return {'ok': False, 'error': str(e)} |
| logger.error(f"Error in scheduler loop: {e}") |
| await asyncio.sleep(60) |
|
|
| async def _initialize_trigger_listeners(self): |
| """Initialize trigger listeners for event-based automations""" |
| |
| event_types = [ |
| AutomationConditionType.EVENT_TRIGGERED.value, |
| AutomationConditionType.SECURITY_ALERT.value, |
| AutomationConditionType.COMPLIANCE_VIOLATION.value, |
| AutomationConditionType.THRESHOLD_EXCEEDED.value, |
| AutomationConditionType.ANOMALY_DETECTED.value, |
| AutomationConditionType.SYSTEM_EVENT.value, |
| AutomationConditionType.USER_ACTION.value, |
| AutomationConditionType.DATA_CHANGED.value |
| ] |
| for event_type in event_types: |
| self.trigger_listeners[event_type] = { |
| 'automations': [], |
| 'callback': self._handle_event_trigger |
| } |
| |
| for automation_id, automation in self.automations.items(): |
| for condition in automation.conditions: |
| if condition['type'] in event_types: |
| if automation_id not in self.trigger_listeners[condition['type']]['automations']: |
| self.trigger_listeners[condition['type']]['automations'].append(automation_id) |
| logger.info(f"Initialized trigger listeners for {len(self.trigger_listeners)} event types") |
| return True |
| except Exception as e: |
| logger.error(f"Operation failed: {e}") |
| log_integration_complete(audit_ctx, error=e) |
| return {'ok': False, 'error': str(e)} |
| logger.error(f"Error initializing trigger listeners: {e}") |
| return False |
|
|
| async def _handle_event_trigger(self, event_type: str, event_data: Dict[str, Any]): |
| """Handle an event trigger""" |
| if event_type not in self.trigger_listeners: |
| logger.warning(f"Unknown event type: {event_type}") |
| return |
| listener = self.trigger_listeners[event_type] |
| automation_ids = listener['automations'] |
| for automation_id in automation_ids: |
| if automation_id in self.automations: |
| automation = self.automations[automation_id] |
| if automation.enabled: |
| await self.execute_automation( |
| automation_id=automation_id, |
| trigger_context=event_data |
| ) |
| except Exception as e: |
| logger.error(f"Operation failed: {e}") |
| log_integration_complete(audit_ctx, error=e) |
| return {'ok': False, 'error': str(e)} |
| logger.error(f"Error handling event trigger: {e}") |
|
|
| async def _initialize_integration_endpoints(self): |
| """Initialize integration endpoints for platform-specific automations""" |
| |
| for platform_name, integration in self.platform_integrations.items(): |
| if integration: |
| try: |
| |
| if hasattr(integration, 'test_connection'): |
| is_connected = await integration.test_connection() |
| logger.info(f"Platform {platform_name} integration: {'connected' if is_connected else 'disconnected'}") |
| except Exception as e: |
| logger.error(f"Operation failed: {e}") |
| log_integration_complete(audit_ctx, error=e) |
| return {'ok': False, 'error': str(e)} |
| logger.warning(f"Could not validate {platform_name} integration: {e}") |
|
|
| logger.info("Integration endpoints initialized") |
| return True |
| except Exception as e: |
| logger.error(f"Error initializing integration endpoints: {e}") |
| return False |
|
|
| async def _start_automation_monitoring(self): |
| """Start background automation monitoring""" |
| |
| asyncio.create_task(self._monitoring_loop()) |
| logger.info("Automation monitoring started") |
| return True |
| except Exception as e: |
| logger.error(f"Operation failed: {e}") |
| log_integration_complete(audit_ctx, error=e) |
| return {'ok': False, 'error': str(e)} |
| logger.error(f"Error starting automation monitoring: {e}") |
| return False |
|
|
| async def _monitoring_loop(self): |
| """Background monitoring loop for automation health""" |
| while True: |
| |
| self.automation_metrics['total_automations'] = len(self.automations) |
| self.automation_metrics['active_automations'] = sum( |
| 1 for auto in self.automations.values() if auto.enabled and auto.status == AutomationStatus.ACTIVE |
| ) |
| |
| for automation_id, automation in self.automations.items(): |
| if automation.last_execution_status == 'failed': |
| |
| if automation.execution_count > 0: |
| failure_rate = automation.failure_count / automation.execution_count |
| if failure_rate > 0.5: |
| logger.warning(f"Automation {automation_id} has high failure rate: {failure_rate:.2%}") |
| |
| await asyncio.sleep(300) |
| except Exception as e: |
| logger.error(f"Operation failed: {e}") |
| log_integration_complete(audit_ctx, error=e) |
| return {'ok': False, 'error': str(e)} |
| logger.error(f"Error in monitoring loop: {e}") |
| await asyncio.sleep(300) |
|
|
| async def _schedule_automation(self, automation: WorkflowAutomation, condition: Dict[str, Any]): |
| """Schedule automation based on condition""" |
| if condition['type'] == AutomationConditionType.SCHEDULED.value: |
| schedule = automation.schedule or condition.get('schedule') |
| if schedule: |
| |
| |
| from datetime import timedelta |
| |
| if automation.next_run: |
| next_run = automation.next_run + timedelta(days=1) |
| else: |
| next_run = datetime.utcnow() + timedelta(days=1) |
| automation.next_run = next_run |
| self.scheduled_automations[automation.automation_id] = { |
| 'schedule': schedule, |
| 'next_run': next_run.isoformat() |
| } |
| logger.info(f"Scheduled automation {automation.automation_id} for {next_run}") |
| return True |
| return False |
| except Exception as e: |
| logger.error(f"Operation failed: {e}") |
| log_integration_complete(audit_ctx, error=e) |
| return {'ok': False, 'error': str(e)} |
| logger.error(f"Error scheduling automation: {e}") |
| return False |
|
|
| async def _setup_event_trigger(self, automation: WorkflowAutomation, condition: Dict[str, Any]): |
| """Setup event-based trigger""" |
| event_type = condition.get('event_type', condition.get('type')) |
| if not event_type: |
| logger.warning(f"No event type specified for automation {automation.automation_id}") |
| return False |
| |
| if event_type not in self.trigger_listeners: |
| self.trigger_listeners[event_type] = { |
| 'automations': [], |
| 'callback': self._handle_event_trigger |
| } |
| if automation.automation_id not in self.trigger_listeners[event_type]['automations']: |
| self.trigger_listeners[event_type]['automations'].append(automation.automation_id) |
| self.active_triggers[automation.automation_id] = { |
| 'type': 'event', |
| 'event_type': event_type, |
| 'condition': condition, |
| 'enabled': automation.enabled |
| } |
| logger.info(f"Setup event trigger for automation {automation.automation_id}: {event_type}") |
| return True |
| except Exception as e: |
| logger.error(f"Operation failed: {e}") |
| log_integration_complete(audit_ctx, error=e) |
| return {'ok': False, 'error': str(e)} |
| logger.error(f"Error setting up event trigger: {e}") |
| return False |
|
|
| async def _setup_threshold_trigger(self, automation: WorkflowAutomation, condition: Dict[str, Any]): |
| """Setup threshold-based trigger""" |
| metric = condition.get('metric') |
| threshold = condition.get('threshold') |
| operator = condition.get('operator', 'gt') |
| if not metric or threshold is None: |
| logger.warning(f"Invalid threshold condition for automation {automation.automation_id}") |
| return False |
| self.active_triggers[automation.automation_id] = { |
| 'type': 'threshold', |
| 'metric': metric, |
| 'threshold': threshold, |
| 'operator': operator, |
| 'condition': condition, |
| 'enabled': automation.enabled |
| } |
| logger.info(f"Setup threshold trigger for automation {automation.automation_id}: {metric} {operator} {threshold}") |
| return True |
| except Exception as e: |
| logger.error(f"Operation failed: {e}") |
| log_integration_complete(audit_ctx, error=e) |
| return {'ok': False, 'error': str(e)} |
| logger.error(f"Error setting up threshold trigger: {e}") |
| return False |
|
|
| async def _setup_anomaly_trigger(self, automation: WorkflowAutomation, condition: Dict[str, Any]): |
| """Setup anomaly detection trigger""" |
| metric = condition.get('metric') |
| sensitivity = condition.get('sensitivity', 'medium') |
| if not metric: |
| logger.warning(f"Invalid anomaly condition for automation {automation.automation_id}") |
| return False |
| self.active_triggers[automation.automation_id] = { |
| 'type': 'anomaly', |
| 'metric': metric, |
| 'sensitivity': sensitivity, |
| 'condition': condition, |
| 'enabled': automation.enabled |
| } |
| logger.info(f"Setup anomaly trigger for automation {automation.automation_id}: {metric} (sensitivity: {sensitivity})") |
| return True |
| except Exception as e: |
| logger.error(f"Operation failed: {e}") |
| log_integration_complete(audit_ctx, error=e) |
| return {'ok': False, 'error': str(e)} |
| logger.error(f"Error setting up anomaly trigger: {e}") |
| return False |
|
|
| async def _setup_security_trigger(self, automation: WorkflowAutomation, condition: Dict[str, Any]): |
| """Setup security event trigger""" |
| threat_type = condition.get('threat_type') |
| severity = condition.get('severity', 'medium') |
| self.active_triggers[automation.automation_id] = { |
| 'type': 'security', |
| 'threat_type': threat_type, |
| 'severity': severity, |
| 'condition': condition, |
| 'enabled': automation.enabled |
| } |
| |
| if self.security_service and hasattr(self.security_service, 'register_security_trigger'): |
| await self.security_service.register_security_trigger( |
| automation_id=automation.automation_id, |
| threat_type=threat_type, |
| severity=severity, |
| callback=lambda event: self.execute_automation(automation.automation_id, event) |
| ) |
| logger.info(f"Setup security trigger for automation {automation.automation_id}: {threat_type} (severity: {severity})") |
| return True |
| except Exception as e: |
| logger.error(f"Operation failed: {e}") |
| log_integration_complete(audit_ctx, error=e) |
| return {'ok': False, 'error': str(e)} |
| logger.error(f"Error setting up security trigger: {e}") |
| return False |
|
|
| async def _setup_compliance_trigger(self, automation: WorkflowAutomation, condition: Dict[str, Any]): |
| """Setup compliance violation trigger""" |
| standard = condition.get('standard') |
| violation_type = condition.get('violation_type') |
| self.active_triggers[automation.automation_id] = { |
| 'type': 'compliance', |
| 'standard': standard, |
| 'violation_type': violation_type, |
| 'condition': condition, |
| 'enabled': automation.enabled |
| } |
| |
| if self.unified_service and hasattr(self.unified_service, 'register_compliance_trigger'): |
| await self.unified_service.register_compliance_trigger( |
| automation_id=automation.automation_id, |
| standard=standard, |
| violation_type=violation_type, |
| callback=lambda event: self.execute_automation(automation.automation_id, event) |
| ) |
| logger.info(f"Setup compliance trigger for automation {automation.automation_id}: {standard} - {violation_type}") |
| return True |
| except Exception as e: |
| logger.error(f"Operation failed: {e}") |
| log_integration_complete(audit_ctx, error=e) |
| return {'ok': False, 'error': str(e)} |
| logger.error(f"Error setting up compliance trigger: {e}") |
| return False |
|
|
| async def _setup_platform_triggers(self, platform: str, automation_id: str, config: Dict[str, Any]): |
| """Setup platform-specific triggers""" |
| if platform not in self.platform_integrations: |
| logger.warning(f"Unknown platform: {platform}") |
| return False |
| integration = self.platform_integrations[platform] |
| if not integration: |
| logger.warning(f"Platform {platform} integration not available") |
| return False |
| |
| trigger_type = config.get('trigger_type') |
| if trigger_type == 'webhook': |
| |
| if hasattr(integration, 'register_webhook'): |
| webhook_url = config.get('webhook_url') |
| events = config.get('events', []) |
| await integration.register_webhook(webhook_url, events) |
| logger.info(f"Registered webhook for {platform}: {webhook_url}") |
| elif trigger_type == 'polling': |
| |
| if hasattr(integration, 'start_polling'): |
| interval = config.get('polling_interval', 300) |
| await integration.start_polling(automation_id, interval) |
| logger.info(f"Started polling for {platform} with interval {interval}s") |
| elif trigger_type == 'event_subscription': |
| |
| if hasattr(integration, 'subscribe_to_events'): |
| events = config.get('events', []) |
| await integration.subscribe_to_events(automation_id, events) |
| logger.info(f"Subscribed to events for {platform}: {events}") |
| logger.info(f"Setup platform triggers for {platform}: {automation_id}") |
| return True |
| except Exception as e: |
| logger.error(f"Operation failed: {e}") |
| log_integration_complete(audit_ctx, error=e) |
| return {'ok': False, 'error': str(e)} |
| logger.error(f"Error setting up platform triggers: {e}") |
| return False |
|
|
| async def _send_automation_notifications(self, automation: WorkflowAutomation, execution: AutomationExecution): |
| """Send notifications based on automation execution""" |
| |
| notification_rules = automation.metadata.get('notification_rules', []) |
| if not notification_rules: |
| |
| if execution.status == AutomationStatus.FAILED: |
| await self._notify_via_slack( |
| message=f"Automation {automation.name} failed: {execution.error}", |
| urgency='high' |
| ) |
| return |
| |
| for rule in notification_rules: |
| should_notify = False |
| |
| if rule.get('status') == execution.status.value: |
| should_notify = True |
| |
| if rule.get('on_error') and execution.error: |
| should_notify = True |
| if should_notify: |
| channels = rule.get('channels', []) |
| message = rule.get('message', f"Automation {automation.name} executed with status: {execution.status.value}") |
| urgency = rule.get('urgency', 'medium') |
| |
| for channel in channels: |
| if channel.startswith('slack:'): |
| await self._notify_via_slack(message, urgency) |
| elif channel.startswith('email:'): |
| await self._notify_via_email(message, urgency) |
| elif channel.startswith('teams:'): |
| await self._notify_via_teams(message, urgency) |
| logger.info(f"Sent notifications for automation {automation.automation_id}") |
| return True |
| except Exception as e: |
| logger.error(f"Operation failed: {e}") |
| log_integration_complete(audit_ctx, error=e) |
| return {'ok': False, 'error': str(e)} |
| logger.error(f"Error sending automation notifications: {e}") |
| return False |
| |
| async def _update_automation_metrics(self, automation: WorkflowAutomation, execution: AutomationExecution): |
| """Update automation metrics""" |
| self.automation_metrics['executed_today'] += 1 |
| self.automation_metrics['executed_this_week'] += 1 |
| self.automation_metrics['executed_this_month'] += 1 |
| |
| |
| total_executions = sum(self.automation_metrics['executions_by_status'].values()) |
| if total_executions > 0: |
| successful_executions = self.automation_metrics['executions_by_status'].get('completed', 0) |
| self.automation_metrics['success_rate'] = successful_executions / total_executions |
| |
| |
| if execution.execution_time > 0: |
| self.automation_metrics['average_execution_time'] = ( |
| (self.automation_metrics['average_execution_time'] * (total_executions - 1) + execution.execution_time) |
| / total_executions |
| ) |
| |
| async def _log_automation_event(self, automation_id: str, event_type: str, user_id: str, details: Dict[str, Any]): |
| """Log automation event""" |
| if self.security_service: |
| await self.security_service.audit_event({ |
| 'event_type': event_type, |
| 'user_id': user_id, |
| 'resource': 'automation', |
| 'action': 'log', |
| 'result': 'success', |
| 'metadata': { |
| 'automation_id': automation_id, |
| 'details': details |
| } |
| }) |
| |
| async def get_service_info(self) -> Dict[str, Any]: |
| """Get workflow automation service information""" |
| return { |
| "name": "Workflow Automation Service", |
| "version": "6.0.0", |
| "description": "Comprehensive workflow automation integrating all enterprise services", |
| "features": [ |
| "multi_platform_integration", |
| "security_automations", |
| "compliance_automations", |
| "trigger_based_execution", |
| "scheduled_executions", |
| "ai_enhanced_automations", |
| "error_handling", |
| "monitoring", |
| "analytics" |
| ], |
| "supported_automation_types": [t.value for t in WorkflowAutomationType], |
| "supported_action_types": [t.value for t in AutomationActionType], |
| "supported_condition_types": [t.value for t in AutomationConditionType], |
| "supported_priorities": [t.value for t in AutomationPriority], |
| "status": "ACTIVE" |
| } |
| |
| async def close(self): |
| """Close workflow automation service""" |
| |
| audit_ctx = log_integration_attempt("atom_workflow_automation", "get_service_info", locals()) |
| |
| if not await circuit_breaker.is_enabled("atom_workflow_automation"): |
| logger.warning(f"Circuit breaker is open for atom_workflow_automation") |
| log_integration_complete(audit_ctx, error=Exception("Circuit breaker open")) |
| raise HTTPException( |
| status_code=503, |
| detail=f"Atom_workflow_automation integration temporarily disabled" |
| ) |
| |
| is_limited, remaining = await rate_limiter.is_rate_limited("atom_workflow_automation") |
| if is_limited: |
| logger.warning(f"Rate limit exceeded for atom_workflow_automation") |
| log_integration_complete(audit_ctx, error=Exception("Rate limit exceeded")) |
| raise HTTPException( |
| status_code=429, |
| detail=f"Rate limit exceeded for atom_workflow_automation" |
| ) |
| |
| if self.scheduler_task: |
| self.scheduler_task.cancel() |
| |
| |
| for session in self.http_sessions.values(): |
| await session.close() |
| |
| logger.info("Workflow Automation Service closed") |
|
|
| |
| |
| atom_workflow_automation_service = AtomWorkflowAutomationService({ |
| 'database': None, |
| 'cache': None, |
| 'security_service': atom_enterprise_security_service if 'atom_enterprise_security_service' in globals() else None, |
| 'unified_service': atom_enterprise_unified_service if 'atom_enterprise_unified_service' in globals() else None, |
| 'workflow_service': None, |
| 'ai_service': ai_enhanced_service if 'ai_enhanced_service' in globals() else None, |
| 'ai_integration': atom_ai_integration if 'atom_ai_integration' in globals() else None |
| }) |
| except Exception as e: |
| logger.warning(f"Could not initialize global workflow automation service: {e}") |
| atom_workflow_automation_service = None |
| |
| audit_ctx = log_integration_attempt("atom_workflow_automation", "close", locals()) |
| |
| if not await circuit_breaker.is_enabled("atom_workflow_automation"): |
| logger.warning(f"Circuit breaker is open for atom_workflow_automation") |
| log_integration_complete(audit_ctx, error=Exception("Circuit breaker open")) |
| raise HTTPException( |
| status_code=503, |
| detail=f"Atom_workflow_automation integration temporarily disabled" |
| ) |
| |
| is_limited, remaining = await rate_limiter.is_rate_limited("atom_workflow_automation") |
| if is_limited: |
| logger.warning(f"Rate limit exceeded for atom_workflow_automation") |
| log_integration_complete(audit_ctx, error=Exception("Rate limit exceeded")) |
| raise HTTPException( |
| status_code=429, |
| detail=f"Rate limit exceeded for atom_workflow_automation" |
| ) |