diff --git a/src/main.rs b/src/main.rs index 7bf0e55..ded175e 100644 --- a/src/main.rs +++ b/src/main.rs @@ -51,48 +51,52 @@ async fn route_crawl_domain(Query(params): Query) -> Json { axum::Json(collector.collect().await) } - #[async_recursion::async_recursion] -async fn scan_instance(domain: &str, map: MapHandle) -> Option<()> { - if map.already_scanned(domain).await { return None }; +async fn scan_instance(domain: &str, map: MapHandle) { + if map.already_scanned(domain).await { return }; tracing::debug!("scanning instance {}", domain); let response = match CACHE.instance_metadata(domain).await { Ok(Some(r)) => r, Ok(None) => { - tracing::info!("instance {} doesn't provide metadata", domain); - map.add_node(domain.to_string(), domain.to_string()); - return None + tracing::info!("instance {} doesn't provide nodeinfo api", domain); + return map.add_node(domain.to_string(), domain.to_string()); }, Err(e) => { - tracing::warn!("could not fetch metadata for {}: {}", domain, e); - return None + return tracing::warn!("could not fetch metadata for {}: {}", domain, e); } }; - let node_name : String = response - .get("metadata")? - .get("nodeName")? - .as_str()? - .to_string(); + let metadata = match response.get("metadata") { + Some(m) => m, + None => { + tracing::info!("instance {} doesn't provide metadata", domain); + return map.add_node(domain.to_string(), domain.to_string()); + } + }; - tracing::info!("adding instance {}", node_name); + let node_name = match metadata.get("nodeName") { + Some(v) => v.as_str().unwrap_or("").to_string(), + None => domain.to_string(), + }; + + tracing::info!("adding instance {} ({})", node_name, domain); map.add_node(domain.to_string(), node_name); + let local_bubble = match metadata.get("localBubbleInstances") { + None => return tracing::info!("instance {} doesn't provide local bubble data", domain), + Some(b) => match b.as_array() { + None => return tracing::warn!("instance {} local bubble is not an array", domain), + Some(v) => v, + }, + }; + let mut tasks = Vec::new(); - for bubble_instance in response - .get("metadata")? - .get("localBubbleInstances")? - .as_array()? - .iter() - .filter_map(|x| x.as_str().map(|x| x.to_string())) - { + for bubble_instance in local_bubble.iter().filter_map(|x| x.as_str().map(|x| x.to_string())) { let _map = map.clone(); map.add_vertex(domain.to_string(), bubble_instance.clone()); tasks.push(tokio::spawn(async move { scan_instance(&bubble_instance, _map).await; })); } - - Some(()) }