Add PostgreSQL database persistence

- Add connect_machines, connect_sessions, connect_session_events, connect_support_codes tables
- Implement db module with connection pooling (sqlx)
- Add machine persistence across server restarts
- Add audit logging for session/viewer events
- Support codes now persisted to database

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
2025-12-28 19:51:01 -07:00
parent 448d3b75ac
commit f6bf0cfd26
10 changed files with 788 additions and 36 deletions

View File

@@ -38,6 +38,7 @@ use support_codes::{SupportCodeManager, CreateCodeRequest, SupportCode, CodeVali
pub struct AppState {
sessions: session::SessionManager,
support_codes: SupportCodeManager,
db: Option<db::Database>,
}
#[tokio::main]
@@ -52,15 +53,55 @@ async fn main() -> Result<()> {
// Load configuration
let config = config::Config::load()?;
// Use port 3002 for GuruConnect
let listen_addr = std::env::var("LISTEN_ADDR").unwrap_or_else(|_| "0.0.0.0:3002".to_string());
info!("Loaded configuration, listening on {}", listen_addr);
// Initialize database if configured
let database = if let Some(ref db_url) = config.database_url {
match db::Database::connect(db_url, config.database_max_connections).await {
Ok(db) => {
// Run migrations
if let Err(e) = db.migrate().await {
tracing::error!("Failed to run migrations: {}", e);
return Err(e);
}
Some(db)
}
Err(e) => {
tracing::warn!("Failed to connect to database: {}. Running without persistence.", e);
None
}
}
} else {
info!("No DATABASE_URL set, running without persistence");
None
};
// Create session manager
let sessions = session::SessionManager::new();
// Restore persistent machines from database
if let Some(ref db) = database {
match db::machines::get_all_machines(db.pool()).await {
Ok(machines) => {
info!("Restoring {} persistent machines from database", machines.len());
for machine in machines {
sessions.restore_offline_machine(&machine.agent_id, &machine.hostname).await;
}
}
Err(e) => {
tracing::warn!("Failed to restore machines: {}", e);
}
}
}
// Create application state
let state = AppState {
sessions: session::SessionManager::new(),
sessions,
support_codes: SupportCodeManager::new(),
db: database,
};
// Build router