feat/web (Patchset 2) (#444)

This patch implement a restful server without any auth.

usage:

```bash
# run easytier-web, which acts as an gateway and registry for all easytier-core
$> easytier-web

# run easytier-core and connect to easytier-web with a token
$> easytier-core --config-server udp://127.0.0.1:22020/fdsafdsa

# use restful api to list session
$> curl -H "Content-Type: application/json" -X GET 127.0.0.1:11211/api/v1/sessions
[{"token":"fdsafdsa","client_url":"udp://127.0.0.1:48915","machine_id":"de3f5b8f-0f2f-d9d0-fb30-a2ac8951d92f"}]%

# use restful api to run a network instance
$> curl -H "Content-Type: application/json" -X POST 127.0.0.1:11211/api/v1/network/de3f5b8f-0f2f-d9d0-fb30-a2ac8951d92f -d '{"config": "listeners = [\"udp://0.0.0.0:12344\"]"}'

# use restful api to get network instance info
$> curl -H "Content-Type: application/json" -X GET 127.0.0.1:11211/api/v1/network/de3f5b8f-0f2f-d9d0-fb30-a2ac8951d92f/65437e50-b286-4098-a624-74429f2cb839 
```
This commit is contained in:
Sijie.Sun
2024-10-26 00:04:22 +08:00
committed by GitHub
parent b5c3726e67
commit a78b759741
33 changed files with 1539 additions and 263 deletions
+52 -57
View File
@@ -7,14 +7,18 @@ use tabled::settings::Style;
use tokio::time::timeout;
use easytier::{
common::{constants::EASYTIER_VERSION, stun::StunInfoCollector, stun::StunInfoCollectorTrait},
common::{
constants::EASYTIER_VERSION,
stun::{StunInfoCollector, StunInfoCollectorTrait},
},
proto::{
cli::{
ConnectorManageRpc, ConnectorManageRpcClientFactory, DumpRouteRequest,
GetVpnPortalInfoRequest, ListConnectorRequest, ListForeignNetworkRequest,
ListGlobalForeignNetworkRequest, ListPeerRequest, ListPeerResponse, ListRouteRequest,
ListRouteResponse, NodeInfo, PeerManageRpc, PeerManageRpcClientFactory,
ShowNodeInfoRequest, VpnPortalRpc, VpnPortalRpcClientFactory,
list_peer_route_pair, ConnectorManageRpc, ConnectorManageRpcClientFactory,
DumpRouteRequest, GetVpnPortalInfoRequest, ListConnectorRequest,
ListForeignNetworkRequest, ListGlobalForeignNetworkRequest, ListPeerRequest,
ListPeerResponse, ListRouteRequest, ListRouteResponse, NodeInfo, PeerManageRpc,
PeerManageRpcClientFactory, ShowNodeInfoRequest, VpnPortalRpc,
VpnPortalRpcClientFactory,
},
common::NatType,
peer_rpc::{GetGlobalPeerMapRequest, PeerCenterRpc, PeerCenterRpcClientFactory},
@@ -22,7 +26,7 @@ use easytier::{
rpc_types::controller::BaseController,
},
tunnel::tcp::TcpTunnelConnector,
utils::{cost_to_str, float_to_str, list_peer_route_pair, PeerRoutePair},
utils::{cost_to_str, float_to_str, PeerRoutePair},
};
#[derive(Parser, Debug)]
@@ -222,25 +226,26 @@ impl CommandHandler {
impl From<PeerRoutePair> for PeerTableItem {
fn from(p: PeerRoutePair) -> Self {
let route = p.route.clone().unwrap_or_default();
PeerTableItem {
ipv4: p
.route
.ipv4_addr
.map(|ip| ip.to_string())
.unwrap_or_default(),
hostname: p.route.hostname.clone(),
cost: cost_to_str(p.route.cost),
ipv4: route.ipv4_addr.map(|ip| ip.to_string()).unwrap_or_default(),
hostname: route.hostname.clone(),
cost: cost_to_str(route.cost),
lat_ms: float_to_str(p.get_latency_ms().unwrap_or(0.0), 3),
loss_rate: float_to_str(p.get_loss_rate().unwrap_or(0.0), 3),
rx_bytes: format_size(p.get_rx_bytes().unwrap_or(0), humansize::DECIMAL),
tx_bytes: format_size(p.get_tx_bytes().unwrap_or(0), humansize::DECIMAL),
tunnel_proto: p.get_conn_protos().unwrap_or_default().join(",").to_string(),
tunnel_proto: p
.get_conn_protos()
.unwrap_or_default()
.join(",")
.to_string(),
nat_type: p.get_udp_nat_type(),
id: p.route.peer_id.to_string(),
version: if p.route.version.is_empty() {
id: route.peer_id.to_string(),
version: if route.version.is_empty() {
"unknown".to_string()
} else {
p.route.version.to_string()
route.version.to_string()
},
}
}
@@ -287,10 +292,7 @@ impl CommandHandler {
items.push(p.into());
}
println!(
"{}",
tabled::Table::new(items).with(Style::modern())
);
println!("{}", tabled::Table::new(items).with(Style::modern()));
Ok(())
}
@@ -404,62 +406,59 @@ impl CommandHandler {
});
let peer_routes = self.list_peer_route_pair().await?;
for p in peer_routes.iter() {
let Some(next_hop_pair) = peer_routes
.iter()
.find(|pair| pair.route.peer_id == p.route.next_hop_peer_id)
else {
let Some(next_hop_pair) = peer_routes.iter().find(|pair| {
pair.route.clone().unwrap_or_default().peer_id
== p.route.clone().unwrap_or_default().next_hop_peer_id
}) else {
continue;
};
if p.route.cost == 1 {
let route = p.route.clone().unwrap_or_default();
if route.cost == 1 {
items.push(RouteTableItem {
ipv4: p
.route
.ipv4_addr
.map(|ip| ip.to_string())
.unwrap_or_default(),
hostname: p.route.hostname.clone(),
proxy_cidrs: p.route.proxy_cidrs.clone().join(",").to_string(),
ipv4: route.ipv4_addr.map(|ip| ip.to_string()).unwrap_or_default(),
hostname: route.hostname.clone(),
proxy_cidrs: route.proxy_cidrs.clone().join(",").to_string(),
next_hop_ipv4: "DIRECT".to_string(),
next_hop_hostname: "".to_string(),
next_hop_lat: next_hop_pair.get_latency_ms().unwrap_or(0.0),
cost: p.route.cost,
version: if p.route.version.is_empty() {
cost: route.cost,
version: if route.version.is_empty() {
"unknown".to_string()
} else {
p.route.version.to_string()
route.version.to_string()
},
});
} else {
items.push(RouteTableItem {
ipv4: p
.route
.ipv4_addr
.map(|ip| ip.to_string())
.unwrap_or_default(),
hostname: p.route.hostname.clone(),
proxy_cidrs: p.route.proxy_cidrs.clone().join(",").to_string(),
ipv4: route.ipv4_addr.map(|ip| ip.to_string()).unwrap_or_default(),
hostname: route.hostname.clone(),
proxy_cidrs: route.proxy_cidrs.clone().join(",").to_string(),
next_hop_ipv4: next_hop_pair
.route
.clone()
.unwrap_or_default()
.ipv4_addr
.map(|ip| ip.to_string())
.unwrap_or_default(),
next_hop_hostname: next_hop_pair.route.hostname.clone(),
next_hop_hostname: next_hop_pair
.route
.clone()
.unwrap_or_default()
.hostname
.clone(),
next_hop_lat: next_hop_pair.get_latency_ms().unwrap_or(0.0),
cost: p.route.cost,
version: if p.route.version.is_empty() {
cost: route.cost,
version: if route.version.is_empty() {
"unknown".to_string()
} else {
p.route.version.to_string()
route.version.to_string()
},
});
}
}
println!(
"{}",
tabled::Table::new(items).with(Style::modern())
);
println!("{}", tabled::Table::new(items).with(Style::modern()));
Ok(())
}
@@ -576,11 +575,7 @@ async fn main() -> Result<(), Error> {
});
}
println!(
"{}",
tabled::Table::new(table_rows)
.with(Style::modern())
);
println!("{}", tabled::Table::new(table_rows).with(Style::modern()));
}
SubCommand::VpnPortal => {
let vpn_portal_client = handler.get_vpn_portal_client().await?;