Spaces:
Sleeping
Sleeping
| #!/usr/bin/env python3 | |
| """ | |
| Production Deployment Setup - Simplified Version | |
| Advanced Workflow Automation - Production Readiness | |
| This script sets up production deployment with: | |
| - Configuration management | |
| - Directory structure | |
| - Security setup | |
| - Monitoring configuration | |
| - Deployment scripts | |
| """ | |
| from datetime import datetime | |
| import json | |
| import os | |
| from pathlib import Path | |
| import subprocess | |
| import sys | |
| import uuid | |
| print("🚀 PRODUCTION DEPLOYMENT SETUP") | |
| print("=" * 80) | |
| print("Setting up production environment for Advanced Workflow Automation") | |
| print("=" * 80) | |
| # Check if running with appropriate permissions | |
| if os.name == 'posix' and os.geteuid() != 0: | |
| print("⚠️ Note: This script is best run with sudo for full functionality") | |
| print(" Some directory creation may require elevated privileges") | |
| print(" Continuing with current user privileges...") | |
| print() | |
| # Define deployment paths | |
| BASE_PATH = Path("/opt/atom") | |
| 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 Production Directory Structure...") | |
| print("-" * 50) | |
| # 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 PermissionError: | |
| print(f" ⚠️ Permission denied for: {directory}") | |
| print(f" Run with sudo to create system directories") | |
| except Exception as e: | |
| print(f" ❌ Error creating {directory}: {str(e)}") | |
| print("\n⚙️ Generating Configuration Files...") | |
| print("-" * 50) | |
| # Main production configuration | |
| prod_config = { | |
| "environment": "production", | |
| "debug": False, | |
| "log_level": "INFO", | |
| "timezone": "UTC", | |
| # Database Configuration | |
| "database": { | |
| "host": "localhost", | |
| "port": 5432, | |
| "name": "atom_production", | |
| "user": "atom_user", | |
| "password": "CHANGE_THIS_PASSWORD", | |
| "pool_size": 20, | |
| "max_overflow": 30, | |
| "ssl_mode": "require" | |
| }, | |
| # Redis Configuration | |
| "redis": { | |
| "host": "localhost", | |
| "port": 6379, | |
| "db": 0, | |
| "password": "CHANGE_THIS_REDIS_PASSWORD", | |
| "max_connections": 100 | |
| }, | |
| # WebSocket Configuration | |
| "websocket": { | |
| "host": "0.0.0.0", | |
| "port": 8765, | |
| "ssl_enabled": True, | |
| "cert_file": f"{SSL_PATH}/cert.pem", | |
| "key_file": f"{SSL_PATH}/key.pem" | |
| }, | |
| # API Configuration | |
| "api": { | |
| "host": "0.0.0.0", | |
| "port": 8000, | |
| "ssl_enabled": True, | |
| "workers": 4, | |
| "worker_class": "uvicorn.workers.UvicornWorker" | |
| }, | |
| # 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 | |
| }, | |
| # Performance Configuration | |
| "performance": { | |
| "max_concurrent_workflows": 1000, | |
| "workflow_timeout_minutes": 60, | |
| "task_queue_max_size": 10000, | |
| "cache_ttl_seconds": 3600, | |
| "connection_pool_size": 100 | |
| }, | |
| # Monitoring Configuration | |
| "monitoring": { | |
| "prometheus_enabled": True, | |
| "prometheus_port": 9090, | |
| "health_check_port": 8080, | |
| "metrics_collection_enabled": True, | |
| "log_analytics_enabled": True | |
| }, | |
| # Backup Configuration | |
| "backup": { | |
| "enabled": True, | |
| "schedule_hours": 24, | |
| "retention_days": 30, | |
| "auto_recovery_enabled": True, | |
| "backup_path": str(BACKUPS_PATH) | |
| }, | |
| # 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_EMAIL_PASSWORD", | |
| "from_email": "noreply@atom.com" | |
| } | |
| } | |
| # 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""" | |
| # 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']} | |
| """ | |
| 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("-" * 50) | |
| # Security policies | |
| security_policies = { | |
| "authentication": { | |
| "password_policy": { | |
| "min_length": 12, | |
| "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": 30, | |
| "max_concurrent_sessions": 3, | |
| "require_reauth_minutes": 60, | |
| "secure_cookies": True, | |
| "http_only_cookies": True | |
| }, | |
| "lockout_policy": { | |
| "max_attempts": 5, | |
| "lockout_duration_minutes": 15, | |
| "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": ["https://localhost"], | |
| "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("-" * 50) | |
| # 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" | |
| }, | |
| { | |
| "job_name": "node-exporter", | |
| "static_configs": [{"targets": ["localhost:9100"]}], | |
| "scrape_interval": "30s" | |
| } | |
| ] | |
| } | |
| 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" | |
| } | |
| }, | |
| { | |
| "alert": "HighMemoryUsage", | |
| "expr": "(node_memory_MemTotal_bytes - node_memory_MemAvailable_bytes) / node_memory_MemTotal_bytes > 0.8", | |
| "for": "5m", | |
| "labels": {"severity": "warning"}, | |
| "annotations": { | |
| "summary": "High memory usage", | |
| "description": "Memory usage is {{ $value | humanizePercentage }}" | |
| } | |
| }, | |
| { | |
| "alert": "HighCPUUsage", | |
| "expr": "100 - (avg by(instance) (rate(node_cpu_seconds_total{mode=\"idle\"}[5m])) * 100) > 80", | |
| "for": "10m", | |
| "labels": {"severity": "warning"}, | |
| "annotations": { | |
| "summary": "High CPU usage", | |
| "description": "CPU usage is {{ $value | humanizePercentage }}" | |
| } | |
| } | |
| ] | |
| } | |
| ] | |
| } | |
| 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("-" * 50) | |
| # Deployment script | |
| deploy_script = f"""#!/bin/bash | |
| # Atom Workflow Automation Deployment Script | |
| set -e | |
| DEPLOYMENT_PATH="{PROD_PATH}" | |
| LOG_FILE="$DEPLOYMENT_PATH/logs/deploy.log" | |
| echo "🚀 Starting Atom Workflow Automation Deployment..." | |
| echo "$(date): Deployment started" >> $LOG_FILE | |
| log() {{ | |
| echo "$1" | |
| echo "$(date): $1" >> $LOG_FILE | |
| }} | |
| # Stop existing services | |
| log "🛑 Stopping existing services..." | |
| systemctl stop atom-workflow-api || true | |
| systemctl stop atom-websocket-server || true | |
| systemctl stop atom-scheduler || true | |
| # Update application code | |
| log "📥 Updating application code..." | |
| cd $DEPLOYMENT_PATH | |
| # Install dependencies | |
| log "📦 Installing Python dependencies..." | |
| if [ -d "venv" ]; then | |
| source venv/bin/activate | |
| else | |
| python3 -m venv venv | |
| source venv/bin/activate | |
| fi | |
| pip install --upgrade pip | |
| pip install -r requirements.txt | |
| # Run database migrations | |
| log "🗄️ Running database migrations..." | |
| python -c " | |
| import psycopg2 | |
| import os | |
| db_config = {json.dumps(prod_config['database'])} | |
| try: | |
| conn = psycopg2.connect( | |
| host=db_config['host'], | |
| port=db_config['port'], | |
| database='postgres', | |
| user=db_config['user'], | |
| password=db_config['password'] | |
| ) | |
| conn.autocommit = True | |
| cursor = conn.cursor() | |
| cursor.execute(f'CREATE DATABASE {{db_config["name"]}}') | |
| print('Database created or already exists') | |
| except Exception as e: | |
| print(f'Database creation skipped: {{e}}') | |
| # Create tables (simplified) | |
| import uuid | |
| from datetime import datetime | |
| conn = psycopg2.connect( | |
| host=db_config['host'], | |
| port=db_config['port'], | |
| database=db_config['name'], | |
| user=db_config['user'], | |
| password=db_config['password'] | |
| ) | |
| cursor = conn.cursor() | |
| # Create workflows table | |
| cursor.execute(''' | |
| CREATE TABLE IF NOT EXISTS workflows ( | |
| id UUID PRIMARY KEY DEFAULT gen_random_uuid(), | |
| name VARCHAR(255) NOT NULL, | |
| description TEXT, | |
| category VARCHAR(100), | |
| user_id UUID NOT NULL, | |
| parameters JSONB DEFAULT '{{}}', | |
| template_id UUID, | |
| created_at TIMESTAMP WITH TIME ZONE DEFAULT NOW(), | |
| updated_at TIMESTAMP WITH TIME ZONE DEFAULT NOW(), | |
| version INTEGER DEFAULT 1 | |
| ) | |
| ''') | |
| # Create workflow_executions table | |
| cursor.execute(''' | |
| CREATE TABLE IF NOT EXISTS workflow_executions ( | |
| id UUID PRIMARY KEY DEFAULT gen_random_uuid(), | |
| workflow_id UUID NOT NULL REFERENCES workflows(id), | |
| status VARCHAR(50) NOT NULL, | |
| input_data JSONB DEFAULT '{{}}', | |
| output_data JSONB DEFAULT '{{}}', | |
| error_message TEXT, | |
| execution_time_seconds DECIMAL, | |
| created_at TIMESTAMP WITH TIME ZONE DEFAULT NOW(), | |
| started_at TIMESTAMP WITH TIME ZONE, | |
| completed_at TIMESTAMP WITH TIME ZONE, | |
| user_id UUID NOT NULL | |
| ) | |
| ''') | |
| # Create workflow_steps table | |
| cursor.execute(''' | |
| CREATE TABLE IF NOT EXISTS workflow_steps ( | |
| id UUID PRIMARY KEY DEFAULT gen_random_uuid(), | |
| execution_id UUID NOT NULL REFERENCES workflow_executions(id), | |
| step_order INTEGER NOT NULL, | |
| service VARCHAR(100) NOT NULL, | |
| action VARCHAR(100) NOT NULL, | |
| parameters JSONB DEFAULT '{{}}', | |
| status VARCHAR(50) NOT NULL, | |
| result JSONB, | |
| error_message TEXT, | |
| execution_time_seconds DECIMAL, | |
| started_at TIMESTAMP WITH TIME ZONE, | |
| completed_at TIMESTAMP WITH TIME ZONE | |
| ) | |
| ''') | |
| # Create users table | |
| cursor.execute(''' | |
| CREATE TABLE IF NOT EXISTS users ( | |
| id UUID PRIMARY KEY DEFAULT gen_random_uuid(), | |
| username VARCHAR(100) UNIQUE NOT NULL, | |
| email VARCHAR(255) UNIQUE NOT NULL, | |
| password_hash VARCHAR(255) NOT NULL, | |
| is_active BOOLEAN DEFAULT TRUE, | |
| is_admin BOOLEAN DEFAULT FALSE, | |
| last_login TIMESTAMP WITH TIME ZONE, | |
| created_at TIMESTAMP WITH TIME ZONE DEFAULT NOW(), | |
| updated_at TIMESTAMP WITH TIME ZONE DEFAULT NOW() | |
| ) | |
| ''') | |
| # Create integration_catalog table | |
| cursor.execute(''' | |
| CREATE TABLE IF NOT EXISTS integration_catalog ( | |
| id TEXT PRIMARY KEY, | |
| name TEXT NOT NULL, | |
| description TEXT, | |
| category TEXT NOT NULL, | |
| icon TEXT, | |
| color TEXT DEFAULT '#6366F1', | |
| auth_type TEXT DEFAULT 'none', | |
| native_id TEXT, | |
| triggers JSONB DEFAULT '[]', | |
| actions JSONB DEFAULT '[]', | |
| popular BOOLEAN DEFAULT FALSE, | |
| created_at TIMESTAMP WITH TIME ZONE DEFAULT NOW(), | |
| updated_at TIMESTAMP WITH TIME ZONE DEFAULT NOW() | |
| ) | |
| ''') | |
| conn.commit() | |
| cursor.close() | |
| conn.close() | |
| print('Database migrations completed') | |
| " | |
| # Start services | |
| log "🚀 Starting services..." | |
| # Note: In a real deployment, you would install and configure systemd services | |
| # For this demo, we'll use nohup to run services in background | |
| # Start WebSocket server | |
| log "🌐 Starting WebSocket server..." | |
| cd $DEPLOYMENT_PATH | |
| nohup python setup_websocket_server.py > logs/websocket.log 2>&1 & | |
| echo $! > logs/websocket.pid | |
| # Start health check server | |
| log "🏥 Starting health check server..." | |
| nohup python -c " | |
| import aiohttp.web | |
| import asyncio | |
| from datetime import datetime | |
| async def health_check(request): | |
| return aiohttp.web.json_response({{ | |
| 'status': 'healthy', | |
| 'timestamp': datetime.now().isoformat(), | |
| 'version': '1.0.0' | |
| }}) | |
| app = aiohttp.web.Application() | |
| app.add_routes([aiohttp.web.get('/health', health_check)]) | |
| aiohttp.web.run_app(app, host='localhost', port=8080) | |
| " > logs/health_check.log 2>&1 & | |
| echo $! > logs/health_check.pid | |
| # Test services | |
| log "🧪 Testing services..." | |
| sleep 5 | |
| if curl -f http://localhost:8080/health > /dev/null 2>&1; then | |
| log "✅ Health check passed" | |
| else | |
| log "❌ Health check failed" | |
| fi | |
| log "🎉 Deployment completed successfully!" | |
| echo "$(date): Deployment completed" >> $LOG_FILE | |
| echo "" | |
| echo "📊 Service Status:" | |
| echo "WebSocket Server: http://localhost:8765" | |
| echo "Health Check: http://localhost:8080/health" | |
| echo "Logs: $DEPLOYMENT_PATH/logs/" | |
| echo "" | |
| echo "🔍 To check logs:" | |
| echo "tail -f $DEPLOYMENT_PATH/logs/websocket.log" | |
| echo "tail -f $DEPLOYMENT_PATH/logs/deploy.log" | |
| echo "" | |
| echo "🛑 To stop services:" | |
| echo "kill \$(cat $DEPLOYMENT_PATH/logs/websocket.pid)" | |
| echo "kill \$(cat $DEPLOYMENT_PATH/logs/health_check.pid)" | |
| """ | |
| 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 | |
| # Atom Workflow Automation 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 | |
| CPU_USAGE=$(top -bn1 | grep "Cpu(s)" | awk '{{print $2}}' | cut -d'%' -f1) | |
| if (( $(echo "$CPU_USAGE > 80" | bc -l) )); then | |
| log "⚠️ High CPU usage: $CPU_USAGE%" | |
| fi | |
| # Memory usage | |
| MEMORY_USAGE=$(free | grep Mem | awk '{{printf("%.0f", $3/$2 * 100.0)}}') | |
| if [ $MEMORY_USAGE -gt 80 ]; then | |
| log "⚠️ High memory usage: $MEMORY_USAGE%" | |
| fi | |
| # Disk usage | |
| DISK_USAGE=$(df / | awk 'NR==2 {{print $5}}' | sed 's/%//') | |
| if [ $DISK_USAGE -gt 80 ]; then | |
| log "⚠️ High disk usage: $DISK_USAGE%" | |
| fi | |
| }} | |
| check_database() {{ | |
| # Simplified database check | |
| if pgrep -f "postgres" > /dev/null; then | |
| log "✅ PostgreSQL is running" | |
| else | |
| log "❌ PostgreSQL is not running" | |
| fi | |
| }} | |
| log "🔍 Starting system monitoring..." | |
| # Check services | |
| check_service "WebSocket Server" 8765 | |
| check_service "Health Check" 8080 | |
| # Check system resources | |
| check_resources | |
| # Check database | |
| check_database | |
| 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 | |
| # Atom Workflow Automation 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 | |
| }} | |
| backup_database() {{ | |
| log "🗄️ Creating database backup..." | |
| TIMESTAMP=$(date +%Y%m%d_%H%M%S) | |
| # Create database backup (simplified) | |
| pg_dump -h {prod_config['database']['host']} -p {prod_config['database']['port']} -U {prod_config['database']['user']} -d {prod_config['database']['name']} | gzip > "$BACKUP_PATH/db_backup_$TIMESTAMP.sql.gz" 2>/dev/null || log "⚠️ Database backup failed" | |
| }} | |
| backup_config() {{ | |
| log "⚙️ Creating configuration backup..." | |
| TIMESTAMP=$(date +%Y%m%d_%H%M%S) | |
| tar -czf "$BACKUP_PATH/config_backup_$TIMESTAMP.tar.gz" "$DEPLOYMENT_PATH/config" 2>/dev/null || log "⚠️ Config backup failed" | |
| }} | |
| cleanup_old_backups() {{ | |
| log "🧹 Cleaning up old backups..." | |
| find "$BACKUP_PATH" -name "*.gz" -mtime +{prod_config['backup']['retention_days']} -delete 2>/dev/null || true | |
| }} | |
| log "📦 Starting backup process..." | |
| # Create backup directory | |
| mkdir -p "$BACKUP_PATH" | |
| # Run backups | |
| backup_database | |
| backup_config | |
| # Cleanup old backups | |
| cleanup_old_backups | |
| log "✅ Backup completed" | |
| 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)") | |
| print("\n📝 Creating Documentation...") | |
| print("-" * 50) | |
| # README file | |
| readme_content = f"""# Atom Workflow Automation - Production Deployment | |
| ## Overview | |
| This is the production deployment setup for the Atom Workflow Automation system. | |
| ## Directory Structure | |
| ``` | |
| {PROD_PATH}/ | |
| ├── config/ # Configuration files | |
| ├── logs/ # Log files | |
| ├── backups/ # Backup files | |
| ├── scripts/ # Deployment and management scripts | |
| ├── ssl/ # SSL certificates | |
| ├── data/ # Application data | |
| ├── temp/ # Temporary files | |
| ├── static/ # Static assets | |
| └── venv/ # Python virtual environment | |
| ``` | |
| ## Configuration | |
| - Main config: `{CONFIG_PATH}/production.json` | |
| - Environment variables: `{CONFIG_PATH}/.env` | |
| - Security policies: `{CONFIG_PATH}/security_policies.json` | |
| ## Services | |
| - WebSocket Server: http://localhost:8765 | |
| - Health Check: http://localhost:8080/health | |
| - API Server: http://localhost:8000 (when deployed) | |
| ## Management Scripts | |
| ### Deployment | |
| ```bash | |
| {SCRIPTS_PATH}/deploy.sh | |
| ``` | |
| ### Monitoring | |
| ```bash | |
| {SCRIPTS_PATH}/monitor.sh | |
| ``` | |
| ### Backup | |
| ```bash | |
| {SCRIPTS_PATH}/backup.sh | |
| ``` | |
| ## Environment Setup | |
| 1. Install dependencies: | |
| ```bash | |
| cd {PROD_PATH} | |
| source venv/bin/activate | |
| pip install -r requirements.txt | |
| ``` | |
| 2. Configure environment: | |
| ```bash | |
| # Edit {CONFIG_PATH}/.env with your settings | |
| vim {CONFIG_PATH}/.env | |
| ``` | |
| 3. Set up database: | |
| ```bash | |
| # PostgreSQL should be installed and running | |
| # Create database and user as specified in config | |
| ``` | |
| 4. Start services: | |
| ```bash | |
| {SCRIPTS_PATH}/deploy.sh | |
| ``` | |
| ## Monitoring | |
| - Health checks: http://localhost:8080/health | |
| - Logs: {LOGS_PATH}/ | |
| - Prometheus: http://localhost:9090 (if configured) | |
| ## Backup Schedule | |
| - Automatic backups: Every {prod_config['backup']['schedule_hours']} hours | |
| - Retention: {prod_config['backup']['retention_days']} days | |
| - Location: {BACKUPS_PATH}/ | |
| ## Security | |
| - All passwords should be changed from defaults | |
| - SSL certificates should be installed in {SSL_PATH}/ | |
| - Review security policies in {CONFIG_PATH}/security_policies.json | |
| ## Troubleshooting | |
| 1. Check logs: `tail -f {LOGS_PATH}/deploy.log` | |
| 2. Verify services: `{SCRIPTS_PATH}/monitor.sh` | |
| 3. Check health: `curl http://localhost:8080/health` | |
| ## Support | |
| For issues, check the logs or contact the system administrator. | |
| """ | |
| readme_file = PROD_PATH / "README.md" | |
| with open(readme_file, 'w') as f: | |
| f.write(readme_content) | |
| print(f" ✅ Created: {readme_file}") | |
| print("\n🎉 PRODUCTION SETUP COMPLETED!") | |
| print("=" * 80) | |
| print("✅ Production environment is ready for deployment") | |
| print("=" * 80) | |
| print("\n📋 NEXT STEPS:") | |
| print("-" * 50) | |
| print("1. Configure environment variables:") | |
| print(f" 📝 Edit: {CONFIG_PATH}/.env") | |
| print(" 🔒 Change all default passwords and keys") | |
| print() | |
| print("2. Set up database:") | |
| print(" 🗄️ Install PostgreSQL") | |
| print(" 👤 Create database and user") | |
| print(" 🔐 Configure security settings") | |
| print() | |
| print("3. Install SSL certificates:") | |
| print(f" 🔒 Place certificates in: {SSL_PATH}/") | |
| print(" 📄 cert.pem and key.pem") | |
| print() | |
| print("4. Deploy application:") | |
| print(f" 🚀 Run: {SCRIPTS_PATH}/deploy.sh") | |
| print() | |
| print("5. Verify deployment:") | |
| print(" 🏥 Health check: http://localhost:8080/health") | |
| print(" 🌐 WebSocket: http://localhost:8765") | |
| print() | |
| print("6. Set up monitoring:") | |
| print(f" 📊 Monitor: {SCRIPTS_PATH}/monitor.sh") | |
| print(f" 📦 Backup: {SCRIPTS_PATH}/backup.sh") | |
| print("\n🔧 MANAGEMENT COMMANDS:") | |
| print("-" * 50) | |
| 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("\n📊 SERVICE ENDPOINTS:") | |
| print("-" * 50) | |
| print("🌐 WebSocket Server: ws://localhost:8765") | |
| print("🏥 Health Check: http://localhost:8080/health") | |
| print("📊 API Server: http://localhost:8000 (when deployed)") | |
| print("📈 Prometheus: http://localhost:9090 (if configured)") | |
| print("\n" + "=" * 80) | |
| print("🎊 PRODUCTION ENVIRONMENT SETUP COMPLETED SUCCESSFULLY! 🎊") | |
| print("🏭 System is ready for production deployment") | |
| print("=" * 80) | |
| # Generate summary report | |
| 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) | |
| }, | |
| "documentation": str(readme_file), | |
| "next_steps": [ | |
| "Configure environment variables", | |
| "Set up database", | |
| "Install SSL certificates", | |
| "Deploy application", | |
| "Verify deployment", | |
| "Set up monitoring" | |
| ], | |
| "service_endpoints": { | |
| "websocket": "ws://localhost:8765", | |
| "health_check": "http://localhost:8080/health", | |
| "api": "http://localhost:8000" | |
| } | |
| } | |
| summary_file = CONFIG_PATH / "setup_summary.json" | |
| with open(summary_file, 'w') as f: | |
| json.dump(setup_summary, f, indent=2) | |
| print(f"\n📄 Setup summary saved to: {summary_file}") | |
| except Exception as e: | |
| print(f"\n❌ Setup failed with error: {str(e)}") | |
| import traceback | |
| traceback.print_exc() | |
| sys.exit(1) |