Skip to content

Commit a98547c

Browse files
committed
feat: show p2p config in doctor info
1 parent 52168f1 commit a98547c

2 files changed

Lines changed: 88 additions & 0 deletions

File tree

aruna-doctor/src/error.rs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -73,4 +73,10 @@ pub enum CliError {
7373
MissingInitialOnboardingSecret,
7474
#[error("Arbitrary user ids require --unsafe-arbitrary-user-id")]
7575
UnsafeUserIdRequired,
76+
#[error("invalid {key} value {value:?}: {message}")]
77+
InvalidConfigValue {
78+
key: &'static str,
79+
value: String,
80+
message: String,
81+
},
7682
}

aruna-doctor/src/info.rs

Lines changed: 82 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,10 @@ struct ConfigView {
2828
p2p_socket_addr: String,
2929
max_concurrent_uni_streams: Option<u64>,
3030
max_concurrent_bidi_streams: Option<u64>,
31+
p2p_discovery_methods: Vec<String>,
32+
p2p_discovery_dns_origins: Vec<String>,
33+
p2p_relay_method: String,
34+
p2p_relay_urls: Vec<String>,
3135
bootstrap_nodes: Vec<String>,
3236
bootstrap_endpoints: Vec<String>,
3337
default_metadata_replication_factor: u32,
@@ -158,6 +162,10 @@ impl ConfigView {
158162
.unwrap_or_else(|_| http_socket_addr.to_string()),
159163
max_concurrent_uni_streams: parse_optional_env("MAX_CONCURRENT_UNI_STREAMS")?,
160164
max_concurrent_bidi_streams: parse_optional_env("MAX_CONCURRENT_BIDI_STREAMS")?,
165+
p2p_discovery_methods: discovery_methods_from_env()?,
166+
p2p_discovery_dns_origins: parse_list_env("P2P_DISCOVERY_DNS_ORIGINS"),
167+
p2p_relay_method: relay_method_from_env()?,
168+
p2p_relay_urls: parse_list_env("P2P_RELAY_URLS"),
161169
bootstrap_nodes: parse_list_env("BOOTSTRAP_NODES"),
162170
bootstrap_endpoints: parse_list_env("BOOTSTRAP_ENDPOINTS"),
163171
default_metadata_replication_factor: parse_optional_env("METADATA_REPLICATION_FACTOR")?
@@ -208,6 +216,56 @@ fn parse_list_env(key: &str) -> Vec<String> {
208216
.collect()
209217
}
210218

219+
fn discovery_methods_from_env() -> Result<Vec<String>, CliError> {
220+
let value = optional_env("P2P_DISCOVERY_METHOD").unwrap_or_else(|| "none".to_string());
221+
match normalize_env_value(&value).as_str() {
222+
"none" => Ok(Vec::new()),
223+
"n0" | "n0_dns" => Ok(vec!["n0_dns".to_string()]),
224+
"custom_dns" => Ok(vec!["custom_dns".to_string()]),
225+
_ => Err(invalid_config_value(
226+
"P2P_DISCOVERY_METHOD",
227+
value,
228+
"expected one of none, n0, n0_dns, custom_dns",
229+
)),
230+
}
231+
}
232+
233+
fn relay_method_from_env() -> Result<String, CliError> {
234+
let value = optional_env("P2P_RELAY_METHOD").unwrap_or_else(|| "none".to_string());
235+
match normalize_env_value(&value).as_str() {
236+
"none" => Ok("none".to_string()),
237+
"n0" => Ok("n0".to_string()),
238+
"custom" => Ok("custom".to_string()),
239+
_ => Err(invalid_config_value(
240+
"P2P_RELAY_METHOD",
241+
value,
242+
"expected one of none, n0, custom",
243+
)),
244+
}
245+
}
246+
247+
fn optional_env(key: &str) -> Option<String> {
248+
dotenvy::var(key)
249+
.ok()
250+
.filter(|value| !value.trim().is_empty())
251+
}
252+
253+
fn normalize_env_value(value: &str) -> String {
254+
value.trim().to_ascii_lowercase().replace('-', "_")
255+
}
256+
257+
fn invalid_config_value(
258+
key: &'static str,
259+
value: impl Into<String>,
260+
message: impl std::fmt::Display,
261+
) -> CliError {
262+
CliError::InvalidConfigValue {
263+
key,
264+
value: value.into(),
265+
message: message.to_string(),
266+
}
267+
}
268+
211269
fn env_key(id: &str) -> String {
212270
id.to_ascii_uppercase().replace('-', "_")
213271
}
@@ -397,6 +455,28 @@ mod tests {
397455

398456
assert_eq!(view.http_base_url, "http://127.0.0.1:3000");
399457
assert!(view.onboarding_secret_present);
458+
assert!(view.p2p_discovery_methods.is_empty());
459+
assert_eq!(view.p2p_relay_method, "none");
460+
}
461+
462+
#[tokio::test]
463+
async fn config_view_reports_p2p_discovery_and_relay_config() {
464+
let _env_lock = env_lock().lock().await;
465+
let _guard = TestEnvGuard::set(&[
466+
("P2P_DISCOVERY_METHOD", "n0".to_string()),
467+
("P2P_RELAY_METHOD", "custom".to_string()),
468+
("P2P_RELAY_URLS", "https://relay.example.com".to_string()),
469+
("BOOTSTRAP_ENDPOINTS", "node.example.invalid".to_string()),
470+
]);
471+
let view = ConfigView::from_env("0.0.0.0:3000".parse().unwrap()).unwrap();
472+
473+
assert_eq!(view.p2p_discovery_methods, vec!["n0_dns"]);
474+
assert_eq!(view.p2p_relay_method, "custom");
475+
assert_eq!(
476+
view.p2p_relay_urls,
477+
vec!["https://relay.example.com".to_string()]
478+
);
479+
assert_eq!(view.bootstrap_endpoints, vec!["node.example.invalid"]);
400480
}
401481

402482
#[tokio::test]
@@ -410,6 +490,8 @@ mod tests {
410490
info.net_state.status,
411491
aruna_api::routes::info::ServiceStatus::Available
412492
);
493+
assert!(info.net_state.discovery_methods.is_empty());
494+
assert_eq!(info.net_state.relay_method.as_deref(), Some("none"));
413495
assert_eq!(
414496
info.interface_status.rest.status,
415497
aruna_api::routes::info::ServiceStatus::Available

0 commit comments

Comments
 (0)