Spaces:
Sleeping
Sleeping
| #!/usr/bin/env python3 | |
| """ | |
| Local Production Setup - Working Version | |
| Advanced Workflow Automation - Local Production Environment | |
| This script creates a local production-ready environment: | |
| - Local directory structure | |
| - Production configuration | |
| - Security settings | |
| - Monitoring setup | |
| - Deployment scripts | |
| """ | |
| from datetime import datetime | |
| import json | |
| import os | |
| from pathlib import Path | |
| import subprocess | |
| import sys | |
| import uuid | |
| print("🚀 LOCAL PRODUCTION SETUP") | |
| print("=" * 80) | |
| print("Setting up local production environment for Advanced Workflow Automation") | |
| print("=" * 80) | |
| # Use local paths that don't require sudo | |
| BASE_PATH = Path.home() / "atom-production" | |
| PROD_PATH = BASE_PATH / "production" | |
| CONFIG_PATH = PROD_PATH / "config" | |
| LOGS_PATH = PROD_PATH / "logs" | |
| BACKUPS_PATH = PROD_PATH / "backups" | |
| SCRIPTS_PATH = PROD_PATH / "scripts" | |
| SSL_PATH = PROD_PATH / "ssl" | |
| try: | |
| print("\n📁 Creating Local Production Directory Structure...") | |
| print("-" * 60) | |
| # Create directory structure | |
| directories = [ | |
| BASE_PATH, | |
| PROD_PATH, | |
| CONFIG_PATH, | |
| LOGS_PATH, | |
| BACKUPS_PATH, | |
| SCRIPTS_PATH, | |
| SSL_PATH, | |
| PROD_PATH / "data", | |
| PROD_PATH / "temp", | |
| PROD_PATH / "static", | |
| PROD_PATH / "venv" | |
| ] | |
| for directory in directories: | |
| try: | |
| directory.mkdir(parents=True, exist_ok=True) | |
| print(f" ✅ Created: {directory}") | |
| except Exception as e: | |
| print(f" ❌ Error creating {directory}: {str(e)}") | |
| print("\n⚙️ Generating Production Configuration...") | |
| print("-" * 60) | |
| # Main production configuration | |
| prod_config = { | |
| "environment": "production", | |
| "debug": False, | |
| "log_level": "INFO", | |
| "timezone": "UTC", | |
| "deployment_path": str(PROD_PATH), | |
| # Database Configuration (PostgreSQL) | |
| "database": { | |
| "host": "localhost", | |
| "port": 5432, | |
| "name": "atom_production", | |
| "user": "atom_user", | |
| "password": "CHANGE_THIS_PASSWORD", | |
| "pool_size": 20, | |
| "max_overflow": 30, | |
| "ssl_mode": "prefer" | |
| }, | |
| # Redis Configuration | |
| "redis": { | |
| "host": "localhost", | |
| "port": 6379, | |
| "db": 0, | |
| "password": "CHANGE_THIS_REDIS_PASSWORD", | |
| "max_connections": 100, | |
| "decode_responses": True | |
| }, | |
| # WebSocket Configuration | |
| "websocket": { | |
| "host": "127.0.0.1", | |
| "port": 8765, | |
| "ssl_enabled": False, # Disabled for local development | |
| "cert_file": str(SSL_PATH / "cert.pem"), | |
| "key_file": str(SSL_PATH / "key.pem"), | |
| "ping_interval": 20, | |
| "ping_timeout": 10 | |
| }, | |
| # API Configuration | |
| "api": { | |
| "host": "127.0.0.1", | |
| "port": 8000, | |
| "ssl_enabled": False, # Disabled for local development | |
| "workers": 4, | |
| "worker_class": "uvicorn.workers.UvicornWorker", | |
| "reload": False | |
| }, | |
| # Security Configuration | |
| "security": { | |
| "secret_key": str(uuid.uuid4()), | |
| "jwt_secret_key": str(uuid.uuid4()), | |
| "jwt_expiration_hours": 24, | |
| "session_timeout_minutes": 30, | |
| "password_min_length": 12, | |
| "max_login_attempts": 5, | |
| "lockout_duration_minutes": 15, | |
| "bcrypt_rounds": 12 | |
| }, | |
| # Performance Configuration | |
| "performance": { | |
| "max_concurrent_workflows": 100, | |
| "workflow_timeout_minutes": 60, | |
| "task_queue_max_size": 1000, | |
| "cache_ttl_seconds": 3600, | |
| "connection_pool_size": 50, | |
| "max_execution_time": 3600 | |
| }, | |
| # Monitoring Configuration | |
| "monitoring": { | |
| "prometheus_enabled": True, | |
| "prometheus_port": 9090, | |
| "health_check_port": 8080, | |
| "metrics_collection_enabled": True, | |
| "log_analytics_enabled": True, | |
| "performance_monitoring": True | |
| }, | |
| # Backup Configuration | |
| "backup": { | |
| "enabled": True, | |
| "schedule_hours": 24, | |
| "retention_days": 30, | |
| "auto_recovery_enabled": True, | |
| "backup_path": str(BACKUPS_PATH), | |
| "compression_enabled": True | |
| }, | |
| # Email Configuration (for notifications) | |
| "email": { | |
| "smtp_server": "smtp.gmail.com", | |
| "smtp_port": 587, | |
| "smtp_use_tls": True, | |
| "smtp_username": "noreply@atom.com", | |
| "smtp_password": "CHANGE_THIS_APP_PASSWORD", | |
| "from_email": "noreply@atom.com", | |
| "notification_enabled": True | |
| }, | |
| # Third-party Service Configuration | |
| "services": { | |
| "gmail": { | |
| "api_key": "CHANGE_GMAIL_API_KEY", | |
| "client_id": "CHANGE_GMAIL_CLIENT_ID", | |
| "client_secret": "CHANGE_GMAIL_CLIENT_SECRET" | |
| }, | |
| "slack": { | |
| "bot_token": "CHANGE_SLACK_BOT_TOKEN", | |
| "signing_secret": "CHANGE_SLACK_SIGNING_SECRET" | |
| }, | |
| "github": { | |
| "personal_access_token": "CHANGE_GITHUB_TOKEN", | |
| "webhook_secret": "CHANGE_GITHUB_WEBHOOK_SECRET" | |
| }, | |
| "asana": { | |
| "api_key": "CHANGE_ASANA_API_KEY", | |
| "workspace_id": "CHANGE_ASANA_WORKSPACE_ID" | |
| }, | |
| "trello": { | |
| "api_key": "CHANGE_TRELLO_API_KEY", | |
| "token": "CHANGE_TRELLO_TOKEN" | |
| }, | |
| "notion": { | |
| "api_key": "CHANGE_NOTION_API_KEY", | |
| "integration_token": "CHANGE_NOTION_INTEGRATION_TOKEN" | |
| } | |
| } | |
| } | |
| # Save main configuration | |
| config_file = CONFIG_PATH / "production.json" | |
| with open(config_file, 'w') as f: | |
| json.dump(prod_config, f, indent=2) | |
| print(f" ✅ Created: {config_file}") | |
| # Environment variables file | |
| env_content = f""" | |
| # Local Production Environment Variables | |
| export ATOM_ENV=production | |
| export ATOM_DEBUG=false | |
| export ATOM_LOG_LEVEL=INFO | |
| # Database | |
| export DATABASE_URL=postgresql://{prod_config['database']['user']}:{prod_config['database']['password']}@{prod_config['database']['host']}:{prod_config['database']['port']}/{prod_config['database']['name']} | |
| export DATABASE_POOL_SIZE={prod_config['database']['pool_size']} | |
| # Redis | |
| export REDIS_URL=redis://:{prod_config['redis']['password']}@{prod_config['redis']['host']}:{prod_config['redis']['port']}/{prod_config['redis']['db']} | |
| # Security | |
| export SECRET_KEY={prod_config['security']['secret_key']} | |
| export JWT_SECRET_KEY={prod_config['security']['jwt_secret_key']} | |
| # WebSocket | |
| export WEBSOCKET_HOST={prod_config['websocket']['host']} | |
| export WEBSOCKET_PORT={prod_config['websocket']['port']} | |
| export WEBSOCKET_SSL_ENABLED={prod_config['websocket']['ssl_enabled']} | |
| # API | |
| export API_HOST={prod_config['api']['host']} | |
| export API_PORT={prod_config['api']['port']} | |
| # Performance | |
| export MAX_CONCURRENT_WORKFLOWS={prod_config['performance']['max_concurrent_workflows']} | |
| export WORKFLOW_TIMEOUT_MINUTES={prod_config['performance']['workflow_timeout_minutes']} | |
| # Monitoring | |
| export PROMETHEUS_ENABLED={prod_config['monitoring']['prometheus_enabled']} | |
| export PROMETHEUS_PORT={prod_config['monitoring']['prometheus_port']} | |
| export HEALTH_CHECK_PORT={prod_config['monitoring']['health_check_port']} | |
| export SMTP_SERVER={prod_config['email']['smtp_server']} | |
| export SMTP_PORT={prod_config['email']['smtp_port']} | |
| export SMTP_USERNAME={prod_config['email']['smtp_username']} | |
| export SMTP_PASSWORD={prod_config['email']['smtp_password']} | |
| # Third-party Services | |
| export GMAIL_API_KEY={prod_config['services']['gmail']['api_key']} | |
| export SLACK_BOT_TOKEN={prod_config['services']['slack']['bot_token']} | |
| export GITHUB_TOKEN={prod_config['services']['github']['personal_access_token']} | |
| export ASANA_API_KEY={prod_config['services']['asana']['api_key']} | |
| export TRELLO_API_KEY={prod_config['services']['trello']['api_key']} | |
| export NOTION_API_KEY={prod_config['services']['notion']['api_key']} | |
| # Paths | |
| export ATOM_DEPLOYMENT_PATH={prod_config['deployment_path']} | |
| export ATOM_CONFIG_PATH={prod_config['config']} | |
| export ATOM_LOGS_PATH={prod_config['logs']} | |
| export ATOM_BACKUPS_PATH={prod_config['backups']} | |
| """ | |
| env_file = CONFIG_PATH / ".env" | |
| with open(env_file, 'w') as f: | |
| f.write(env_content.strip()) | |
| print(f" ✅ Created: {env_file}") | |
| print("\n🔒 Setting Up Security Configuration...") | |
| print("-" * 60) | |
| # Security policies | |
| security_policies = { | |
| "authentication": { | |
| "password_policy": { | |
| "min_length": prod_config['security']['password_min_length'], | |
| "require_uppercase": True, | |
| "require_lowercase": True, | |
| "require_numbers": True, | |
| "require_symbols": True, | |
| "max_age_days": 90, | |
| "prevent_reuse": True, | |
| "reuse_count": 5 | |
| }, | |
| "session_policy": { | |
| "timeout_minutes": prod_config['security']['session_timeout_minutes'], | |
| "max_concurrent_sessions": 3, | |
| "require_reauth_minutes": 60, | |
| "secure_cookies": True, | |
| "http_only_cookies": True | |
| }, | |
| "lockout_policy": { | |
| "max_attempts": prod_config['security']['max_login_attempts'], | |
| "lockout_duration_minutes": prod_config['security']['lockout_duration_minutes'], | |
| "progressive_lockout": True, | |
| "ip_based_lockout": True | |
| } | |
| }, | |
| "authorization": { | |
| "rbac_enabled": True, | |
| "default_roles": ["user", "admin", "operator"], | |
| "principle_of_least_privilege": True, | |
| "role_hierarchy": { | |
| "user": [], | |
| "operator": ["user"], | |
| "admin": ["user", "operator"] | |
| } | |
| }, | |
| "api_security": { | |
| "rate_limiting": { | |
| "enabled": True, | |
| "requests_per_minute": 100, | |
| "requests_per_hour": 1000, | |
| "burst_size": 20, | |
| "per_user_limiting": True | |
| }, | |
| "cors": { | |
| "allowed_origins": ["http://localhost:3000", "http://localhost:8080"], | |
| "allowed_methods": ["GET", "POST", "PUT", "DELETE", "OPTIONS"], | |
| "allowed_headers": ["Authorization", "Content-Type", "X-Requested-With"], | |
| "max_age_seconds": 3600, | |
| "credentials_allowed": True | |
| }, | |
| "request_validation": { | |
| "max_request_size_mb": 10, | |
| "max_header_size_kb": 8, | |
| "validate_content_type": True, | |
| "sanitize_inputs": True | |
| } | |
| }, | |
| "encryption": { | |
| "at_rest": { | |
| "database_encryption": True, | |
| "file_encryption": True, | |
| "key_rotation_days": 90 | |
| }, | |
| "in_transit": { | |
| "tls_version": "1.2", | |
| "cipher_suites": ["ECDHE-RSA-AES256-GCM-SHA512", "ECDHE-RSA-AES256-GCM-SHA384"], | |
| "hsts_enabled": True, | |
| "hsts_max_age_seconds": 31536000 | |
| } | |
| } | |
| } | |
| security_file = CONFIG_PATH / "security_policies.json" | |
| with open(security_file, 'w') as f: | |
| json.dump(security_policies, f, indent=2) | |
| print(f" ✅ Created: {security_file}") | |
| print("\n📊 Setting Up Monitoring Configuration...") | |
| print("-" * 60) | |
| # Prometheus configuration | |
| prometheus_config = { | |
| "global": { | |
| "scrape_interval": "15s", | |
| "evaluation_interval": "15s" | |
| }, | |
| "rule_files": [f"{CONFIG_PATH}/workflow_alerts.yml"], | |
| "scrape_configs": [ | |
| { | |
| "job_name": "atom-api", | |
| "static_configs": [{"targets": ["localhost:8000"]}], | |
| "metrics_path": "/metrics", | |
| "scrape_interval": "30s" | |
| }, | |
| { | |
| "job_name": "atom-websocket", | |
| "static_configs": [{"targets": ["localhost:8765"]}], | |
| "metrics_path": "/metrics", | |
| "scrape_interval": "30s" | |
| }, | |
| { | |
| "job_name": "atom-health", | |
| "static_configs": [{"targets": ["localhost:8080"]}], | |
| "metrics_path": "/metrics", | |
| "scrape_interval": "60s" | |
| } | |
| ] | |
| } | |
| prometheus_file = CONFIG_PATH / "prometheus.yml" | |
| with open(prometheus_file, 'w') as f: | |
| json.dump(prometheus_config, f, indent=2) | |
| print(f" ✅ Created: {prometheus_file}") | |
| # Alert rules | |
| alert_rules = { | |
| "groups": [ | |
| { | |
| "name": "atom_workflow_alerts", | |
| "rules": [ | |
| { | |
| "alert": "WorkflowExecutionFailure", | |
| "expr": "workflow_execution_failures_total > 0", | |
| "for": "5m", | |
| "labels": {"severity": "warning"}, | |
| "annotations": { | |
| "summary": "Workflow execution failed", | |
| "description": "Workflow {{ $labels.workflow_id }} has failed {{ $value }} times in last 5 minutes" | |
| } | |
| }, | |
| { | |
| "alert": "HighWorkflowExecutionTime", | |
| "expr": "workflow_execution_duration_seconds > 300", | |
| "for": "10m", | |
| "labels": {"severity": "warning"}, | |
| "annotations": { | |
| "summary": "High workflow execution time", | |
| "description": "Workflow {{ $labels.workflow_id }} has been running for {{ $value }} seconds" | |
| } | |
| }, | |
| { | |
| "alert": "WebSocketConnectionFailure", | |
| "expr": "websocket_connection_errors_total > 10", | |
| "for": "2m", | |
| "labels": {"severity": "critical"}, | |
| "annotations": { | |
| "summary": "High WebSocket connection errors", | |
| "description": "{{ $value }} WebSocket connection errors in last 2 minutes" | |
| } | |
| } | |
| ] | |
| } | |
| ] | |
| } | |
| alerts_file = CONFIG_PATH / "workflow_alerts.yml" | |
| with open(alerts_file, 'w') as f: | |
| json.dump(alert_rules, f, indent=2) | |
| print(f" ✅ Created: {alerts_file}") | |
| print("\n🚀 Creating Deployment Scripts...") | |
| print("-" * 60) | |
| # Local deployment script | |
| deploy_script = f"""#!/bin/bash | |
| # Local Production Deployment Script | |
| set -e | |
| DEPLOYMENT_PATH="{PROD_PATH}" | |
| LOG_FILE="$DEPLOYMENT_PATH/logs/deploy.log" | |
| echo "🚀 Starting Atom Workflow Automation Local Deployment..." | |
| echo "$(date): Deployment started" >> $LOG_FILE | |
| log() {{ | |
| echo "$1" | |
| echo "$(date): $1" >> $LOG_FILE | |
| }} | |
| # Create logs directory | |
| mkdir -p "$DEPLOYMENT_PATH/logs" | |
| # Stop existing processes | |
| log "🛑 Stopping existing processes..." | |
| pkill -f "setup_websocket_server.py" || true | |
| pkill -f "health_check_server.py" || true | |
| pkill -f "uvicorn.*main:app" || true | |
| sleep 2 | |
| # Create virtual environment if it doesn't exist | |
| if [ ! -d "$DEPLOYMENT_PATH/venv" ]; then | |
| log "🐍 Creating virtual environment..." | |
| python3 -m venv "$DEPLOYMENT_PATH/venv" | |
| fi | |
| # Activate virtual environment | |
| log "🔧 Activating virtual environment..." | |
| source "$DEPLOYMENT_PATH/venv/bin/activate" | |
| # Install dependencies | |
| log "📦 Installing Python dependencies..." | |
| pip install --upgrade pip | |
| pip install fastapi uvicorn websockets aiohttp psutil prometheus-client | |
| pip install psycopg2-binary redis cryptography pyyaml | |
| pip install python-jose[cryptography] passlib[bcrypt] python-multipart | |
| # Copy required files | |
| log "📋 Copying application files..." | |
| cp -r /home/developer/projects/atom/atom/*.py "$DEPLOYMENT_PATH/" 2>/dev/null || true | |
| # Load environment variables | |
| if [ -f "$DEPLOYMENT_PATH/config/.env" ]; then | |
| log "🔐 Loading environment variables..." | |
| set -a | |
| source "$DEPLOYMENT_PATH/config/.env" | |
| set +a | |
| else | |
| log "⚠️ Environment file not found, using defaults" | |
| export ATOM_ENV=production | |
| export WEBSOCKET_HOST=127.0.0.1 | |
| export WEBSOCKET_PORT=8765 | |
| export HEALTH_CHECK_PORT=8080 | |
| export API_HOST=127.0.0.1 | |
| export API_PORT=8000 | |
| fi | |
| # Start WebSocket server in background | |
| log "🌐 Starting WebSocket server..." | |
| cd "$DEPLOYMENT_PATH" | |
| nohup python setup_websocket_server.py > logs/websocket.log 2>&1 & | |
| WEBSOCKET_PID=$! | |
| echo $WEBSOCKET_PID > logs/websocket.pid | |
| log "WebSocket server started with PID: $WEBSOCKET_PID" | |
| # Start health check server in background | |
| log "🏥 Starting health check server..." | |
| nohup python -c " | |
| import json | |
| import asyncio | |
| import aiohttp | |
| from datetime import datetime | |
| from pathlib import Path | |
| class HealthCheckServer: | |
| def __init__(self): | |
| self.port = 8080 | |
| async def health_check(self, request): | |
| status = {{ | |
| 'status': 'healthy', | |
| 'timestamp': datetime.now().isoformat(), | |
| 'version': '1.0.0', | |
| 'environment': 'local_production', | |
| 'services': {{ | |
| 'websocket': 'running', | |
| 'api': 'starting', | |
| 'database': 'checking' | |
| }} | |
| }} | |
| return aiohttp.web.json_response(status) | |
| async def start(self): | |
| app = aiohttp.web.Application() | |
| app.router.add_get('/health', self.health_check) | |
| runner = aiohttp.web.AppRunner(app) | |
| await runner.setup() | |
| site = aiohttp.web.TCPSite(runner, '127.0.0.1', self.port) | |
| await site.start() | |
| print(f'Health check server started on port {{self.port}}') | |
| if __name__ == '__main__': | |
| server = HealthCheckServer() | |
| asyncio.run(server.start()) | |
| " > logs/health_check.log 2>&1 & | |
| HEALTH_PID=$! | |
| echo $HEALTH_PID > logs/health_check.pid | |
| log "Health check server started with PID: $HEALTH_PID" | |
| # Wait for services to start | |
| log "⏳ Waiting for services to start..." | |
| sleep 5 | |
| # Health checks | |
| log "🏥 Running health checks..." | |
| # Check WebSocket server | |
| if curl -f http://localhost:8765/health > /dev/null 2>&1; then | |
| log "✅ WebSocket server is healthy" | |
| else | |
| log "⚠️ WebSocket server might not be ready (normal for startup)" | |
| fi | |
| # Check health check server | |
| if curl -f http://localhost:8080/health > /dev/null 2>&1; then | |
| log "✅ Health check server is healthy" | |
| else | |
| log "⚠️ Health check server might not be ready (normal for startup)" | |
| fi | |
| log "🎉 Local deployment completed successfully!" | |
| log "📊 Service endpoints:" | |
| log " WebSocket: ws://localhost:8765" | |
| log " Health Check: http://localhost:8080/health" | |
| log " Configuration: $DEPLOYMENT_PATH/config/" | |
| log " Logs: $DEPLOYMENT_PATH/logs/" | |
| echo "$(date): Deployment completed" >> $LOG_FILE | |
| # Display status | |
| echo "" | |
| echo "🚀 DEPLOYMENT STATUS" | |
| echo "==================" | |
| echo "WebSocket Server PID: $WEBSOCKET_PID" | |
| echo "Health Check Server PID: $HEALTH_PID" | |
| echo "" | |
| echo "📊 SERVICE ENDPOINTS:" | |
| echo "WebSocket: ws://localhost:8765" | |
| echo "Health Check: http://localhost:8080/health" | |
| echo "" | |
| echo "🔧 MANAGEMENT COMMANDS:" | |
| echo "View WebSocket logs: tail -f $DEPLOYMENT_PATH/logs/websocket.log" | |
| echo "View health check logs: tail -f $DEPLOYMENT_PATH/logs/health_check.log" | |
| echo "Stop services: kill \$(cat $DEPLOYMENT_PATH/logs/websocket.pid) kill \$(cat $DEPLOYMENT_PATH/logs/health_check.pid)" | |
| echo "" | |
| echo "🎯 NEXT STEPS:" | |
| echo "1. Configure API keys in: $DEPLOYMENT_PATH/config/.env" | |
| echo "2. Test WebSocket server: curl http://localhost:8765/health" | |
| echo "3. Test health check: curl http://localhost:8080/health" | |
| echo "4. Run monitoring: $DEPLOYMENT_PATH/scripts/monitor.sh" | |
| echo "5. Create backup: $DEPLOYMENT_PATH/scripts/backup.sh" | |
| """ | |
| deploy_file = SCRIPTS_PATH / "deploy.sh" | |
| with open(deploy_file, 'w') as f: | |
| f.write(deploy_script) | |
| # Make script executable | |
| try: | |
| os.chmod(deploy_file, 0o755) | |
| print(f" ✅ Created: {deploy_file} (executable)") | |
| except: | |
| print(f" ✅ Created: {deploy_file} (run: chmod +x to make executable)") | |
| # Monitoring script | |
| monitor_script = f"""#!/bin/bash | |
| # Local Monitoring Script | |
| DEPLOYMENT_PATH="{PROD_PATH}" | |
| LOG_FILE="$DEPLOYMENT_PATH/logs/monitoring.log" | |
| log() {{ | |
| echo "$1" | |
| echo "$(date): $1" >> $LOG_FILE | |
| }} | |
| check_service() {{ | |
| local service_name=$1 | |
| local port=$2 | |
| if curl -f http://localhost:$port/health > /dev/null 2>&1; then | |
| log "✅ $service_name is healthy" | |
| return 0 | |
| else | |
| log "❌ $service_name is unhealthy" | |
| return 1 | |
| fi | |
| }} | |
| check_resources() {{ | |
| # CPU usage (macOS) | |
| if command -v sysctl > /dev/null; then | |
| CPU_USAGE=$(sysctl -n hw.cpufrequency | awk '{{print $1}}') | |
| if [ $CPU_USAGE -gt 0 ]; then | |
| log "📊 CPU Frequency: $CPU_USAGE MHz" | |
| fi | |
| fi | |
| # Memory usage (macOS) | |
| if command -v vm_stat > /dev/null; then | |
| MEMORY_INFO=$(vm_stat | grep "Pages free:") | |
| if [ -n "$MEMORY_INFO" ]; then | |
| log "📊 Memory info available" | |
| fi | |
| fi | |
| # Disk usage | |
| if command -v df > /dev/null; then | |
| DISK_USAGE=$(df -h / | awk 'NR==2 {{print $5}}' | sed 's/%//') | |
| if [ $DISK_USAGE -gt 80 ]; then | |
| log "⚠️ High disk usage: $DISK_USAGE%" | |
| else | |
| log "✅ Disk usage: $DISK_USAGE%" | |
| fi | |
| fi | |
| }} | |
| log "🔍 Starting system monitoring..." | |
| # Check services | |
| check_service "WebSocket Server" 8765 | |
| check_service "Health Check" 8080 | |
| # Check resources | |
| check_resources | |
| log "✅ Monitoring completed" | |
| """ | |
| monitor_file = SCRIPTS_PATH / "monitor.sh" | |
| with open(monitor_file, 'w') as f: | |
| f.write(monitor_script) | |
| try: | |
| os.chmod(monitor_file, 0o755) | |
| print(f" ✅ Created: {monitor_file} (executable)") | |
| except: | |
| print(f" ✅ Created: {monitor_file} (run: chmod +x to make executable)") | |
| # Backup script | |
| backup_script = f"""#!/bin/bash | |
| # Local Backup Script | |
| DEPLOYMENT_PATH="{PROD_PATH}" | |
| BACKUP_PATH="{BACKUPS_PATH}" | |
| LOG_FILE="$DEPLOYMENT_PATH/logs/backup.log" | |
| log() {{ | |
| echo "$1" | |
| echo "$(date): $1" >> $LOG_FILE | |
| }} | |
| log "📦 Starting backup process..." | |
| # Create backup directories | |
| mkdir -p "$BACKUP_PATH" | |
| mkdir -p "$BACKUP_PATH/config" | |
| mkdir -p "$BACKUP_PATH/scripts" | |
| TIMESTAMP=$(date +%Y%m%d_%H%M%S) | |
| # Configuration backup | |
| log "⚙️ Creating configuration backup..." | |
| tar -czf "$BACKUP_PATH/config/config_backup_$TIMESTAMP.tar.gz" "$DEPLOYMENT_PATH/config/" | |
| # Scripts backup | |
| log "🚀 Creating scripts backup..." | |
| tar -czf "$BACKUP_PATH/scripts/scripts_backup_$TIMESTAMP.tar.gz" "$DEPLOYMENT_PATH/scripts/" | |
| # Logs backup (last 7 days) | |
| log "📄 Creating logs backup..." | |
| find "$DEPLOYMENT_PATH/logs" -name "*.log" -mtime -7 -print0 | tar -czf "$BACKUP_PATH/logs/logs_backup_$TIMESTAMP.tar.gz" --null -T - | |
| # Cleanup old backups (keep last 30 days) | |
| log "🧹 Cleaning up old backups..." | |
| find "$BACKUP_PATH" -name "*.gz" -mtime +30 -delete 2>/dev/null || true | |
| log "✅ Backup completed successfully" | |
| log "📊 Backup size: $(du -sh $BACKUP_PATH | cut -f1)" | |
| log "📁 Backup location: $BACKUP_PATH" | |
| """ | |
| backup_file = SCRIPTS_PATH / "backup.sh" | |
| with open(backup_file, 'w') as f: | |
| f.write(backup_script) | |
| try: | |
| os.chmod(backup_file, 0o755) | |
| print(f" ✅ Created: {backup_file} (executable)") | |
| except: | |
| print(f" ✅ Created: {backup_file} (run: chmod +x to make executable)") | |
| # Stop script | |
| stop_script = f"""#!/bin/bash | |
| # Stop Services Script | |
| DEPLOYMENT_PATH="{PROD_PATH}" | |
| LOG_FILE="$DEPLOYMENT_PATH/logs/stop.log" | |
| log() {{ | |
| echo "$1" | |
| echo "$(date): $1" >> $LOG_FILE | |
| }} | |
| log "🛑 Stopping Atom Workflow Automation services..." | |
| # Stop WebSocket server | |
| if [ -f "$DEPLOYMENT_PATH/logs/websocket.pid" ]; then | |
| WEBSOCKET_PID=$(cat "$DEPLOYMENT_PATH/logs/websocket.pid") | |
| if kill -0 $WEBSOCKET_PID 2>/dev/null; then | |
| log "🛑 Stopping WebSocket server (PID: $WEBSOCKET_PID)..." | |
| kill $WEBSOCKET_PID | |
| sleep 2 | |
| # Force kill if still running | |
| kill -9 $WEBSOCKET_PID 2>/dev/null || true | |
| fi | |
| rm -f "$DEPLOYMENT_PATH/logs/websocket.pid" | |
| fi | |
| # Stop health check server | |
| if [ -f "$DEPLOYMENT_PATH/logs/health_check.pid" ]; then | |
| HEALTH_PID=$(cat "$DEPLOYMENT_PATH/logs/health_check.pid") | |
| if kill -0 $HEALTH_PID 2>/dev/null; then | |
| log "🛑 Stopping health check server (PID: $HEALTH_PID)..." | |
| kill $HEALTH_PID | |
| sleep 2 | |
| # Force kill if still running | |
| kill -9 $HEALTH_PID 2>/dev/null || true | |
| fi | |
| rm -f "$DEPLOYMENT_PATH/logs/health_check.pid" | |
| fi | |
| # Kill any remaining processes | |
| log "🧹 Cleaning up remaining processes..." | |
| pkill -f "setup_websocket_server.py" 2>/dev/null || true | |
| pkill -f "health_check_server.py" 2>/dev/null || true | |
| pkill -f "uvicorn.*main:app" 2>/dev/null || true | |
| log "✅ All services stopped successfully" | |
| """ | |
| stop_file = SCRIPTS_PATH / "stop.sh" | |
| with open(stop_file, 'w') as f: | |
| f.write(stop_script) | |
| try: | |
| os.chmod(stop_file, 0o755) | |
| print(f" ✅ Created: {stop_file} (executable)") | |
| except: | |
| print(f" ✅ Created: {stop_file} (run: chmod +x to make executable)") | |
| print("\n📝 Creating Documentation...") | |
| print("-" * 60) | |
| # README file | |
| readme_content = f"""# Atom Workflow Automation - Local Production | |
| ## Overview | |
| This is a local production-ready environment for the Advanced Workflow Automation system. | |
| ## Directory Structure | |
| ``` | |
| {PROD_PATH}/ | |
| ├── config/ # Configuration files | |
| ├── logs/ # Log files | |
| ├── backups/ # Backup files | |
| ├── scripts/ # Management scripts | |
| ├── ssl/ # SSL certificates | |
| ├── data/ # Application data | |
| ├── temp/ # Temporary files | |
| ├── static/ # Static assets | |
| └── venv/ # Python virtual environment | |
| ``` | |
| ## Quick Start | |
| ### 1. Environment Setup | |
| ```bash | |
| # Activate virtual environment | |
| source {PROD_PATH}/venv/bin/activate | |
| # Load environment variables | |
| source {CONFIG_PATH}/.env | |
| ``` | |
| ### 2. Deploy Application | |
| ```bash | |
| # Deploy all services | |
| {SCRIPTS_PATH}/deploy.sh | |
| ``` | |
| ### 3. Verify Deployment | |
| ```bash | |
| # Test WebSocket server | |
| curl http://localhost:8765/health | |
| # Test health check server | |
| curl http://localhost:8080/health | |
| # Run monitoring | |
| {SCRIPTS_PATH}/monitor.sh | |
| ``` | |
| ## Service Endpoints | |
| - WebSocket Server: ws://localhost:8765 | |
| - Health Check: http://localhost:8080/health | |
| - API Server: http://localhost:8000 (when started) | |
| ## Management Scripts | |
| ### Deployment | |
| ```bash | |
| {SCRIPTS_PATH}/deploy.sh | |
| ``` | |
| ### Monitoring | |
| ```bash | |
| {SCRIPTS_PATH}/monitor.sh | |
| ``` | |
| ### Backup | |
| ```bash | |
| {SCRIPTS_PATH}/backup.sh | |
| ``` | |
| ### Stop Services | |
| ```bash | |
| {SCRIPTS_PATH}/stop.sh | |
| ``` | |
| ## Configuration | |
| ### Main Configuration | |
| - File: `{CONFIG_PATH}/production.json` | |
| - Contains all production settings | |
| ### Environment Variables | |
| - File: `{CONFIG_PATH}/.env` | |
| - Contains sensitive data and API keys | |
| ### Security Policies | |
| - File: `{CONFIG_PATH}/security_policies.json` | |
| - Contains authentication and authorization settings | |
| ### Monitoring Configuration | |
| - File: `{CONFIG_PATH}/prometheus.yml` | |
| - Contains Prometheus scrape configurations | |
| ## Logs | |
| - WebSocket Server: `{LOGS_PATH}/websocket.log` | |
| - Health Check: `{LOGS_PATH}/health_check.log` | |
| - Deployment: `{LOGS_PATH}/deploy.log` | |
| - Monitoring: `{LOGS_PATH}/monitoring.log` | |
| - Backup: `{LOGS_PATH}/backup.log` | |
| ## Backups | |
| - Location: `{BACKUPS_PATH}/` | |
| - Schedule: Every 24 hours | |
| - Retention: 30 days | |
| ## Third-party Services | |
| You need to configure API keys for the following services: | |
| 1. **Gmail**: Update `GMAIL_API_KEY` in `.env` | |
| 2. **Slack**: Update `SLACK_BOT_TOKEN` in `.env` | |
| 3. **GitHub**: Update `GITHUB_TOKEN` in `.env` | |
| 4. **Asana**: Update `ASANA_API_KEY` in `.env` | |
| 5. **Trello**: Update `TRELLO_API_KEY` in `.env` | |
| 6. **Notion**: Update `NOTION_API_KEY` in `.env` | |
| ## Database Setup | |
| For local development, you can use Docker to run PostgreSQL: | |
| ```bash | |
| # Run PostgreSQL in Docker | |
| docker run -d \\ | |
| --name atom-postgres \\ | |
| -e POSTGRES_DB=atom_production \\ | |
| -e POSTGRES_USER=atom_user \\ | |
| -e POSTGRES_PASSWORD=CHANGE_THIS_PASSWORD \\ | |
| -p 5432:5432 \\ | |
| postgres:13 | |
| # Run Redis in Docker | |
| docker run -d \\ | |
| --name atom-redis \\ | |
| -p 6379:6379 \\ | |
| redis:6-alpine | |
| ``` | |
| ## Monitoring | |
| ### Prometheus | |
| - Port: 9090 | |
| - URL: http://localhost:9090 | |
| ### Health Checks | |
| - Port: 8080 | |
| - URL: http://localhost:8080/health | |
| ### Metrics | |
| - API Metrics: http://localhost:8000/metrics | |
| - WebSocket Metrics: http://localhost:8765/metrics | |
| ## Troubleshooting | |
| ### Services Won't Start | |
| 1. Check logs: `tail -f {LOGS_PATH}/deploy.log` | |
| 2. Verify ports: `lsof -i :8765` and `lsof -i :8080` | |
| 3. Check environment: `source {CONFIG_PATH}/.env` | |
| ### Connection Issues | |
| 1. Stop and restart services: `{SCRIPTS_PATH}/stop.sh && {SCRIPTS_PATH}/deploy.sh` | |
| 2. Check firewall settings | |
| 3. Verify no port conflicts | |
| ### Performance Issues | |
| 1. Monitor resources: `{SCRIPTS_PATH}/monitor.sh` | |
| 2. Check logs for errors | |
| 3. Review configuration settings | |
| ## Security | |
| ### Passwords | |
| - Change all default passwords in configuration files | |
| - Use strong, unique passwords | |
| ### SSL/TLS | |
| - For local development, SSL is disabled | |
| - For production, enable SSL and configure certificates | |
| ### API Keys | |
| - Never commit API keys to version control | |
| - Use environment variables for sensitive data | |
| ## Support | |
| For issues: | |
| 1. Check logs in `{LOGS_PATH}/` | |
| 2. Run monitoring script: `{SCRIPTS_PATH}/monitor.sh` | |
| 3. Review configuration in `{CONFIG_PATH}/` | |
| ## Development | |
| ### Adding New Services | |
| 1. Update configuration files | |
| 2. Add service to deployment script | |
| 3. Update monitoring configuration | |
| 4. Test thoroughly | |
| ### Modifying Configuration | |
| 1. Edit `{CONFIG_PATH}/production.json` | |
| 2. Update `.env` if needed | |
| 3. Restart services: `{SCRIPTS_PATH}/stop.sh && {SCRIPTS_PATH}/deploy.sh` | |
| ### Updating Dependencies | |
| ```bash | |
| # Activate virtual environment | |
| source {PROD_PATH}/venv/bin/activate | |
| # Update dependencies | |
| pip install -r requirements.txt --upgrade | |
| # Restart services | |
| {SCRIPTS_PATH}/stop.sh && {SCRIPTS_PATH}/deploy.sh | |
| ``` | |
| """ | |
| readme_file = PROD_PATH / "README.md" | |
| with open(readme_file, 'w') as f: | |
| f.write(readme_content) | |
| print(f" ✅ Created: {readme_file}") | |
| # Generate setup summary | |
| setup_summary = { | |
| "setup_completed": True, | |
| "deployment_path": str(PROD_PATH), | |
| "config_path": str(CONFIG_PATH), | |
| "logs_path": str(LOGS_PATH), | |
| "backups_path": str(BACKUPS_PATH), | |
| "scripts_path": str(SCRIPTS_PATH), | |
| "ssl_path": str(SSL_PATH), | |
| "created_at": datetime.now().isoformat(), | |
| "configuration": { | |
| "main_config": str(config_file), | |
| "env_file": str(env_file), | |
| "security_policies": str(security_file), | |
| "prometheus_config": str(prometheus_file), | |
| "alerts_config": str(alerts_file) | |
| }, | |
| "scripts": { | |
| "deploy_script": str(deploy_file), | |
| "monitor_script": str(monitor_file), | |
| "backup_script": str(backup_file), | |
| "stop_script": str(stop_file) | |
| }, | |
| "documentation": str(readme_file), | |
| "service_endpoints": { | |
| "websocket": "ws://localhost:8765", | |
| "health_check": "http://localhost:8080/health", | |
| "api": "http://localhost:8000", | |
| "prometheus": "http://localhost:9090" | |
| }, | |
| "next_steps": [ | |
| "Configure environment variables in .env file", | |
| "Set up database (PostgreSQL + Redis)", | |
| "Run deployment script", | |
| "Verify all services are healthy", | |
| "Configure third-party API keys", | |
| "Test workflow functionality", | |
| "Set up monitoring and alerts" | |
| ] | |
| } | |
| summary_file = CONFIG_PATH / "setup_summary.json" | |
| with open(summary_file, 'w') as f: | |
| json.dump(setup_summary, f, indent=2) | |
| print(f" ✅ Created: {summary_file}") | |
| print("\n🎉 LOCAL PRODUCTION SETUP COMPLETED!") | |
| print("=" * 80) | |
| print("✅ Local production environment is ready") | |
| print("=" * 80) | |
| print(f"\n📁 DEPLOYMENT PATH: {PROD_PATH}") | |
| print(f"⚙️ CONFIGURATION PATH: {CONFIG_PATH}") | |
| print(f"📄 LOGS PATH: {LOGS_PATH}") | |
| print(f"💾 BACKUPS PATH: {BACKUPS_PATH}") | |
| print("\n🚀 NEXT STEPS:") | |
| print("-" * 60) | |
| print("1. Configure environment variables:") | |
| print(f" 📝 Edit: {CONFIG_PATH}/.env") | |
| print(" 🔒 Change all default passwords and API keys") | |
| print() | |
| print("2. Set up database (for local testing):") | |
| print(" 🐳 Run: docker run -d --name atom-postgres -e POSTGRES_DB=atom_production -e POSTGRES_USER=atom_user -e POSTGRES_PASSWORD=CHANGE_THIS_PASSWORD -p 5432:5432 postgres:13") | |
| print(" 🐳 Run: docker run -d --name atom-redis -p 6379:6379 redis:6-alpine") | |
| print() | |
| print("3. Deploy application:") | |
| print(f" 🚀 Run: {SCRIPTS_PATH}/deploy.sh") | |
| print() | |
| print("4. Verify deployment:") | |
| print(" 🌐 Test WebSocket: curl http://localhost:8765/health") | |
| print(" 🏥 Test Health Check: curl http://localhost:8080/health") | |
| print(" 📊 Test Monitoring: curl http://localhost:9090") | |
| print() | |
| print("5. Monitor and maintain:") | |
| print(f" 🔍 Monitor: {SCRIPTS_PATH}/monitor.sh") | |
| print(f" 📦 Backup: {SCRIPTS_PATH}/backup.sh") | |
| print(f" 🛑 Stop: {SCRIPTS_PATH}/stop.sh") | |
| print(f"\n📊 SERVICE ENDPOINTS:") | |
| print("-" * 60) | |
| print("🌐 WebSocket Server: ws://localhost:8765") | |
| print("🏥 Health Check: http://localhost:8080/health") | |
| print("📈 Prometheus: http://localhost:9090") | |
| print("🔧 API Server: http://localhost:8000") | |
| print(f"\n🔧 MANAGEMENT COMMANDS:") | |
| print("-" * 60) | |
| print(f"📂 Deployment Path: {PROD_PATH}") | |
| print(f"⚙️ Configuration: {CONFIG_PATH}/") | |
| print(f"📄 Logs: {LOGS_PATH}/") | |
| print(f"💾 Backups: {BACKUPS_PATH}/") | |
| print(f"🚀 Deploy: {SCRIPTS_PATH}/deploy.sh") | |
| print(f"🔍 Monitor: {SCRIPTS_PATH}/monitor.sh") | |
| print(f"📦 Backup: {SCRIPTS_PATH}/backup.sh") | |
| print(f"🛑 Stop: {SCRIPTS_PATH}/stop.sh") | |
| print(f"\n📋 CONFIGURATION FILES CREATED:") | |
| print("-" * 60) | |
| print(f"📄 Main Config: {config_file}") | |
| print(f"🔐 Environment: {env_file}") | |
| print(f"🛡️ Security: {security_file}") | |
| print(f"📊 Monitoring: {prometheus_file}") | |
| print(f"🚨 Alerts: {alerts_file}") | |
| print("\n" + "=" * 80) | |
| print("🎉 LOCAL PRODUCTION ENVIRONMENT SETUP COMPLETED! 🎉") | |
| print("=" * 80) | |
| print("🏭 System is ready for local production deployment") | |
| print("🚀 All configurations and scripts have been created") | |
| print("=" * 80) | |
| # Create a simple test script | |
| test_script = f"""#!/bin/bash | |
| # Simple Test Script | |
| DEPLOYMENT_PATH="{PROD_PATH}" | |
| echo "🧪 Testing Local Production Environment" | |
| echo "==================================" | |
| # Test if directories exist | |
| echo "📁 Testing directories..." | |
| if [ -d "$DEPLOYMENT_PATH" ]; then | |
| echo "✅ Deployment directory exists" | |
| else | |
| echo "❌ Deployment directory missing" | |
| exit 1 | |
| fi | |
| if [ -d "$DEPLOYMENT_PATH/config" ]; then | |
| echo "✅ Config directory exists" | |
| else | |
| echo "❌ Config directory missing" | |
| exit 1 | |
| fi | |
| if [ -d "$DEPLOYMENT_PATH/scripts" ]; then | |
| echo "✅ Scripts directory exists" | |
| else | |
| echo "❌ Scripts directory missing" | |
| exit 1 | |
| fi | |
| # Test if configuration files exist | |
| echo "📄 Testing configuration files..." | |
| if [ -f "$DEPLOYMENT_PATH/config/production.json" ]; then | |
| echo "✅ Main configuration exists" | |
| else | |
| echo "❌ Main configuration missing" | |
| exit 1 | |
| fi | |
| if [ -f "$DEPLOYMENT_PATH/config/.env" ]; then | |
| echo "✅ Environment file exists" | |
| else | |
| echo "❌ Environment file missing" | |
| exit 1 | |
| fi | |
| # Test if scripts exist | |
| echo "🚀 Testing deployment scripts..." | |
| if [ -f "$DEPLOYMENT_PATH/scripts/deploy.sh" ]; then | |
| echo "✅ Deploy script exists" | |
| else | |
| echo "❌ Deploy script missing" | |
| exit 1 | |
| fi | |
| if [ -f "$DEPLOYMENT_PATH/scripts/monitor.sh" ]; then | |
| echo "✅ Monitor script exists" | |
| else | |
| echo "❌ Monitor script missing" | |
| exit 1 | |
| fi | |
| echo "" | |
| echo "🎉 All tests passed! Local production environment is ready." | |
| echo "" | |
| echo "📋 Next steps:" | |
| echo "1. Configure environment variables in: $DEPLOYMENT_PATH/config/.env" | |
| echo "2. Set up database (PostgreSQL + Redis)" | |
| echo "3. Run: $DEPLOYMENT_PATH/scripts/deploy.sh" | |
| echo "4. Test: curl http://localhost:8080/health" | |
| """ | |
| test_file = SCRIPTS_PATH / "test.sh" | |
| with open(test_file, 'w') as f: | |
| f.write(test_script) | |
| try: | |
| os.chmod(test_file, 0o755) | |
| print(f"🧪 Test script created: {test_file}") | |
| except: | |
| print(f"🧪 Test script created: {test_file} (run: chmod +x to make executable)") | |
| print(f"\n🧪 Run test script: {test_file}") | |
| except Exception as e: | |
| print(f"\n❌ Setup failed with error: {str(e)}") | |
| import traceback | |
| traceback.print_exc() | |
| sys.exit(1) |