From 24143cbf1c059dd4d5798b1f177f34aa25809de9 Mon Sep 17 00:00:00 2001 From: "Sijie.Sun" Date: Sun, 7 Jul 2024 16:51:20 +0800 Subject: [PATCH] add verbose cli mode; add list foreign network (#156) --- easytier/proto/cli.proto | 10 ++++ easytier/src/easytier-cli.rs | 60 +++++++++++++++++-- easytier/src/peers/foreign_network_manager.rs | 44 +++++++++++--- easytier/src/peers/rpc_service.rs | 15 ++++- 4 files changed, 113 insertions(+), 16 deletions(-) diff --git a/easytier/proto/cli.proto b/easytier/proto/cli.proto index 03bdba2..76a47a2 100644 --- a/easytier/proto/cli.proto +++ b/easytier/proto/cli.proto @@ -81,10 +81,20 @@ message DumpRouteRequest {} message DumpRouteResponse { string result = 1; } +message ListForeignNetworkRequest {} + +message ForeignNetworkEntryPb { repeated PeerInfo peers = 1; } + +message ListForeignNetworkResponse { + map foreign_networks = 1; +} + service PeerManageRpc { rpc ListPeer(ListPeerRequest) returns (ListPeerResponse); rpc ListRoute(ListRouteRequest) returns (ListRouteResponse); rpc DumpRoute(DumpRouteRequest) returns (DumpRouteResponse); + rpc ListForeignNetwork(ListForeignNetworkRequest) + returns (ListForeignNetworkResponse); } enum ConnectorStatus { diff --git a/easytier/src/easytier-cli.rs b/easytier/src/easytier-cli.rs index bfcf96c..08f49f2 100644 --- a/easytier/src/easytier-cli.rs +++ b/easytier/src/easytier-cli.rs @@ -33,6 +33,9 @@ struct Cli { #[arg(short = 'p', long, default_value = "127.0.0.1:15888")] rpc_portal: SocketAddr, + #[arg(short, long, default_value = "false", help = "verbose output")] + verbose: bool, + #[command(subcommand)] sub_command: SubCommand, } @@ -49,12 +52,6 @@ enum SubCommand { #[derive(Args, Debug)] struct PeerArgs { - #[arg(short, long)] - ipv4: Option, - - #[arg(short, long)] - peers: Vec, - #[command(subcommand)] sub_command: Option, } @@ -70,6 +67,7 @@ enum PeerSubCommand { Add, Remove, List(PeerListArgs), + ListForeign, } #[derive(Args, Debug)] @@ -113,6 +111,7 @@ enum Error { struct CommandHandler { addr: String, + verbose: bool, } impl CommandHandler { @@ -204,6 +203,11 @@ impl CommandHandler { let mut items: Vec = vec![]; let peer_routes = self.list_peer_route_pair().await?; + if self.verbose { + println!("{:#?}", peer_routes); + return Ok(()); + } + for p in peer_routes { items.push(p.into()); } @@ -224,6 +228,46 @@ impl CommandHandler { Ok(()) } + async fn handle_foreign_network_list(&self) -> Result<(), Error> { + let mut client = self.get_peer_manager_client().await?; + let request = tonic::Request::new(ListForeignNetworkRequest::default()); + let response = client.list_foreign_network(request).await?; + let network_map = response.into_inner(); + if self.verbose { + println!("{:#?}", network_map); + return Ok(()); + } + + for (idx, (k, v)) in network_map.foreign_networks.iter().enumerate() { + println!("{} Network Name: {}", idx + 1, k); + for peer in v.peers.iter() { + println!( + " peer_id: {}, peer_conn_count: {}, conns: [ {} ]", + peer.peer_id, + peer.conns.len(), + peer.conns + .iter() + .map(|conn| format!( + "remote_addr: {}, rx_bytes: {}, tx_bytes: {}, latency_us: {}", + conn.tunnel + .as_ref() + .map(|t| t.remote_addr.clone()) + .unwrap_or_default(), + conn.stats.as_ref().map(|s| s.rx_bytes).unwrap_or_default(), + conn.stats.as_ref().map(|s| s.tx_bytes).unwrap_or_default(), + conn.stats + .as_ref() + .map(|s| s.latency_us) + .unwrap_or_default(), + )) + .collect::>() + .join("; ") + ); + } + } + Ok(()) + } + async fn handle_route_list(&self) -> Result<(), Error> { #[derive(tabled::Tabled)] struct RouteTableItem { @@ -292,6 +336,7 @@ async fn main() -> Result<(), Error> { let cli = Cli::parse(); let handler = CommandHandler { addr: format!("http://{}:{}", cli.rpc_portal.ip(), cli.rpc_portal.port()), + verbose: cli.verbose, }; match cli.sub_command { @@ -309,6 +354,9 @@ async fn main() -> Result<(), Error> { handler.handle_peer_list(&peer_args).await?; } } + Some(PeerSubCommand::ListForeign) => { + handler.handle_foreign_network_list().await?; + } None => { handler.handle_peer_list(&peer_args).await?; } diff --git a/easytier/src/peers/foreign_network_manager.rs b/easytier/src/peers/foreign_network_manager.rs index 35ef2f8..beecaa3 100644 --- a/easytier/src/peers/foreign_network_manager.rs +++ b/easytier/src/peers/foreign_network_manager.rs @@ -22,6 +22,7 @@ use crate::{ global_ctx::{ArcGlobalCtx, GlobalCtxEvent, NetworkIdentity}, PeerId, }, + rpc::{ForeignNetworkEntryPb, ListForeignNetworkResponse, PeerInfo}, tunnel::packet_def::{PacketType, ZCPacket}, }; @@ -306,15 +307,16 @@ impl ForeignNetworkManager { self.register_peer_rpc_service().await; } - pub async fn list_foreign_networks(&self) -> DashMap> { - let ret = DashMap::new(); - for item in self.data.network_peer_maps.iter() { - let network_name = item.key().clone(); - ret.insert(network_name, vec![]); - } + pub async fn list_foreign_networks(&self) -> ListForeignNetworkResponse { + let mut ret = ListForeignNetworkResponse::default(); + let networks = self + .data + .network_peer_maps + .iter() + .map(|v| v.key().clone()) + .collect::>(); - for mut n in ret.iter_mut() { - let network_name = n.key().clone(); + for network_name in networks { let Some(item) = self .data .network_peer_maps @@ -323,7 +325,16 @@ impl ForeignNetworkManager { else { continue; }; - n.value_mut().extend(item.peer_map.list_peers().await); + + let mut entry = ForeignNetworkEntryPb::default(); + for peer in item.peer_map.list_peers().await { + let mut peer_info = PeerInfo::default(); + peer_info.peer_id = peer; + peer_info.conns = item.peer_map.list_peer_conns(peer).await.unwrap_or(vec![]); + entry.peers.push(peer_info); + } + + ret.foreign_networks.insert(network_name, entry); } ret } @@ -379,6 +390,13 @@ mod tests { .unwrap(); assert_eq!(1, pma_net1.list_routes().await.len()); assert_eq!(1, pmb_net1.list_routes().await.len()); + + let rpc_resp = pm_center + .get_foreign_network_manager() + .list_foreign_networks() + .await; + assert_eq!(1, rpc_resp.foreign_networks.len()); + assert_eq!(2, rpc_resp.foreign_networks["net1"].peers.len()); } #[tokio::test] @@ -484,6 +502,14 @@ mod tests { .len() ); + let rpc_resp = pm_center + .get_foreign_network_manager() + .list_foreign_networks() + .await; + assert_eq!(2, rpc_resp.foreign_networks.len()); + assert_eq!(3, rpc_resp.foreign_networks["net1"].peers.len()); + assert_eq!(2, rpc_resp.foreign_networks["net2"].peers.len()); + drop(pmb_net2); tokio::time::sleep(std::time::Duration::from_secs(1)).await; assert_eq!( diff --git a/easytier/src/peers/rpc_service.rs b/easytier/src/peers/rpc_service.rs index 2323e34..425e530 100644 --- a/easytier/src/peers/rpc_service.rs +++ b/easytier/src/peers/rpc_service.rs @@ -2,7 +2,8 @@ use std::sync::Arc; use crate::rpc::{ cli::PeerInfo, peer_manage_rpc_server::PeerManageRpc, DumpRouteRequest, DumpRouteResponse, - ListPeerRequest, ListPeerResponse, ListRouteRequest, ListRouteResponse, + ListForeignNetworkRequest, ListForeignNetworkResponse, ListPeerRequest, ListPeerResponse, + ListRouteRequest, ListRouteResponse, }; use tonic::{Request, Response, Status}; @@ -68,4 +69,16 @@ impl PeerManageRpc for PeerManagerRpcService { reply.result = self.peer_manager.dump_route().await; Ok(Response::new(reply)) } + + async fn list_foreign_network( + &self, + _request: Request, // Accept request of type HelloRequest + ) -> Result, Status> { + let reply = self + .peer_manager + .get_foreign_network_manager() + .list_foreign_networks() + .await; + Ok(Response::new(reply)) + } }