mirror of
https://github.com/EasyTier/EasyTier.git
synced 2026-09-03 09:35:41 +00:00
refactor(core): separate portable core from native runtime (#2451)
Create easytier-core as the portable owner of configuration, connectivity, tunnels, peer and routing state, gateways, management, the data plane, and instance lifecycle. Keep operating-system integration, native protocol engines, process startup, and presentation in easytier behind explicit Host capability adapters. Create easytier-proto to own schemas, generated RPC types, descriptors, and feature-scoped protocol slices. Remove runtime protobuf reflection from core while preserving unknown route-peer fields across forwarding. Normalize instance construction through CoreInstance, CoreHostAdapters, CoreProcessRuntime, and InstanceManager. Make the runtime config store the only authoritative mutable configuration after startup. Move the portable TCP/UDP data plane into core and extract a generic OperationBroker for completion, cancellation, disposal, and capacity accounting. Expose the session-based FFI v2 completion API and keep the WASI guest ABI, wire schemas, and adapters with core. Migrate CLI, GUI, web, FFI, Android JNI, OHOS, uptime, and mobile consumers to the shared manager and core state. Add explicit user/web config ownership and revision-aware web reconciliation. Preserve configuration, wire, and management behavior while fixing regressions discovered by the full platform and integration matrix: - inherit advertised relay capabilities in foreign networks; - refresh OSPF peer state immediately after runtime config changes; - restore CLI GlobalCtx event output without forcing GUI logging; - retain legacy encryption names and standalone RPC tunnel metadata; - restore ICMP host composition and fragmented UDP handling; - use portable 64-bit atomics on 32-bit MIPS targets; and - retain discarded operations until late cancellation completes. Validate the refactor across 45 GitHub checks, including Linux, macOS, Windows, FreeBSD, web, GUI, Android, OHOS, feature profiles, and three-node and subnet-proxy integration tests. BREAKING CHANGE: internal Rust module paths are not preserved. Legacy native data-plane APIs are replaced by the session-based FFI v2 API. The dedicated Android data-plane wrapper is removed.
This commit is contained in:
@@ -11,7 +11,10 @@ use easytier::{
|
||||
api::manage::{ConfigSource as RpcConfigSource, NetworkConfig, NetworkMeta},
|
||||
common::Uuid as RpcUuid,
|
||||
},
|
||||
rpc_service::remote_client::{ListNetworkProps, PersistentConfig as _, Storage as _},
|
||||
};
|
||||
use easytier_core::management::config_source_from_rpc;
|
||||
use easytier_core::management::remote_client::{
|
||||
ListNetworkProps, PersistentConfig as _, Storage as _,
|
||||
};
|
||||
|
||||
use super::storage::Storage;
|
||||
@@ -469,7 +472,7 @@ pub(super) async fn sync_running_config_sources(
|
||||
continue;
|
||||
};
|
||||
|
||||
let Some(running_source) = ConfigSource::from_rpc(meta.source) else {
|
||||
let Some(running_source) = config_source_from_rpc(meta.source) else {
|
||||
continue;
|
||||
};
|
||||
let local_source = PersistedConfigSource::from_db(&local_cfg.source);
|
||||
@@ -503,9 +506,11 @@ mod tests {
|
||||
use std::collections::HashSet;
|
||||
|
||||
use easytier::{
|
||||
common::config::{ConfigLoader as _, ConfigSource},
|
||||
common::config::{ConfigLoader as _, ConfigSource, NetworkConfigExt},
|
||||
proto::api::manage::{ConfigSource as RpcConfigSource, NetworkConfig, NetworkMeta},
|
||||
rpc_service::remote_client::{ListNetworkProps, PersistentConfig as _, Storage as _},
|
||||
};
|
||||
use easytier_core::management::remote_client::{
|
||||
ListNetworkProps, PersistentConfig as _, Storage as _,
|
||||
};
|
||||
use serde_json::json;
|
||||
|
||||
|
||||
@@ -10,13 +10,13 @@ use std::sync::{
|
||||
use std::time::Duration;
|
||||
|
||||
use dashmap::DashMap;
|
||||
use easytier::{
|
||||
proto::{
|
||||
api::manage::WebClientService, rpc_types::controller::BaseController, web::HeartbeatRequest,
|
||||
},
|
||||
rpc_service::remote_client::{self, RemoteClientManager},
|
||||
tunnel::TunnelListener,
|
||||
web_client::security,
|
||||
use easytier::proto::{
|
||||
api::manage::WebClientService, rpc_types::controller::BaseController, web::HeartbeatRequest,
|
||||
};
|
||||
use easytier_core::{
|
||||
management::remote_client::{self, RemoteClientManager},
|
||||
socket::SocketListener,
|
||||
tunnel::{Tunnel, web_security},
|
||||
};
|
||||
use maxminddb::geoip2;
|
||||
use session::{Location, Session};
|
||||
@@ -105,11 +105,12 @@ impl ClientManager {
|
||||
}
|
||||
}
|
||||
|
||||
pub async fn add_listener<L: TunnelListener + 'static>(
|
||||
pub async fn add_listener<L: SocketListener<Accepted = Box<dyn Tunnel>> + 'static>(
|
||||
&mut self,
|
||||
mut listener: L,
|
||||
) -> Result<(), anyhow::Error> {
|
||||
) -> Result<url::Url, anyhow::Error> {
|
||||
listener.listen().await?;
|
||||
let local_url = listener.local_url();
|
||||
self.listeners_cnt.fetch_add(1, Ordering::Relaxed);
|
||||
let sessions = self.client_sessions.clone();
|
||||
let storage = self.storage.weak_ref();
|
||||
@@ -120,7 +121,11 @@ impl ClientManager {
|
||||
let webhook_config = self.webhook_config.clone();
|
||||
self.tasks.spawn(async move {
|
||||
while let Ok(tunnel) = listener.accept().await {
|
||||
let (tunnel, secure) = match security::accept_or_upgrade_server_tunnel(tunnel).await {
|
||||
let (tunnel, secure) = match web_security::accept_or_upgrade_server_tunnel(
|
||||
tunnel,
|
||||
)
|
||||
.await
|
||||
{
|
||||
Ok(v) => v,
|
||||
Err(error) => {
|
||||
tracing::warn!(%error, "failed to accept secure tunnel, dropping connection");
|
||||
@@ -150,7 +155,7 @@ impl ClientManager {
|
||||
listeners_cnt.fetch_sub(1, Ordering::Relaxed);
|
||||
});
|
||||
|
||||
Ok(())
|
||||
Ok(local_url)
|
||||
}
|
||||
|
||||
pub fn is_running(&self) -> bool {
|
||||
@@ -369,6 +374,7 @@ impl
|
||||
mod tests {
|
||||
use std::{
|
||||
collections::VecDeque,
|
||||
future::Future,
|
||||
sync::{
|
||||
Arc,
|
||||
atomic::{AtomicBool, AtomicUsize, Ordering},
|
||||
@@ -378,22 +384,18 @@ mod tests {
|
||||
|
||||
use axum::{Json, Router, extract::State, routing::post};
|
||||
use easytier::{
|
||||
common::MachineIdOptions,
|
||||
instance_manager::NetworkInstanceManager,
|
||||
common::{MachineIdOptions, config::NetworkConfigExt},
|
||||
instance::factory::{NativeInstanceManager, native_instance_manager},
|
||||
proto::{
|
||||
api::manage::{NetworkConfig, NetworkingMethod, PortForwardConfig},
|
||||
common::CompressionAlgoPb,
|
||||
},
|
||||
rpc_service::remote_client::Storage as RemoteStorage,
|
||||
tunnel::{
|
||||
common::tests::wait_for_condition,
|
||||
udp::{UdpTunnelConnector, UdpTunnelListener},
|
||||
rpc::standalone::{runtime_udp_tunnel_dialer, runtime_udp_tunnel_listener},
|
||||
},
|
||||
web_client::{WebClient, run_web_client},
|
||||
};
|
||||
use easytier_core::management::remote_client::Storage as RemoteStorage;
|
||||
use serde_json::json;
|
||||
use sqlx::Executor;
|
||||
use tokio::net::UdpSocket;
|
||||
|
||||
use crate::{
|
||||
FeatureFlags, client_manager::ClientManager, db::Db, webhook::ManagedNetworkConfig,
|
||||
@@ -401,6 +403,21 @@ mod tests {
|
||||
|
||||
const MANAGED_CONFIG_TOKEN: &str = "managed-config-token";
|
||||
|
||||
async fn wait_for_condition<F, Fut>(mut condition: F, timeout: Duration)
|
||||
where
|
||||
F: FnMut() -> Fut,
|
||||
Fut: Future<Output = bool>,
|
||||
{
|
||||
let deadline = tokio::time::Instant::now() + timeout;
|
||||
while !condition().await {
|
||||
assert!(
|
||||
tokio::time::Instant::now() < deadline,
|
||||
"condition timed out"
|
||||
);
|
||||
tokio::time::sleep(Duration::from_millis(50)).await;
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
struct TestWebhookState {
|
||||
validate_responses: Arc<tokio::sync::Mutex<VecDeque<bool>>>,
|
||||
@@ -510,12 +527,15 @@ mod tests {
|
||||
}
|
||||
|
||||
async fn add_random_udp_listener(mgr: &mut ClientManager) -> std::net::SocketAddr {
|
||||
let socket = Arc::new(UdpSocket::bind("127.0.0.1:0").await.unwrap());
|
||||
let addr = socket.local_addr().unwrap();
|
||||
let listener =
|
||||
UdpTunnelListener::new_with_socket(format!("udp://{addr}").parse().unwrap(), socket);
|
||||
mgr.add_listener(listener).await.unwrap();
|
||||
addr
|
||||
let local_url = "udp://127.0.0.1:0".parse().unwrap();
|
||||
let listener = runtime_udp_tunnel_listener(local_url, "127.0.0.1:0".parse().unwrap());
|
||||
let local_url = mgr.add_listener(listener).await.unwrap();
|
||||
local_url
|
||||
.socket_addrs(|| None)
|
||||
.unwrap()
|
||||
.into_iter()
|
||||
.next()
|
||||
.unwrap()
|
||||
}
|
||||
|
||||
async fn wait_for_validated_user(mgr: &ClientManager, machine_id: uuid::Uuid) -> i32 {
|
||||
@@ -575,14 +595,14 @@ mod tests {
|
||||
}
|
||||
|
||||
async fn wait_for_runtime_config(
|
||||
manager: &NetworkInstanceManager,
|
||||
manager: &NativeInstanceManager,
|
||||
inst_id: uuid::Uuid,
|
||||
predicate: impl Fn(&NetworkConfig) -> bool,
|
||||
) -> NetworkConfig {
|
||||
tokio::time::timeout(Duration::from_secs(12), async {
|
||||
loop {
|
||||
if let Some(config) = manager
|
||||
.get_instance_config(&inst_id)
|
||||
.config(inst_id)
|
||||
.and_then(|config| NetworkConfig::new_from_config(&config).ok())
|
||||
.filter(|config| predicate(config))
|
||||
{
|
||||
@@ -598,7 +618,7 @@ mod tests {
|
||||
async fn start_web_client_for_test(
|
||||
config_server_addr: std::net::SocketAddr,
|
||||
machine_id: uuid::Uuid,
|
||||
manager: Arc<NetworkInstanceManager>,
|
||||
manager: Arc<NativeInstanceManager>,
|
||||
) -> WebClient {
|
||||
run_web_client(
|
||||
&format!("udp://{config_server_addr}/{MANAGED_CONFIG_TOKEN}"),
|
||||
@@ -813,7 +833,10 @@ mod tests {
|
||||
|
||||
#[tokio::test]
|
||||
async fn test_client() {
|
||||
let listener = UdpTunnelListener::new("udp://0.0.0.0:54333".parse().unwrap());
|
||||
let listener = runtime_udp_tunnel_listener(
|
||||
"udp://127.0.0.1:0".parse().unwrap(),
|
||||
"127.0.0.1:0".parse().unwrap(),
|
||||
);
|
||||
let mut mgr = ClientManager::new(
|
||||
Db::memory_db().await,
|
||||
None,
|
||||
@@ -823,7 +846,7 @@ mod tests {
|
||||
None, None, None, None, None,
|
||||
)),
|
||||
);
|
||||
mgr.add_listener(Box::new(listener)).await.unwrap();
|
||||
let listener_url = mgr.add_listener(listener).await.unwrap();
|
||||
|
||||
mgr.db()
|
||||
.inner()
|
||||
@@ -831,14 +854,14 @@ mod tests {
|
||||
.await
|
||||
.unwrap();
|
||||
|
||||
let connector = UdpTunnelConnector::new("udp://127.0.0.1:54333".parse().unwrap());
|
||||
let connector = runtime_udp_tunnel_dialer(listener_url);
|
||||
let _c = WebClient::new(
|
||||
connector,
|
||||
"test",
|
||||
uuid::Uuid::new_v4(),
|
||||
"test",
|
||||
false,
|
||||
Arc::new(NetworkInstanceManager::new()),
|
||||
Arc::new(native_instance_manager()),
|
||||
None,
|
||||
);
|
||||
|
||||
@@ -892,7 +915,7 @@ mod tests {
|
||||
|
||||
let machine_id = uuid::Uuid::new_v4();
|
||||
let instance_id = uuid::Uuid::new_v4();
|
||||
let core_manager = Arc::new(NetworkInstanceManager::new());
|
||||
let core_manager = Arc::new(native_instance_manager());
|
||||
let client =
|
||||
start_web_client_for_test(config_server_addr, machine_id, core_manager.clone()).await;
|
||||
|
||||
@@ -939,7 +962,7 @@ mod tests {
|
||||
assert_updated_runtime_config(&updated, instance_id);
|
||||
|
||||
assert_eq!(
|
||||
core_manager.get_instance_network_config_source(&instance_id),
|
||||
core_manager.config_source(instance_id),
|
||||
Some(easytier::common::config::ConfigSource::Web)
|
||||
);
|
||||
assert_eq!(
|
||||
@@ -1003,7 +1026,7 @@ mod tests {
|
||||
assert_eq!(redelivered.enable_kcp_proxy, Some(true));
|
||||
assert_eq!(redelivered.instance_recv_bps_limit, Some(654321));
|
||||
assert_eq!(
|
||||
core_manager.get_instance_network_config_source(&instance_id),
|
||||
core_manager.config_source(instance_id),
|
||||
Some(easytier::common::config::ConfigSource::Web)
|
||||
);
|
||||
assert_eq!(
|
||||
@@ -1018,7 +1041,7 @@ mod tests {
|
||||
// Reconnect path: a fresh core manager has no local runtime state, so
|
||||
// the new session must replay the managed config persisted in web DB.
|
||||
drop(client);
|
||||
let reconnected_core_manager = Arc::new(NetworkInstanceManager::new());
|
||||
let reconnected_core_manager = Arc::new(native_instance_manager());
|
||||
let _reconnected_client = start_web_client_for_test(
|
||||
config_server_addr,
|
||||
machine_id,
|
||||
@@ -1055,7 +1078,7 @@ mod tests {
|
||||
);
|
||||
let config_server_addr = add_random_udp_listener(&mut mgr).await;
|
||||
let machine_id = uuid::Uuid::new_v4();
|
||||
let core_manager = Arc::new(NetworkInstanceManager::new());
|
||||
let core_manager = Arc::new(native_instance_manager());
|
||||
let client =
|
||||
start_web_client_for_test(config_server_addr, machine_id, core_manager.clone()).await;
|
||||
|
||||
|
||||
@@ -1,7 +1,8 @@
|
||||
use anyhow::Context as _;
|
||||
use easytier::{
|
||||
common::config::{
|
||||
ConfigLoader, EncryptionAlgorithm, PortForwardConfig as RuntimePortForwardConfig,
|
||||
ConfigLoader, EncryptionAlgorithm, NetworkConfigExt,
|
||||
PortForwardConfig as RuntimePortForwardConfig,
|
||||
},
|
||||
proto::{
|
||||
acl::Acl,
|
||||
@@ -802,8 +803,7 @@ mod tests {
|
||||
let current = config_with_port_forwards(vec![port_forward(23000, 5174)]);
|
||||
let mut desired =
|
||||
config_with_port_forwards(vec![port_forward(23000, 5174), port_forward(23007, 3389)]);
|
||||
desired.hostname =
|
||||
Some(easytier::common::config::TomlConfigLoader::default().get_hostname());
|
||||
desired.hostname = Some("desired-host".to_string());
|
||||
|
||||
let patch = web_source_runtime_patch(¤t, &desired).expect("build patch");
|
||||
|
||||
|
||||
@@ -6,18 +6,16 @@ use std::{
|
||||
};
|
||||
|
||||
use anyhow::Context;
|
||||
use easytier::{
|
||||
proto::{
|
||||
api::{
|
||||
config::{ConfigRpc, ConfigRpcClientFactory},
|
||||
manage::{WebClientService, WebClientServiceClientFactory},
|
||||
},
|
||||
rpc_impl::bidirect::BidirectRpcManager,
|
||||
rpc_types::{self, controller::BaseController},
|
||||
web::{HeartbeatRequest, HeartbeatResponse, WebServerService, WebServerServiceServer},
|
||||
use easytier::proto::{
|
||||
api::{
|
||||
config::{ConfigRpc, ConfigRpcClientFactory},
|
||||
manage::{WebClientService, WebClientServiceClientFactory},
|
||||
},
|
||||
tunnel::Tunnel,
|
||||
rpc::bidirect::BidirectRpcManager,
|
||||
rpc_types::{self, controller::BaseController},
|
||||
web::{HeartbeatRequest, HeartbeatResponse, WebServerService, WebServerServiceServer},
|
||||
};
|
||||
use easytier_core::tunnel::Tunnel;
|
||||
use tokio::sync::{Notify, RwLock, broadcast};
|
||||
use tokio_util::task::AbortOnDropHandle;
|
||||
|
||||
@@ -565,7 +563,7 @@ impl WebServerService for SessionRpcService {
|
||||
_: easytier::proto::web::GetFeatureRequest,
|
||||
) -> rpc_types::error::Result<easytier::proto::web::GetFeatureResponse> {
|
||||
Ok(easytier::proto::web::GetFeatureResponse {
|
||||
support_encryption: easytier::web_client::security::web_secure_tunnel_supported(),
|
||||
support_encryption: easytier_core::tunnel::web_security::web_secure_tunnel_supported(),
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,16 +1,14 @@
|
||||
use std::collections::{HashMap, HashSet};
|
||||
|
||||
use easytier::{
|
||||
proto::{
|
||||
api::manage::{
|
||||
DeleteNetworkInstanceRequest, ListNetworkInstanceMetaRequest,
|
||||
ListNetworkInstanceRequest, NetworkConfig, NetworkMeta, RunNetworkInstanceRequest,
|
||||
},
|
||||
rpc_types::controller::BaseController,
|
||||
web::HeartbeatRequest,
|
||||
use easytier::proto::{
|
||||
api::manage::{
|
||||
DeleteNetworkInstanceRequest, ListNetworkInstanceMetaRequest, ListNetworkInstanceRequest,
|
||||
NetworkConfig, NetworkMeta, RunNetworkInstanceRequest,
|
||||
},
|
||||
rpc_service::remote_client::{ListNetworkProps, Storage as _},
|
||||
rpc_types::controller::BaseController,
|
||||
web::HeartbeatRequest,
|
||||
};
|
||||
use easytier_core::management::remote_client::{ListNetworkProps, Storage as _};
|
||||
use tokio::sync::{RwLock, broadcast};
|
||||
|
||||
use super::{SessionConfigClient, SessionData, SessionRpcClient, SessionRpcService};
|
||||
|
||||
@@ -1,9 +1,7 @@
|
||||
//! `SeaORM` Entity, @generated by sea-orm-codegen 1.1.0
|
||||
|
||||
use easytier::{
|
||||
common::config::ConfigSource, launcher::NetworkConfig,
|
||||
rpc_service::remote_client::PersistentConfig,
|
||||
};
|
||||
use easytier::common::config::{ConfigSource, NetworkConfig};
|
||||
use easytier_core::management::remote_client::PersistentConfig;
|
||||
use sea_orm::entity::prelude::*;
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
|
||||
@@ -2,11 +2,8 @@
|
||||
#[allow(unused_imports)]
|
||||
pub mod entity;
|
||||
|
||||
use easytier::{
|
||||
common::config::ConfigSource,
|
||||
launcher::NetworkConfig,
|
||||
rpc_service::remote_client::{ListNetworkProps, Storage},
|
||||
};
|
||||
use easytier::common::config::{ConfigSource, NetworkConfig};
|
||||
use easytier_core::management::remote_client::{ListNetworkProps, Storage};
|
||||
use entity::user_running_network_configs;
|
||||
use sea_orm::{
|
||||
ColumnTrait as _, DatabaseConnection, DbErr, EntityTrait, QueryFilter as _, Set,
|
||||
@@ -385,11 +382,8 @@ impl Storage<(UserIdInDb, Uuid), user_running_network_configs::Model, DbErr> for
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use easytier::{
|
||||
common::config::ConfigSource,
|
||||
proto::api::manage::NetworkConfig,
|
||||
rpc_service::remote_client::{PersistentConfig, Storage},
|
||||
};
|
||||
use easytier::{common::config::ConfigSource, proto::api::manage::NetworkConfig};
|
||||
use easytier_core::management::remote_client::{PersistentConfig, Storage};
|
||||
use sea_orm::{ActiveModelTrait, ColumnTrait, EntityTrait, QueryFilter as _, Set};
|
||||
|
||||
use crate::db::{Db, ListNetworkProps, entity::user_running_network_configs};
|
||||
|
||||
@@ -16,12 +16,12 @@ use easytier::{
|
||||
log,
|
||||
network::{local_ipv4, local_ipv6},
|
||||
},
|
||||
tunnel::{TunnelListener, tcp::TcpTunnelListener, udp::UdpTunnelListener},
|
||||
proto::rpc::standalone::{runtime_rpc_listener, runtime_udp_tunnel_listener},
|
||||
utils::panic::setup_panic_handler,
|
||||
};
|
||||
use easytier_core::{socket::SocketListener, tunnel::Tunnel};
|
||||
|
||||
use easytier::tunnel::IpScheme;
|
||||
use easytier::utils::BoxExt;
|
||||
use mimalloc::MiMalloc;
|
||||
|
||||
mod client_manager;
|
||||
@@ -230,11 +230,20 @@ impl LoggingConfigLoader for &Cli {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn get_listener_by_url(scheme: IpScheme, l: &url::Url) -> Option<Box<dyn TunnelListener>> {
|
||||
pub fn get_listener_by_url(
|
||||
scheme: IpScheme,
|
||||
l: &url::Url,
|
||||
) -> Option<Box<dyn SocketListener<Accepted = Box<dyn Tunnel>>>> {
|
||||
Some(match scheme {
|
||||
IpScheme::Tcp => TcpTunnelListener::new(l.clone()).boxed(),
|
||||
IpScheme::Udp => UdpTunnelListener::new(l.clone()).boxed(),
|
||||
IpScheme::Ws => WsTunnelListener::new(l.clone()).boxed(),
|
||||
IpScheme::Tcp => {
|
||||
let addr = l.socket_addrs(|| Some(11010)).ok()?.into_iter().next()?;
|
||||
Box::new(runtime_rpc_listener(addr))
|
||||
}
|
||||
IpScheme::Udp => {
|
||||
let addr = l.socket_addrs(|| Some(11010)).ok()?.into_iter().next()?;
|
||||
Box::new(runtime_udp_tunnel_listener(l.clone(), addr))
|
||||
}
|
||||
IpScheme::Ws => Box::new(WsTunnelListener::new(l.clone())),
|
||||
_ => return None,
|
||||
})
|
||||
}
|
||||
@@ -244,8 +253,8 @@ async fn get_dual_stack_listener(
|
||||
port: u16,
|
||||
) -> Result<
|
||||
(
|
||||
Option<Box<dyn TunnelListener>>,
|
||||
Option<Box<dyn TunnelListener>>,
|
||||
Option<Box<dyn SocketListener<Accepted = Box<dyn Tunnel>>>>,
|
||||
Option<Box<dyn SocketListener<Accepted = Box<dyn Tunnel>>>>,
|
||||
),
|
||||
Error,
|
||||
> {
|
||||
|
||||
@@ -16,8 +16,7 @@ use axum::{Extension, Json, Router, extract::State, routing::get};
|
||||
use axum_login::tower_sessions::{ExpiredDeletion, SessionManagerLayer};
|
||||
use axum_login::{AuthManagerLayerBuilder, AuthUser, login_required};
|
||||
use axum_messages::MessagesManagerLayer;
|
||||
use easytier::common::config::{ConfigLoader, TomlConfigLoader};
|
||||
use easytier::launcher::NetworkConfig;
|
||||
use easytier::common::config::{ConfigLoader, NetworkConfig, NetworkConfigExt, TomlConfigLoader};
|
||||
use easytier::proto::rpc_types;
|
||||
use network::NetworkApi;
|
||||
use sea_orm::DbErr;
|
||||
|
||||
@@ -3,11 +3,12 @@ use axum::http::StatusCode;
|
||||
use axum::routing::{delete, post};
|
||||
use axum::{Json, Router, extract::State, routing::get};
|
||||
use axum_login::AuthUser;
|
||||
use easytier::common::config::ConfigSource as RuntimeConfigSource;
|
||||
use easytier::launcher::NetworkConfig;
|
||||
use easytier::common::config::{
|
||||
ConfigSource as RuntimeConfigSource, NetworkConfig, config_source_from_rpc,
|
||||
};
|
||||
use easytier::proto::common::Void;
|
||||
use easytier::proto::{api::manage::*, web::*};
|
||||
use easytier::rpc_service::remote_client::{
|
||||
use easytier_core::management::remote_client::{
|
||||
GetNetworkMetasResponse, ListNetworkInstanceIdsJsonResp, RemoteClientError, RemoteClientManager,
|
||||
};
|
||||
use sea_orm::DbErr;
|
||||
@@ -321,7 +322,7 @@ impl NetworkApi {
|
||||
) -> Result<Json<Void>, HttpHandleError> {
|
||||
let source = payload
|
||||
.source
|
||||
.and_then(RuntimeConfigSource::from_rpc)
|
||||
.and_then(config_source_from_rpc)
|
||||
.unwrap_or(RuntimeConfigSource::Web);
|
||||
client_mgr
|
||||
.handle_run_network_instance_with_source(
|
||||
|
||||
Reference in New Issue
Block a user