mirror of
				https://github.com/9technologygroup/patchmon.net.git
				synced 2025-11-03 21:43:33 +00:00 
			
		
		
		
	
		
			
				
	
	
		
			325 lines
		
	
	
		
			9.8 KiB
		
	
	
	
		
			Bash
		
	
	
		
			Executable File
		
	
	
	
	
			
		
		
	
	
			325 lines
		
	
	
		
			9.8 KiB
		
	
	
	
		
			Bash
		
	
	
		
			Executable File
		
	
	
	
	
#!/bin/bash
 | 
						||
 | 
						||
# PatchMon Agent Migration Script v1.2.9
 | 
						||
# This script migrates from legacy bash agent (v1.2.8) to Go agent (v1.3.0+)
 | 
						||
# It acts as an intermediary during the upgrade process
 | 
						||
 | 
						||
# Configuration
 | 
						||
PATCHMON_SERVER="${PATCHMON_SERVER:-http://localhost:3001}"
 | 
						||
API_VERSION="v1"
 | 
						||
AGENT_VERSION="1.2.9"
 | 
						||
CREDENTIALS_FILE="/etc/patchmon/credentials"
 | 
						||
LOG_FILE="/var/log/patchmon-agent.log"
 | 
						||
 | 
						||
# This placeholder will be dynamically replaced by the server when serving this
 | 
						||
# script based on the "ignore SSL self-signed" setting. If set to -k, curl will
 | 
						||
# ignore certificate validation. Otherwise, it will be empty for secure default.
 | 
						||
CURL_FLAGS=""
 | 
						||
 | 
						||
# Colors for output
 | 
						||
RED='\033[0;31m'
 | 
						||
GREEN='\033[0;32m'
 | 
						||
YELLOW='\033[1;33m'
 | 
						||
BLUE='\033[0;34m'
 | 
						||
NC='\033[0m' # No Color
 | 
						||
 | 
						||
# Logging function
 | 
						||
log() {
 | 
						||
    if [[ -w "$(dirname "$LOG_FILE")" ]] 2>/dev/null; then
 | 
						||
        echo "[$(date '+%Y-%m-%d %H:%M:%S')] MIGRATION: $1" >> "$LOG_FILE" 2>/dev/null
 | 
						||
    fi
 | 
						||
}
 | 
						||
 | 
						||
# Error handling
 | 
						||
error() {
 | 
						||
    echo -e "${RED}ERROR: $1${NC}" >&2
 | 
						||
    log "ERROR: $1"
 | 
						||
    exit 1
 | 
						||
}
 | 
						||
 | 
						||
# Info logging
 | 
						||
info() {
 | 
						||
    echo -e "${BLUE}ℹ️  $1${NC}" >&2
 | 
						||
    log "INFO: $1"
 | 
						||
}
 | 
						||
 | 
						||
# Success logging
 | 
						||
success() {
 | 
						||
    echo -e "${GREEN}✅ $1${NC}" >&2
 | 
						||
    log "SUCCESS: $1"
 | 
						||
}
 | 
						||
 | 
						||
# Warning logging
 | 
						||
warning() {
 | 
						||
    echo -e "${YELLOW}⚠️  $1${NC}" >&2
 | 
						||
    log "WARNING: $1"
 | 
						||
}
 | 
						||
 | 
						||
# Check if running as root
 | 
						||
check_root() {
 | 
						||
    if [[ $EUID -ne 0 ]]; then
 | 
						||
        error "This migration script must be run as root"
 | 
						||
    fi
 | 
						||
}
 | 
						||
 | 
						||
# Load API credentials from legacy format
 | 
						||
load_legacy_credentials() {
 | 
						||
    if [[ ! -f "$CREDENTIALS_FILE" ]]; then
 | 
						||
        error "Legacy credentials file not found at $CREDENTIALS_FILE"
 | 
						||
    fi
 | 
						||
    
 | 
						||
    source "$CREDENTIALS_FILE"
 | 
						||
    
 | 
						||
    if [[ -z "$API_ID" ]] || [[ -z "$API_KEY" ]]; then
 | 
						||
        error "API_ID and API_KEY must be configured in $CREDENTIALS_FILE"
 | 
						||
    fi
 | 
						||
    
 | 
						||
    # Use PATCHMON_URL from credentials if available
 | 
						||
    if [[ -n "$PATCHMON_URL" ]]; then
 | 
						||
        PATCHMON_SERVER="$PATCHMON_URL"
 | 
						||
    fi
 | 
						||
}
 | 
						||
 | 
						||
 | 
						||
# Remove cron entries
 | 
						||
remove_cron_entries() {
 | 
						||
    info "Removing legacy cron entries..."
 | 
						||
    
 | 
						||
    # Get current crontab
 | 
						||
    local current_crontab=$(crontab -l 2>/dev/null || echo "")
 | 
						||
    
 | 
						||
    if [[ -n "$current_crontab" ]]; then
 | 
						||
        # Remove any lines containing patchmon-agent
 | 
						||
        local new_crontab=$(echo "$current_crontab" | grep -v "patchmon-agent" || true)
 | 
						||
        
 | 
						||
        # Update crontab if it changed
 | 
						||
        if [[ "$current_crontab" != "$new_crontab" ]]; then
 | 
						||
            if [[ -n "$new_crontab" ]]; then
 | 
						||
                echo "$new_crontab" | crontab -
 | 
						||
                success "Legacy cron entries removed (kept other cron jobs)"
 | 
						||
            else
 | 
						||
                crontab -r 2>/dev/null || true
 | 
						||
                success "All cron entries removed"
 | 
						||
            fi
 | 
						||
        else
 | 
						||
            info "No patchmon cron entries found to remove"
 | 
						||
        fi
 | 
						||
    else
 | 
						||
        info "No crontab found"
 | 
						||
    fi
 | 
						||
}
 | 
						||
 | 
						||
 | 
						||
# Clean up legacy files (only after successful verification)
 | 
						||
cleanup_legacy_files() {
 | 
						||
    info "Cleaning up legacy files..."
 | 
						||
    
 | 
						||
    # Remove legacy script
 | 
						||
    if [[ -f "/usr/local/bin/patchmon-agent.sh" ]]; then
 | 
						||
        rm -f "/usr/local/bin/patchmon-agent.sh"
 | 
						||
        success "Removed legacy script"
 | 
						||
    fi
 | 
						||
    
 | 
						||
    # Remove legacy credentials file
 | 
						||
    if [[ -f "$CREDENTIALS_FILE" ]]; then
 | 
						||
        rm -f "$CREDENTIALS_FILE"
 | 
						||
        success "Removed legacy credentials file"
 | 
						||
    fi
 | 
						||
    
 | 
						||
    # Remove legacy config file (if it exists)
 | 
						||
    if [[ -f "/etc/patchmon/config" ]]; then
 | 
						||
        rm -f "/etc/patchmon/config"
 | 
						||
        success "Removed legacy config file"
 | 
						||
    fi
 | 
						||
}
 | 
						||
 | 
						||
# Show migration summary
 | 
						||
show_migration_summary() {
 | 
						||
    echo ""
 | 
						||
    echo "=========================================="
 | 
						||
    echo "PatchMon Agent Migration Complete!"
 | 
						||
    echo "=========================================="
 | 
						||
    echo ""
 | 
						||
    echo "✅ Successfully migrated from bash agent to Go agent"
 | 
						||
    echo ""
 | 
						||
    echo "What was done:"
 | 
						||
    echo "  • Loaded legacy credentials"
 | 
						||
    echo "  • Downloaded and ran PatchMon install script"
 | 
						||
    echo "  • Installed Go agent binary and systemd service"
 | 
						||
    echo "  • Verified service is running"
 | 
						||
    echo "  • Removed legacy cron entries"
 | 
						||
    echo "  • Cleaned up legacy files"
 | 
						||
    echo ""
 | 
						||
    echo "Next steps:"
 | 
						||
    echo "  • The Go agent runs as a service, no cron needed"
 | 
						||
    echo "  • Use: patchmon-agent serve (to run as service)"
 | 
						||
    echo "  • Use: patchmon-agent report (for one-time report)"
 | 
						||
    echo "  • Use: patchmon-agent --help (for all commands)"
 | 
						||
    echo ""
 | 
						||
    echo "Monitoring commands:"
 | 
						||
    echo "  • Check status: systemctl status patchmon-agent"
 | 
						||
    echo "  • View logs: tail -f /etc/patchmon/logs/patchmon-agent.log"
 | 
						||
    echo "  • Run diagnostics: patchmon-agent diagnostics"
 | 
						||
    echo ""
 | 
						||
    echo "Configuration files:"
 | 
						||
    echo "  • Config: /etc/patchmon/config.yml"
 | 
						||
    echo "  • Credentials: /etc/patchmon/credentials.yml"
 | 
						||
    echo "  • Logs: /etc/patchmon/logs/patchmon-agent.log"
 | 
						||
    echo ""
 | 
						||
}
 | 
						||
 | 
						||
# Post-migration verification
 | 
						||
post_migration_check() {
 | 
						||
    echo ""
 | 
						||
    echo "=========================================="
 | 
						||
    echo "Post-Migration Verification"
 | 
						||
    echo "=========================================="
 | 
						||
    echo ""
 | 
						||
    
 | 
						||
    # Check if patchmon-agent is running
 | 
						||
    info "Checking if patchmon-agent is running..."
 | 
						||
    if pgrep -f "patchmon-agent serve" >/dev/null 2>&1; then
 | 
						||
        success "PatchMon agent is running"
 | 
						||
    else
 | 
						||
        warning "PatchMon agent is not running (this is normal if not started as service)"
 | 
						||
        info "To start as service: patchmon-agent serve"
 | 
						||
    fi
 | 
						||
    
 | 
						||
    # Check WebSocket connection (if agent is running)
 | 
						||
    if pgrep -f "patchmon-agent serve" >/dev/null 2>&1; then
 | 
						||
        info "Checking WebSocket connection..."
 | 
						||
        if /usr/local/bin/patchmon-agent ping >/dev/null 2>&1; then
 | 
						||
            success "WebSocket connection is active"
 | 
						||
        else
 | 
						||
            warning "WebSocket connection test failed"
 | 
						||
        fi
 | 
						||
    else
 | 
						||
        info "Skipping WebSocket check (agent not running)"
 | 
						||
    fi
 | 
						||
    
 | 
						||
    # Run diagnostics
 | 
						||
    info "Running system diagnostics..."
 | 
						||
    echo ""
 | 
						||
    if [[ -f "/usr/local/bin/patchmon-agent" ]]; then
 | 
						||
        if /usr/local/bin/patchmon-agent diagnostics >/dev/null 2>&1; then
 | 
						||
            success "Diagnostics completed successfully"
 | 
						||
            echo ""
 | 
						||
            echo "Full diagnostics output:"
 | 
						||
            echo "----------------------------------------"
 | 
						||
            /usr/local/bin/patchmon-agent diagnostics
 | 
						||
            echo "----------------------------------------"
 | 
						||
        else
 | 
						||
            warning "Diagnostics failed to run"
 | 
						||
        fi
 | 
						||
    else
 | 
						||
        warning "Go agent binary not found - cannot run diagnostics"
 | 
						||
    fi
 | 
						||
    
 | 
						||
    echo ""
 | 
						||
    echo "=========================================="
 | 
						||
    echo "Migration Verification Complete!"
 | 
						||
    echo "=========================================="
 | 
						||
    echo ""
 | 
						||
    success "Thank you for using PatchMon Agent!"
 | 
						||
    echo ""
 | 
						||
}
 | 
						||
 | 
						||
# Main migration function
 | 
						||
perform_migration() {
 | 
						||
    info "Starting PatchMon Agent migration from bash to Go..."
 | 
						||
    echo ""
 | 
						||
    
 | 
						||
    # Load legacy credentials
 | 
						||
    load_legacy_credentials
 | 
						||
    
 | 
						||
    # Set environment variables for install script
 | 
						||
    export API_ID="$API_ID"
 | 
						||
    export API_KEY="$API_KEY"
 | 
						||
    export PATCHMON_URL="$PATCHMON_SERVER"
 | 
						||
    
 | 
						||
    # Detect architecture
 | 
						||
    local arch=$(uname -m)
 | 
						||
    local goarch=""
 | 
						||
    case "$arch" in
 | 
						||
        "x86_64") goarch="amd64" ;;
 | 
						||
        "i386"|"i686") goarch="386" ;;
 | 
						||
        "aarch64"|"arm64") goarch="arm64" ;;
 | 
						||
        "armv7l"|"armv6l"|"armv5l") goarch="arm" ;;
 | 
						||
        *) error "Unsupported architecture: $arch" ;;
 | 
						||
    esac
 | 
						||
    
 | 
						||
    info "Downloading and running PatchMon install script..."
 | 
						||
    
 | 
						||
    # Download and run the install script
 | 
						||
    if curl $CURL_FLAGS -H "X-API-ID: $API_ID" -H "X-API-KEY: $API_KEY" \
 | 
						||
           "$PATCHMON_SERVER/api/v1/hosts/install?arch=$goarch" | bash; then
 | 
						||
        
 | 
						||
        success "PatchMon Go agent installed successfully"
 | 
						||
        
 | 
						||
        # Wait a moment for service to start
 | 
						||
        sleep 3
 | 
						||
        
 | 
						||
        # Test if the service is running
 | 
						||
        if systemctl is-active --quiet patchmon-agent.service; then
 | 
						||
            success "PatchMon agent service is running"
 | 
						||
            
 | 
						||
            # Clean up legacy files
 | 
						||
            remove_cron_entries
 | 
						||
            cleanup_legacy_files
 | 
						||
            
 | 
						||
            # Show summary
 | 
						||
            show_migration_summary
 | 
						||
            post_migration_check
 | 
						||
            
 | 
						||
            success "Migration completed successfully!"
 | 
						||
        else
 | 
						||
            warning "PatchMon agent service failed to start"
 | 
						||
            warning "Legacy files preserved for debugging"
 | 
						||
            show_migration_summary
 | 
						||
        fi
 | 
						||
    else
 | 
						||
        error "Failed to install PatchMon Go agent"
 | 
						||
    fi
 | 
						||
    
 | 
						||
    # Exit here to prevent the legacy script from continuing
 | 
						||
    exit 0
 | 
						||
}
 | 
						||
 | 
						||
# Handle command line arguments
 | 
						||
case "$1" in
 | 
						||
    "migrate")
 | 
						||
        check_root
 | 
						||
        perform_migration
 | 
						||
        ;;
 | 
						||
    "test")
 | 
						||
        check_root
 | 
						||
        load_legacy_credentials
 | 
						||
        test_go_agent
 | 
						||
        ;;
 | 
						||
    "update-agent")
 | 
						||
        # This is called by legacy agents during update
 | 
						||
        check_root
 | 
						||
        perform_migration
 | 
						||
        ;;
 | 
						||
    *)
 | 
						||
        # If no arguments provided, check if we're being executed by a legacy agent
 | 
						||
        # Legacy agents will call this script directly during update
 | 
						||
        if [[ -f "$CREDENTIALS_FILE" ]]; then
 | 
						||
            info "Detected legacy agent execution - starting migration..."
 | 
						||
            check_root
 | 
						||
            perform_migration
 | 
						||
        else
 | 
						||
            echo "PatchMon Agent Migration Script v$AGENT_VERSION"
 | 
						||
            echo "Usage: $0 {migrate|test|update-agent}"
 | 
						||
            echo ""
 | 
						||
            echo "Commands:"
 | 
						||
            echo "  migrate      - Perform full migration from bash to Go agent"
 | 
						||
            echo "  test         - Test Go agent after migration"
 | 
						||
            echo "  update-agent - Called by legacy agents during update"
 | 
						||
            echo ""
 | 
						||
            echo "This script should be executed by the legacy agent during update."
 | 
						||
            exit 1
 | 
						||
        fi
 | 
						||
        ;;
 | 
						||
esac
 |