use std::{net::ToSocketAddrs, sync::Arc}; use tracing::info; use crate::{connector::agent::AgentConnectorTrait, service::certificate::CertificateService}; pub mod agent; pub mod certificate; pub async fn start_master_server( settings: crate::config::settings::Settings, cli: crate::cli::Cli, ) -> Result<(), Box> { // Initialize database connection let db_connection = crate::db::establish_connection(&settings.database.url).await?; // Initialize certificate service with default cert folder path let cert_service = Arc::new(crate::service::certificate::CertificateServiceImpl::new( db_connection.clone(), settings.grpc.certificate.cert_dir.clone(), Arc::new(settings.clone()), )); // if generate_ca is set, generate a new certificate and exit if cli.generate_ca { // TODO: check the error type and return a more specific error message cert_service.generate_ca_cert().await.ok(); println!("Certificate generated and stored successfully."); } let ssh_connector = crate::connector::agent::ssh::SshAgentConnector::new(settings.clone())?; let cert_service_for_agent = cert_service.clone(); let settings_for_agent = settings.clone(); let connection_for_agent = db_connection.clone(); tokio::spawn(async move { let mut connector = ssh_connector; tracing::info!("Starting agent server..."); if let Err(e) = connector .start_server( &settings_for_agent, cert_service_for_agent, connection_for_agent, ) .await { tracing::error!("Agent server failed: {}", e); } else { tracing::info!("Agent server stopped."); } }); let axum_router = crate::routes::get_root_router().await; // Start the HTTP server let addr = format!("{}:{}", settings.server.bind_address, settings.server.port) .to_socket_addrs()? .next() .ok_or("Invalid bind address")?; let listener = tokio::net::TcpListener::bind(addr).await?; info!("Web/API server is listening on {}", addr); axum::serve(listener, axum_router).await?; Ok(()) }