mirror of
https://github.com/EasyTier/EasyTier.git
synced 2026-05-06 17:59:11 +00:00
refactor(web): Refactor web logic to extract reusable remote client management module (#1465)
This commit is contained in:
@@ -7,13 +7,19 @@ use std::sync::{
|
||||
};
|
||||
|
||||
use dashmap::DashMap;
|
||||
use easytier::{proto::web::HeartbeatRequest, tunnel::TunnelListener};
|
||||
use easytier::{
|
||||
proto::{
|
||||
api::manage::WebClientService, rpc_types::controller::BaseController, web::HeartbeatRequest,
|
||||
},
|
||||
rpc_service::remote_client::{self, RemoteClientManager},
|
||||
tunnel::TunnelListener,
|
||||
};
|
||||
use maxminddb::geoip2;
|
||||
use session::{Location, Session};
|
||||
use storage::{Storage, StorageToken};
|
||||
use tokio::task::JoinSet;
|
||||
|
||||
use crate::db::{Db, UserIdInDb};
|
||||
use crate::db::{entity::user_running_network_configs, Db, UserIdInDb};
|
||||
|
||||
#[derive(rust_embed::Embed)]
|
||||
#[folder = "resources/"]
|
||||
@@ -152,7 +158,7 @@ impl ClientManager {
|
||||
s.data().read().await.location().cloned()
|
||||
}
|
||||
|
||||
pub fn db(&self) -> &Db {
|
||||
fn db(&self) -> &Db {
|
||||
self.storage.db()
|
||||
}
|
||||
|
||||
@@ -245,6 +251,32 @@ impl ClientManager {
|
||||
}
|
||||
}
|
||||
|
||||
impl
|
||||
RemoteClientManager<
|
||||
(UserIdInDb, uuid::Uuid),
|
||||
user_running_network_configs::Model,
|
||||
sea_orm::DbErr,
|
||||
> for ClientManager
|
||||
{
|
||||
fn get_rpc_client(
|
||||
&self,
|
||||
(user_id, machine_id): (UserIdInDb, uuid::Uuid),
|
||||
) -> Option<Box<dyn WebClientService<Controller = BaseController> + Send>> {
|
||||
let s = self.get_session_by_machine_id(user_id, &machine_id)?;
|
||||
Some(s.scoped_rpc_client())
|
||||
}
|
||||
|
||||
fn get_storage(
|
||||
&self,
|
||||
) -> &impl remote_client::Storage<
|
||||
(UserIdInDb, uuid::Uuid),
|
||||
user_running_network_configs::Model,
|
||||
sea_orm::DbErr,
|
||||
> {
|
||||
self.storage.db()
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use std::{sync::Arc, time::Duration};
|
||||
|
||||
@@ -12,12 +12,11 @@ use easytier::{
|
||||
rpc_types::{self, controller::BaseController},
|
||||
web::{HeartbeatRequest, HeartbeatResponse, WebServerService, WebServerServiceServer},
|
||||
},
|
||||
rpc_service::remote_client::{ListNetworkProps, Storage as _},
|
||||
tunnel::Tunnel,
|
||||
};
|
||||
use tokio::sync::{broadcast, RwLock};
|
||||
|
||||
use crate::db::ListNetworkProps;
|
||||
|
||||
use super::storage::{Storage, StorageToken, WeakRefStorage};
|
||||
|
||||
#[derive(Debug, Clone, serde::Serialize, serde::Deserialize)]
|
||||
@@ -224,10 +223,10 @@ impl Session {
|
||||
}
|
||||
|
||||
let req = req.unwrap();
|
||||
if req.machine_id.is_none() {
|
||||
let Some(machine_id) = req.machine_id else {
|
||||
tracing::warn!(?req, "Machine id is not set, ignore");
|
||||
continue;
|
||||
}
|
||||
};
|
||||
|
||||
let running_inst_ids = req
|
||||
.running_network_instances
|
||||
@@ -257,11 +256,7 @@ impl Session {
|
||||
|
||||
let local_configs = match storage
|
||||
.db
|
||||
.list_network_configs(
|
||||
user_id,
|
||||
Some(req.machine_id.unwrap().into()),
|
||||
ListNetworkProps::EnabledOnly,
|
||||
)
|
||||
.list_network_configs((user_id, machine_id.into()), ListNetworkProps::EnabledOnly)
|
||||
.await
|
||||
{
|
||||
Ok(configs) => configs,
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
//! `SeaORM` Entity, @generated by sea-orm-codegen 1.1.0
|
||||
|
||||
use easytier::rpc_service::remote_client::PersistentConfig;
|
||||
use sea_orm::entity::prelude::*;
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
@@ -39,3 +40,12 @@ impl Related<super::users::Entity> for Entity {
|
||||
}
|
||||
|
||||
impl ActiveModelBehavior for ActiveModel {}
|
||||
|
||||
impl PersistentConfig for Model {
|
||||
fn get_network_inst_id(&self) -> &str {
|
||||
&self.network_instance_id
|
||||
}
|
||||
fn get_network_config(&self) -> &str {
|
||||
&self.network_config
|
||||
}
|
||||
}
|
||||
|
||||
+52
-52
@@ -2,6 +2,7 @@
|
||||
#[allow(unused_imports)]
|
||||
pub mod entity;
|
||||
|
||||
use easytier::rpc_service::remote_client::{ListNetworkProps, Storage};
|
||||
use entity::user_running_network_configs;
|
||||
use sea_orm::{
|
||||
prelude::Expr, sea_query::OnConflict, ColumnTrait as _, DatabaseConnection, DbErr, EntityTrait,
|
||||
@@ -9,17 +10,13 @@ use sea_orm::{
|
||||
};
|
||||
use sea_orm_migration::MigratorTrait as _;
|
||||
use sqlx::{migrate::MigrateDatabase as _, types::chrono, Sqlite, SqlitePool};
|
||||
use uuid::Uuid;
|
||||
|
||||
use crate::migrator;
|
||||
use async_trait::async_trait;
|
||||
|
||||
pub type UserIdInDb = i32;
|
||||
|
||||
pub enum ListNetworkProps {
|
||||
All,
|
||||
EnabledOnly,
|
||||
DisabledOnly,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct Db {
|
||||
db_path: String,
|
||||
@@ -68,12 +65,36 @@ impl Db {
|
||||
&self.orm_db
|
||||
}
|
||||
|
||||
pub async fn insert_or_update_user_network_config<T: ToString>(
|
||||
pub async fn get_user_id<T: ToString>(
|
||||
&self,
|
||||
user_id: UserIdInDb,
|
||||
device_id: uuid::Uuid,
|
||||
network_inst_id: uuid::Uuid,
|
||||
network_config: T,
|
||||
user_name: T,
|
||||
) -> Result<Option<UserIdInDb>, DbErr> {
|
||||
use entity::users as u;
|
||||
|
||||
let user = u::Entity::find()
|
||||
.filter(u::Column::Username.eq(user_name.to_string()))
|
||||
.one(self.orm_db())
|
||||
.await?;
|
||||
|
||||
Ok(user.map(|u| u.id))
|
||||
}
|
||||
|
||||
// TODO: currently we don't have a token system, so we just use the user name as token
|
||||
pub async fn get_user_id_by_token<T: ToString>(
|
||||
&self,
|
||||
token: T,
|
||||
) -> Result<Option<UserIdInDb>, DbErr> {
|
||||
self.get_user_id(token).await
|
||||
}
|
||||
}
|
||||
|
||||
#[async_trait]
|
||||
impl Storage<(UserIdInDb, Uuid), user_running_network_configs::Model, DbErr> for Db {
|
||||
async fn insert_or_update_user_network_config(
|
||||
&self,
|
||||
(user_id, device_id): (UserIdInDb, Uuid),
|
||||
network_inst_id: Uuid,
|
||||
network_config: impl ToString + Send,
|
||||
) -> Result<(), DbErr> {
|
||||
let txn = self.orm_db().begin().await?;
|
||||
|
||||
@@ -105,10 +126,10 @@ impl Db {
|
||||
txn.commit().await
|
||||
}
|
||||
|
||||
pub async fn delete_network_config(
|
||||
async fn delete_network_config(
|
||||
&self,
|
||||
user_id: UserIdInDb,
|
||||
network_inst_id: uuid::Uuid,
|
||||
(user_id, _): (UserIdInDb, Uuid),
|
||||
network_inst_id: Uuid,
|
||||
) -> Result<(), DbErr> {
|
||||
use entity::user_running_network_configs as urnc;
|
||||
|
||||
@@ -121,12 +142,12 @@ impl Db {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub async fn update_network_config_state(
|
||||
async fn update_network_config_state(
|
||||
&self,
|
||||
user_id: UserIdInDb,
|
||||
network_inst_id: uuid::Uuid,
|
||||
(user_id, _): (UserIdInDb, Uuid),
|
||||
network_inst_id: Uuid,
|
||||
disabled: bool,
|
||||
) -> Result<entity::user_running_network_configs::Model, DbErr> {
|
||||
) -> Result<user_running_network_configs::Model, DbErr> {
|
||||
use entity::user_running_network_configs as urnc;
|
||||
|
||||
urnc::Entity::update_many()
|
||||
@@ -151,10 +172,9 @@ impl Db {
|
||||
)))
|
||||
}
|
||||
|
||||
pub async fn list_network_configs(
|
||||
async fn list_network_configs(
|
||||
&self,
|
||||
user_id: UserIdInDb,
|
||||
device_id: Option<uuid::Uuid>,
|
||||
(user_id, device_id): (UserIdInDb, Uuid),
|
||||
props: ListNetworkProps,
|
||||
) -> Result<Vec<user_running_network_configs::Model>, DbErr> {
|
||||
use entity::user_running_network_configs as urnc;
|
||||
@@ -169,7 +189,7 @@ impl Db {
|
||||
} else {
|
||||
configs
|
||||
};
|
||||
let configs = if let Some(device_id) = device_id {
|
||||
let configs = if !device_id.is_nil() {
|
||||
configs.filter(urnc::Column::DeviceId.eq(device_id.to_string()))
|
||||
} else {
|
||||
configs
|
||||
@@ -180,11 +200,10 @@ impl Db {
|
||||
Ok(configs)
|
||||
}
|
||||
|
||||
pub async fn get_network_config(
|
||||
async fn get_network_config(
|
||||
&self,
|
||||
user_id: UserIdInDb,
|
||||
device_id: &uuid::Uuid,
|
||||
network_inst_id: &String,
|
||||
(user_id, device_id): (UserIdInDb, Uuid),
|
||||
network_inst_id: &str,
|
||||
) -> Result<Option<user_running_network_configs::Model>, DbErr> {
|
||||
use entity::user_running_network_configs as urnc;
|
||||
|
||||
@@ -197,32 +216,11 @@ impl Db {
|
||||
|
||||
Ok(config)
|
||||
}
|
||||
|
||||
pub async fn get_user_id<T: ToString>(
|
||||
&self,
|
||||
user_name: T,
|
||||
) -> Result<Option<UserIdInDb>, DbErr> {
|
||||
use entity::users as u;
|
||||
|
||||
let user = u::Entity::find()
|
||||
.filter(u::Column::Username.eq(user_name.to_string()))
|
||||
.one(self.orm_db())
|
||||
.await?;
|
||||
|
||||
Ok(user.map(|u| u.id))
|
||||
}
|
||||
|
||||
// TODO: currently we don't have a token system, so we just use the user name as token
|
||||
pub async fn get_user_id_by_token<T: ToString>(
|
||||
&self,
|
||||
token: T,
|
||||
) -> Result<Option<UserIdInDb>, DbErr> {
|
||||
self.get_user_id(token).await
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use easytier::rpc_service::remote_client::Storage;
|
||||
use sea_orm::{ColumnTrait, EntityTrait, QueryFilter as _};
|
||||
|
||||
use crate::db::{entity::user_running_network_configs, Db, ListNetworkProps};
|
||||
@@ -235,7 +233,7 @@ mod tests {
|
||||
let inst_id = uuid::Uuid::new_v4();
|
||||
let device_id = uuid::Uuid::new_v4();
|
||||
|
||||
db.insert_or_update_user_network_config(user_id, device_id, inst_id, network_config)
|
||||
db.insert_or_update_user_network_config((user_id, device_id), inst_id, network_config)
|
||||
.await
|
||||
.unwrap();
|
||||
|
||||
@@ -250,7 +248,7 @@ mod tests {
|
||||
|
||||
// overwrite the config
|
||||
let network_config = "test_config2";
|
||||
db.insert_or_update_user_network_config(user_id, device_id, inst_id, network_config)
|
||||
db.insert_or_update_user_network_config((user_id, device_id), inst_id, network_config)
|
||||
.await
|
||||
.unwrap();
|
||||
|
||||
@@ -267,14 +265,16 @@ mod tests {
|
||||
assert_ne!(result.update_time, result2.update_time);
|
||||
|
||||
assert_eq!(
|
||||
db.list_network_configs(user_id, Some(device_id), ListNetworkProps::All)
|
||||
db.list_network_configs((user_id, device_id), ListNetworkProps::All)
|
||||
.await
|
||||
.unwrap()
|
||||
.len(),
|
||||
1
|
||||
);
|
||||
|
||||
db.delete_network_config(user_id, inst_id).await.unwrap();
|
||||
db.delete_network_config((user_id, device_id), inst_id)
|
||||
.await
|
||||
.unwrap();
|
||||
let result3 = user_running_network_configs::Entity::find()
|
||||
.filter(user_running_network_configs::Column::UserId.eq(user_id))
|
||||
.one(db.orm_db())
|
||||
|
||||
@@ -41,8 +41,7 @@ pub struct RestfulServer {
|
||||
|
||||
// serve_task: Option<ScopedTask<()>>,
|
||||
// delete_task: Option<ScopedTask<tower_sessions::session_store::Result<()>>>,
|
||||
network_api: NetworkApi,
|
||||
|
||||
// network_api: NetworkApi<WebClientManager>,
|
||||
web_router: Option<Router>,
|
||||
}
|
||||
|
||||
@@ -108,7 +107,7 @@ impl RestfulServer {
|
||||
) -> anyhow::Result<Self> {
|
||||
assert!(client_mgr.is_running());
|
||||
|
||||
let network_api = NetworkApi::new();
|
||||
// let network_api = NetworkApi::new();
|
||||
|
||||
Ok(RestfulServer {
|
||||
bind_addr,
|
||||
@@ -116,7 +115,7 @@ impl RestfulServer {
|
||||
db,
|
||||
// serve_task: None,
|
||||
// delete_task: None,
|
||||
network_api,
|
||||
// network_api,
|
||||
web_router,
|
||||
})
|
||||
}
|
||||
@@ -188,6 +187,7 @@ impl RestfulServer {
|
||||
}
|
||||
}
|
||||
|
||||
#[allow(unused_mut)]
|
||||
pub async fn start(
|
||||
mut self,
|
||||
) -> Result<
|
||||
@@ -238,7 +238,7 @@ impl RestfulServer {
|
||||
let app = Router::new()
|
||||
.route("/api/v1/summary", get(Self::handle_get_summary))
|
||||
.route("/api/v1/sessions", get(Self::handle_list_all_sessions))
|
||||
.merge(self.network_api.build_route())
|
||||
.merge(NetworkApi::build_route())
|
||||
.route_layer(login_required!(Backend))
|
||||
.merge(auth::router())
|
||||
.with_state(self.client_mgr.clone())
|
||||
|
||||
@@ -1,5 +1,3 @@
|
||||
use std::sync::Arc;
|
||||
|
||||
use axum::extract::Path;
|
||||
use axum::http::StatusCode;
|
||||
use axum::routing::{delete, post};
|
||||
@@ -7,12 +5,14 @@ use axum::{extract::State, routing::get, Json, Router};
|
||||
use axum_login::AuthUser;
|
||||
use easytier::launcher::NetworkConfig;
|
||||
use easytier::proto::common::Void;
|
||||
use easytier::proto::rpc_types::controller::BaseController;
|
||||
use easytier::proto::{self, api::manage::*, web::*};
|
||||
use easytier::proto::{api::manage::*, web::*};
|
||||
use easytier::rpc_service::remote_client::{
|
||||
ListNetworkInstanceIdsJsonResp, RemoteClientError, RemoteClientManager,
|
||||
};
|
||||
use sea_orm::DbErr;
|
||||
|
||||
use crate::client_manager::session::{Location, Session};
|
||||
use crate::client_manager::ClientManager;
|
||||
use crate::db::{ListNetworkProps, UserIdInDb};
|
||||
use crate::client_manager::session::Location;
|
||||
use crate::db::UserIdInDb;
|
||||
|
||||
use super::users::AuthSession;
|
||||
use super::{
|
||||
@@ -31,6 +31,21 @@ fn convert_rpc_error(e: RpcError) -> (StatusCode, Json<Error>) {
|
||||
(status_code, Json(error))
|
||||
}
|
||||
|
||||
fn convert_error(e: RemoteClientError<DbErr>) -> (StatusCode, Json<Error>) {
|
||||
match e {
|
||||
RemoteClientError::PersistentError(e) => convert_db_error(e),
|
||||
RemoteClientError::RpcError(e) => convert_rpc_error(e),
|
||||
RemoteClientError::ClientNotFound => (
|
||||
StatusCode::NOT_FOUND,
|
||||
other_error("Client not found").into(),
|
||||
),
|
||||
RemoteClientError::NotFound(msg) => (StatusCode::NOT_FOUND, other_error(msg).into()),
|
||||
RemoteClientError::Other(msg) => {
|
||||
(StatusCode::INTERNAL_SERVER_ERROR, other_error(msg).into())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, serde::Deserialize, serde::Serialize)]
|
||||
struct ValidateConfigJsonReq {
|
||||
config: NetworkConfig,
|
||||
@@ -42,7 +57,7 @@ struct RunNetworkJsonReq {
|
||||
}
|
||||
|
||||
#[derive(Debug, serde::Deserialize, serde::Serialize)]
|
||||
struct ColletNetworkInfoJsonReq {
|
||||
struct CollectNetworkInfoJsonReq {
|
||||
inst_ids: Option<Vec<uuid::Uuid>>,
|
||||
}
|
||||
|
||||
@@ -56,12 +71,6 @@ struct RemoveNetworkJsonReq {
|
||||
inst_ids: Vec<uuid::Uuid>,
|
||||
}
|
||||
|
||||
#[derive(Debug, serde::Deserialize, serde::Serialize)]
|
||||
struct ListNetworkInstanceIdsJsonResp {
|
||||
running_inst_ids: Vec<easytier::proto::common::Uuid>,
|
||||
disabled_inst_ids: Vec<easytier::proto::common::Uuid>,
|
||||
}
|
||||
|
||||
#[derive(Debug, serde::Deserialize, serde::Serialize)]
|
||||
struct ListMachineItem {
|
||||
client_url: Option<url::Url>,
|
||||
@@ -74,13 +83,9 @@ struct ListMachineJsonResp {
|
||||
machines: Vec<ListMachineItem>,
|
||||
}
|
||||
|
||||
pub struct NetworkApi {}
|
||||
pub struct NetworkApi;
|
||||
|
||||
impl NetworkApi {
|
||||
pub fn new() -> Self {
|
||||
Self {}
|
||||
}
|
||||
|
||||
fn get_user_id(auth_session: &AuthSession) -> Result<UserIdInDb, (StatusCode, Json<Error>)> {
|
||||
let Some(user_id) = auth_session.user.as_ref().map(|x| x.id()) else {
|
||||
return Err((
|
||||
@@ -91,63 +96,20 @@ impl NetworkApi {
|
||||
Ok(user_id)
|
||||
}
|
||||
|
||||
async fn get_session_by_machine_id(
|
||||
auth_session: &AuthSession,
|
||||
client_mgr: &ClientManager,
|
||||
machine_id: &uuid::Uuid,
|
||||
) -> Result<Arc<Session>, HttpHandleError> {
|
||||
let user_id = Self::get_user_id(auth_session)?;
|
||||
|
||||
let Some(result) = client_mgr.get_session_by_machine_id(user_id, machine_id) else {
|
||||
return Err((
|
||||
StatusCode::NOT_FOUND,
|
||||
other_error(format!("No such session: {}", machine_id)).into(),
|
||||
));
|
||||
};
|
||||
|
||||
let Some(token) = result.get_token().await else {
|
||||
return Err((
|
||||
StatusCode::UNAUTHORIZED,
|
||||
other_error("No token reported".to_string()).into(),
|
||||
));
|
||||
};
|
||||
|
||||
if !auth_session
|
||||
.user
|
||||
.as_ref()
|
||||
.map(|x| x.tokens.contains(&token.token))
|
||||
.unwrap_or(false)
|
||||
{
|
||||
return Err((
|
||||
StatusCode::FORBIDDEN,
|
||||
other_error("Token mismatch".to_string()).into(),
|
||||
));
|
||||
}
|
||||
|
||||
Ok(result)
|
||||
}
|
||||
|
||||
async fn handle_validate_config(
|
||||
auth_session: AuthSession,
|
||||
State(client_mgr): AppState,
|
||||
Path(machine_id): Path<uuid::Uuid>,
|
||||
Json(payload): Json<ValidateConfigJsonReq>,
|
||||
) -> Result<Json<ValidateConfigResponse>, HttpHandleError> {
|
||||
let config = payload.config;
|
||||
let result =
|
||||
Self::get_session_by_machine_id(&auth_session, &client_mgr, &machine_id).await?;
|
||||
|
||||
let c = result.scoped_rpc_client();
|
||||
let ret = c
|
||||
.validate_config(
|
||||
BaseController::default(),
|
||||
ValidateConfigRequest {
|
||||
config: Some(config),
|
||||
},
|
||||
Ok(client_mgr
|
||||
.handle_validate_config(
|
||||
(Self::get_user_id(&auth_session)?, machine_id),
|
||||
payload.config,
|
||||
)
|
||||
.await
|
||||
.map_err(convert_rpc_error)?;
|
||||
Ok(ret.into())
|
||||
.map_err(convert_error)?
|
||||
.into())
|
||||
}
|
||||
|
||||
async fn handle_run_network_instance(
|
||||
@@ -156,33 +118,13 @@ impl NetworkApi {
|
||||
Path(machine_id): Path<uuid::Uuid>,
|
||||
Json(payload): Json<RunNetworkJsonReq>,
|
||||
) -> Result<Json<Void>, HttpHandleError> {
|
||||
let config = payload.config;
|
||||
let result =
|
||||
Self::get_session_by_machine_id(&auth_session, &client_mgr, &machine_id).await?;
|
||||
|
||||
let c = result.scoped_rpc_client();
|
||||
let resp = c
|
||||
.run_network_instance(
|
||||
BaseController::default(),
|
||||
RunNetworkInstanceRequest {
|
||||
inst_id: None,
|
||||
config: Some(config.clone()),
|
||||
},
|
||||
)
|
||||
.await
|
||||
.map_err(convert_rpc_error)?;
|
||||
|
||||
client_mgr
|
||||
.db()
|
||||
.insert_or_update_user_network_config(
|
||||
auth_session.user.as_ref().unwrap().id(),
|
||||
machine_id,
|
||||
resp.inst_id.unwrap_or_default().into(),
|
||||
serde_json::to_string(&config).unwrap(),
|
||||
.handle_run_network_instance(
|
||||
(Self::get_user_id(&auth_session)?, machine_id),
|
||||
payload.config,
|
||||
)
|
||||
.await
|
||||
.map_err(convert_db_error)?;
|
||||
|
||||
.map_err(convert_error)?;
|
||||
Ok(Void::default().into())
|
||||
}
|
||||
|
||||
@@ -191,47 +133,30 @@ impl NetworkApi {
|
||||
State(client_mgr): AppState,
|
||||
Path((machine_id, inst_id)): Path<(uuid::Uuid, uuid::Uuid)>,
|
||||
) -> Result<Json<CollectNetworkInfoResponse>, HttpHandleError> {
|
||||
let result =
|
||||
Self::get_session_by_machine_id(&auth_session, &client_mgr, &machine_id).await?;
|
||||
|
||||
let c = result.scoped_rpc_client();
|
||||
let ret = c
|
||||
.collect_network_info(
|
||||
BaseController::default(),
|
||||
CollectNetworkInfoRequest {
|
||||
inst_ids: vec![inst_id.into()],
|
||||
},
|
||||
Ok(client_mgr
|
||||
.handle_collect_network_info(
|
||||
(Self::get_user_id(&auth_session)?, machine_id),
|
||||
Some(vec![inst_id]),
|
||||
)
|
||||
.await
|
||||
.map_err(convert_rpc_error)?;
|
||||
Ok(ret.into())
|
||||
.map_err(convert_error)?
|
||||
.into())
|
||||
}
|
||||
|
||||
async fn handle_collect_network_info(
|
||||
auth_session: AuthSession,
|
||||
State(client_mgr): AppState,
|
||||
Path(machine_id): Path<uuid::Uuid>,
|
||||
Json(payload): Json<ColletNetworkInfoJsonReq>,
|
||||
Json(payload): Json<CollectNetworkInfoJsonReq>,
|
||||
) -> Result<Json<CollectNetworkInfoResponse>, HttpHandleError> {
|
||||
let result =
|
||||
Self::get_session_by_machine_id(&auth_session, &client_mgr, &machine_id).await?;
|
||||
|
||||
let c = result.scoped_rpc_client();
|
||||
let ret = c
|
||||
.collect_network_info(
|
||||
BaseController::default(),
|
||||
CollectNetworkInfoRequest {
|
||||
inst_ids: payload
|
||||
.inst_ids
|
||||
.unwrap_or_default()
|
||||
.into_iter()
|
||||
.map(Into::into)
|
||||
.collect(),
|
||||
},
|
||||
Ok(client_mgr
|
||||
.handle_collect_network_info(
|
||||
(Self::get_user_id(&auth_session)?, machine_id),
|
||||
payload.inst_ids,
|
||||
)
|
||||
.await
|
||||
.map_err(convert_rpc_error)?;
|
||||
Ok(ret.into())
|
||||
.map_err(convert_error)?
|
||||
.into())
|
||||
}
|
||||
|
||||
async fn handle_list_network_instance_ids(
|
||||
@@ -239,36 +164,11 @@ impl NetworkApi {
|
||||
State(client_mgr): AppState,
|
||||
Path(machine_id): Path<uuid::Uuid>,
|
||||
) -> Result<Json<ListNetworkInstanceIdsJsonResp>, HttpHandleError> {
|
||||
let result =
|
||||
Self::get_session_by_machine_id(&auth_session, &client_mgr, &machine_id).await?;
|
||||
|
||||
let c = result.scoped_rpc_client();
|
||||
let ret = c
|
||||
.list_network_instance(BaseController::default(), ListNetworkInstanceRequest {})
|
||||
Ok(client_mgr
|
||||
.handle_list_network_instance_ids((Self::get_user_id(&auth_session)?, machine_id))
|
||||
.await
|
||||
.map_err(convert_rpc_error)?;
|
||||
|
||||
let running_inst_ids = ret.inst_ids.clone().into_iter().collect();
|
||||
|
||||
// collect networks that are disabled
|
||||
let disabled_inst_ids = client_mgr
|
||||
.db()
|
||||
.list_network_configs(
|
||||
auth_session.user.unwrap().id(),
|
||||
Some(machine_id),
|
||||
ListNetworkProps::DisabledOnly,
|
||||
)
|
||||
.await
|
||||
.map_err(convert_db_error)?
|
||||
.iter()
|
||||
.map(|x| Into::<proto::common::Uuid>::into(x.network_instance_id.clone()))
|
||||
.collect::<Vec<_>>();
|
||||
|
||||
Ok(ListNetworkInstanceIdsJsonResp {
|
||||
running_inst_ids,
|
||||
disabled_inst_ids,
|
||||
}
|
||||
.into())
|
||||
.map_err(convert_error)?
|
||||
.into())
|
||||
}
|
||||
|
||||
async fn handle_remove_network_instance(
|
||||
@@ -276,25 +176,13 @@ impl NetworkApi {
|
||||
State(client_mgr): AppState,
|
||||
Path((machine_id, inst_id)): Path<(uuid::Uuid, uuid::Uuid)>,
|
||||
) -> Result<(), HttpHandleError> {
|
||||
let result =
|
||||
Self::get_session_by_machine_id(&auth_session, &client_mgr, &machine_id).await?;
|
||||
|
||||
client_mgr
|
||||
.db()
|
||||
.delete_network_config(auth_session.user.as_ref().unwrap().id(), inst_id)
|
||||
.handle_remove_network_instance(
|
||||
(Self::get_user_id(&auth_session)?, machine_id),
|
||||
inst_id,
|
||||
)
|
||||
.await
|
||||
.map_err(convert_db_error)?;
|
||||
|
||||
let c = result.scoped_rpc_client();
|
||||
c.delete_network_instance(
|
||||
BaseController::default(),
|
||||
DeleteNetworkInstanceRequest {
|
||||
inst_ids: vec![inst_id.into()],
|
||||
},
|
||||
)
|
||||
.await
|
||||
.map_err(convert_rpc_error)?;
|
||||
Ok(())
|
||||
.map_err(convert_error)
|
||||
}
|
||||
|
||||
async fn handle_list_machines(
|
||||
@@ -334,37 +222,14 @@ impl NetworkApi {
|
||||
));
|
||||
};
|
||||
|
||||
let sess = Self::get_session_by_machine_id(&auth_session, &client_mgr, &machine_id).await?;
|
||||
let cfg = client_mgr
|
||||
.db()
|
||||
.update_network_config_state(auth_session.user.unwrap().id(), inst_id, payload.disabled)
|
||||
.await
|
||||
.map_err(convert_db_error)?;
|
||||
|
||||
let c = sess.scoped_rpc_client();
|
||||
|
||||
if payload.disabled {
|
||||
c.delete_network_instance(
|
||||
BaseController::default(),
|
||||
DeleteNetworkInstanceRequest {
|
||||
inst_ids: vec![inst_id.into()],
|
||||
},
|
||||
client_mgr
|
||||
.handle_update_network_state(
|
||||
(auth_session.user.unwrap().id(), machine_id),
|
||||
inst_id,
|
||||
payload.disabled,
|
||||
)
|
||||
.await
|
||||
.map_err(convert_rpc_error)?;
|
||||
} else {
|
||||
c.run_network_instance(
|
||||
BaseController::default(),
|
||||
RunNetworkInstanceRequest {
|
||||
inst_id: Some(inst_id.into()),
|
||||
config: Some(serde_json::from_str(&cfg.network_config).unwrap()),
|
||||
},
|
||||
)
|
||||
.await
|
||||
.map_err(convert_rpc_error)?;
|
||||
}
|
||||
|
||||
Ok(())
|
||||
.map_err(convert_error)
|
||||
}
|
||||
|
||||
async fn handle_get_network_config(
|
||||
@@ -372,31 +237,14 @@ impl NetworkApi {
|
||||
State(client_mgr): AppState,
|
||||
Path((machine_id, inst_id)): Path<(uuid::Uuid, uuid::Uuid)>,
|
||||
) -> Result<Json<NetworkConfig>, HttpHandleError> {
|
||||
let inst_id = inst_id.to_string();
|
||||
|
||||
let db_row = client_mgr
|
||||
.db()
|
||||
.get_network_config(auth_session.user.unwrap().id(), &machine_id, &inst_id)
|
||||
Ok(client_mgr
|
||||
.handle_get_network_config((auth_session.user.unwrap().id(), machine_id), inst_id)
|
||||
.await
|
||||
.map_err(convert_db_error)?
|
||||
.ok_or((
|
||||
StatusCode::NOT_FOUND,
|
||||
other_error(format!("No such network instance: {}", inst_id)).into(),
|
||||
))?;
|
||||
|
||||
Ok(
|
||||
serde_json::from_str::<NetworkConfig>(&db_row.network_config)
|
||||
.map_err(|e| {
|
||||
(
|
||||
StatusCode::INTERNAL_SERVER_ERROR,
|
||||
other_error(format!("Failed to parse network config: {:?}", e)).into(),
|
||||
)
|
||||
})?
|
||||
.into(),
|
||||
)
|
||||
.map_err(convert_error)?
|
||||
.into())
|
||||
}
|
||||
|
||||
pub fn build_route(&mut self) -> Router<AppStateInner> {
|
||||
pub fn build_route() -> Router<AppStateInner> {
|
||||
Router::new()
|
||||
.route("/api/v1/machines", get(Self::handle_list_machines))
|
||||
.route(
|
||||
|
||||
Reference in New Issue
Block a user