Some checks failed
Rust Cross-Platform Build / Detect Rust Project (push) Has been cancelled
Rust Cross-Platform Build / Setup Rust Toolchain (push) Has been cancelled
Rust Cross-Platform Build / Run Tests (push) Has been cancelled
Rust Cross-Platform Build / Set Tag Name (push) Has been cancelled
Rust Cross-Platform Build / Build (x86_64-unknown-linux-gnu) (push) Has been cancelled
Rust Cross-Platform Build / Build (x86_64-pc-windows-gnu) (push) Has been cancelled
Rust Cross-Platform Build / Build and Push Docker Image (push) Has been cancelled
Rust Cross-Platform Build / Create Tag (push) Has been cancelled
Rust Cross-Platform Build / Workflow Summary (push) Has been cancelled
157 lines
5.2 KiB
Rust
157 lines
5.2 KiB
Rust
use std::time::Duration;
|
|
|
|
use crate::hardware::HardwareInfo;
|
|
use crate::models::{HeartbeatDto, IdResponse, MetricDto, RegistrationDto};
|
|
use anyhow::Result;
|
|
use reqwest::{Client, StatusCode};
|
|
use std::error::Error;
|
|
use tokio::time::sleep;
|
|
|
|
pub async fn register_with_server(
|
|
base_url: &str,
|
|
) -> Result<(i32, String), Box<dyn Error + Send + Sync>> {
|
|
// First get local IP
|
|
let ip = local_ip_address::local_ip()?.to_string();
|
|
println!("Local IP address detected: {}", ip);
|
|
|
|
// Get server ID from backend (this will retry until successful)
|
|
let (server_id, registered_ip) = get_server_id_by_ip(base_url, &ip).await?;
|
|
|
|
// Create HTTP client for registration
|
|
let client = Client::builder()
|
|
.danger_accept_invalid_certs(true)
|
|
.build()?;
|
|
|
|
// Collect hardware info
|
|
let hardware = HardwareInfo::collect().await?;
|
|
|
|
// Prepare registration data
|
|
let registration = RegistrationDto {
|
|
id: server_id,
|
|
ip_address: registered_ip.clone(),
|
|
cpu_type: hardware.cpu.name.clone().unwrap_or_default(),
|
|
cpu_cores: (hardware.cpu.cores).unwrap_or_default(),
|
|
gpu_type: hardware.gpu.name.clone().unwrap_or_default(),
|
|
ram_size: hardware.memory.total.unwrap_or_default(),
|
|
};
|
|
|
|
// Try to register (will retry on failure)
|
|
loop {
|
|
println!("Attempting to register with server...");
|
|
let url = format!("{}/monitoring/register-agent-by-id", base_url);
|
|
match client.post(&url).json(®istration).send().await {
|
|
Ok(resp) if resp.status().is_success() => {
|
|
println!("✅ Successfully registered with server.");
|
|
return Ok((server_id, registered_ip));
|
|
}
|
|
Ok(resp) => {
|
|
let status = resp.status();
|
|
let text = resp.text().await.unwrap_or_default();
|
|
println!(
|
|
"⚠️ Registration failed ({}): {} (will retry in 10 seconds)",
|
|
status, text
|
|
);
|
|
}
|
|
Err(err) => {
|
|
println!("⚠️ Registration error: {} (will retry in 10 seconds)", err);
|
|
}
|
|
}
|
|
sleep(Duration::from_secs(10)).await;
|
|
}
|
|
}
|
|
|
|
async fn get_server_id_by_ip(
|
|
base_url: &str,
|
|
ip: &str,
|
|
) -> Result<(i32, String), Box<dyn Error + Send + Sync>> {
|
|
let client = Client::builder()
|
|
.danger_accept_invalid_certs(true)
|
|
.build()?;
|
|
|
|
let url = format!("{}/monitoring/server-id-by-ip?ipAddress={}", base_url, ip);
|
|
|
|
loop {
|
|
println!("Attempting to fetch server ID for IP {}...", ip);
|
|
match client.get(&url).send().await {
|
|
Ok(resp) if resp.status().is_success() => {
|
|
let text = resp.text().await?;
|
|
println!("Raw response: {}", text); // Debug output
|
|
|
|
let id_resp: IdResponse = serde_json::from_str(&text).map_err(|e| {
|
|
println!("Failed to parse response: {}", e);
|
|
e
|
|
})?;
|
|
|
|
println!(
|
|
"✅ Received ID {} for IP {}",
|
|
id_resp.id, id_resp.ip_address
|
|
);
|
|
return Ok((id_resp.id, id_resp.ip_address));
|
|
}
|
|
Ok(resp) if resp.status() == StatusCode::NOT_FOUND => {
|
|
println!(
|
|
"❌ Server with IP {} not found in database (will retry in 10 seconds)",
|
|
ip
|
|
);
|
|
sleep(Duration::from_secs(10)).await;
|
|
}
|
|
Ok(resp) => {
|
|
println!(
|
|
"⚠️ Server responded with status: {} - {}",
|
|
resp.status(),
|
|
resp.text().await?
|
|
);
|
|
sleep(Duration::from_secs(10)).await;
|
|
}
|
|
Err(err) => {
|
|
println!("⚠️ Request failed: {} (will retry in 10 seconds)", err);
|
|
sleep(Duration::from_secs(10)).await;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
pub async fn heartbeat_loop(base_url: &str, ip: &str) -> Result<(), Box<dyn Error + Send + Sync>> {
|
|
let client = Client::builder()
|
|
.danger_accept_invalid_certs(true)
|
|
.build()?;
|
|
let url = format!("{}/heartbeat/receive", base_url);
|
|
|
|
loop {
|
|
let payload = HeartbeatDto {
|
|
ip_address: ip.to_string(),
|
|
};
|
|
|
|
match client.post(&url).json(&payload).send().await {
|
|
Ok(res) if res.status().is_success() => {
|
|
println!("✅ Heartbeat sent successfully.");
|
|
}
|
|
Ok(res) => eprintln!("Server responded with status: {}", res.status()),
|
|
Err(e) => eprintln!("Heartbeat error: {}", e),
|
|
}
|
|
|
|
sleep(Duration::from_secs(20)).await;
|
|
}
|
|
}
|
|
|
|
pub async fn send_metrics(
|
|
base_url: &str,
|
|
metrics: &MetricDto,
|
|
) -> Result<(), Box<dyn Error + Send + Sync>> {
|
|
let client = Client::new();
|
|
let url = format!("{}/monitoring/metric", base_url);
|
|
println!("Metrics: {:?}", metrics);
|
|
|
|
match client.post(&url).json(&metrics).send().await {
|
|
Ok(res) => println!(
|
|
"✅ Sent metrics for server {} | Status: {}",
|
|
metrics.server_id,
|
|
res.status()
|
|
),
|
|
Err(err) => eprintln!("❌ Failed to send metrics: {}", err),
|
|
}
|
|
|
|
Ok(())
|
|
}
|
|
|
|
//test
|