fix: added connection retry for site-id

This commit is contained in:
etiennecollin
2025-08-22 13:27:51 -04:00
parent ad42110722
commit 1f534b45c3
3 changed files with 31 additions and 23 deletions

View File

@@ -53,13 +53,9 @@ impl Environment {
}; };
let unifi_has_valid_cert: bool = match env::var("UNIFI_HAS_VALID_CERT") { let unifi_has_valid_cert: bool = match env::var("UNIFI_HAS_VALID_CERT") {
Ok(val) => match val.trim().to_lowercase().as_str() { Ok(val) => {
"true" | "1" | "yes" => true, Self::parse_bool(&val).map_err(|e| format!("Invalid UNIFI_HAS_VALID_CERT: {e}"))?
"false" | "0" | "no" => false, }
_ => {
return Err("Invalid UNIFI_HAS_VALID_CERT, must be true/false".to_string());
}
},
Err(_) => true, Err(_) => true,
}; };
@@ -90,4 +86,12 @@ impl Environment {
timezone, timezone,
}) })
} }
fn parse_bool(s: &str) -> Result<bool, String> {
match s.trim().to_lowercase().as_str() {
"true" | "1" | "yes" => Ok(true),
"false" | "0" | "no" => Ok(false),
_ => Err(format!("Boolean value must be true or false, found: {s}")),
}
}
} }

View File

@@ -9,7 +9,7 @@ use backend::{
unifi_api::{UNIFI_API, UnifiAPI}, unifi_api::{UNIFI_API, UnifiAPI},
}; };
use tower_http::cors::{Any, CorsLayer}; use tower_http::cors::{Any, CorsLayer};
use tracing::{error, info, level_filters::LevelFilter}; use tracing::{error, info, level_filters::LevelFilter, warn};
use tracing_subscriber::EnvFilter; use tracing_subscriber::EnvFilter;
#[tokio::main] #[tokio::main]
@@ -35,14 +35,20 @@ async fn main() {
.set(env) .set(env)
.expect("Failed to set environment variables"); .expect("Failed to set environment variables");
let unifi_api = match UnifiAPI::new().await { loop {
Ok(api) => api, match UnifiAPI::try_new().await {
Err(_) => { Ok(api) => {
error!("Failed to initialize UnifiAPI wrapper"); UNIFI_API.set(api).expect("Failed to set UnifiAPI");
std::process::exit(1); info!("Successfully connected to Unifi controller");
break;
}
Err(e) => {
error!("Failed to initialize UnifiAPI wrapper: {}", e);
warn!("Retrying connection in 5 seconds...");
tokio::time::sleep(std::time::Duration::from_secs(5)).await;
}
} }
}; }
UNIFI_API.set(unifi_api).expect("Failed to set UnifiAPI");
let cors = CorsLayer::new() let cors = CorsLayer::new()
.allow_headers([http::header::CONTENT_TYPE]) .allow_headers([http::header::CONTENT_TYPE])

View File

@@ -1,3 +1,4 @@
use axum::http::HeaderValue;
use chrono::DateTime; use chrono::DateTime;
use chrono_tz::Tz; use chrono_tz::Tz;
use reqwest::{Client, ClientBuilder, StatusCode}; use reqwest::{Client, ClientBuilder, StatusCode};
@@ -32,20 +33,18 @@ pub struct UnifiAPI<'a> {
} }
impl<'a> UnifiAPI<'a> { impl<'a> UnifiAPI<'a> {
pub async fn new() -> Result<Self, ()> { pub async fn try_new() -> Result<Self, String> {
let environment: &Environment = ENVIRONMENT.get().expect("Environment not set"); let environment: &Environment = ENVIRONMENT.get().expect("Environment not set");
let mut headers = reqwest::header::HeaderMap::with_capacity(2); let mut headers = reqwest::header::HeaderMap::with_capacity(2);
headers.insert( headers.insert(
reqwest::header::CONTENT_TYPE, reqwest::header::CONTENT_TYPE,
reqwest::header::HeaderValue::from_static("application/json"), HeaderValue::from_static("application/json"),
); );
headers.insert( headers.insert(
"X-API-Key", "X-API-Key",
environment HeaderValue::from_str(&environment.unifi_api_key)
.unifi_api_key .map_err(|e| format!("Failed to set X-API-Key header: {e}"))?,
.parse()
.expect("Could not parse API Key"),
); );
let client = ClientBuilder::new() let client = ClientBuilder::new()
@@ -70,8 +69,7 @@ impl<'a> UnifiAPI<'a> {
let id = match unifi_api.get_default_site_id().await { let id = match unifi_api.get_default_site_id().await {
Ok(id) => id, Ok(id) => id,
Err(e) => { Err(e) => {
error!("Failed to fetch default site ID: {}", e); return Err(format!("Failed to fetch default site ID: {e}"));
return Err(());
} }
}; };
info!("Default site ID found: {}", id); info!("Default site ID found: {}", id);