feat(proxy): implement log setting, proxy setting, rewrite rule, server block, and SSL certificate services
- Added LogSettingService with CRUD operations for log settings. - Introduced ProxySettingService for managing proxy settings with CRUD functionality. - Created RewriteRuleService to handle rewrite rules with full CRUD capabilities. - Implemented ServerBlockService for managing server blocks, including relationships with access rules and location blocks. - Added SslCertificateService for managing SSL certificates with create, read, update, and delete operations. - Updated types.rs to include new service configurations and ensure proper merging of overrides. - Enhanced existing tests to cover new functionalities and ensure correctness.
This commit is contained in:
155
apps/nxmesh-master/src/service/proxy/access_rule/mod.rs
Normal file
155
apps/nxmesh-master/src/service/proxy/access_rule/mod.rs
Normal file
@@ -0,0 +1,155 @@
|
||||
use sea_orm::{ActiveModelTrait, ActiveValue::Set, DatabaseConnection, EntityTrait, prelude::*};
|
||||
use uuid::Uuid;
|
||||
|
||||
use crate::service::proxy::types::{AccessRuleConfig, ProxyServiceError, ProxyServiceResult};
|
||||
|
||||
pub struct CreateAccessRuleParams {
|
||||
pub server_id: Option<Uuid>,
|
||||
pub location_id: Option<Uuid>,
|
||||
pub r#type: String,
|
||||
pub ip_cidr: String,
|
||||
pub description: Option<String>,
|
||||
pub priority: i32,
|
||||
pub override_of_id: Option<Uuid>,
|
||||
}
|
||||
|
||||
pub struct UpdateAccessRuleParams {
|
||||
pub server_id: Option<Option<Uuid>>,
|
||||
pub location_id: Option<Option<Uuid>>,
|
||||
pub r#type: Option<String>,
|
||||
pub ip_cidr: Option<String>,
|
||||
pub description: Option<Option<String>>,
|
||||
pub priority: Option<i32>,
|
||||
pub override_of_id: Option<Option<Uuid>>,
|
||||
}
|
||||
|
||||
#[async_trait::async_trait]
|
||||
pub trait AccessRuleService: Send + Sync + 'static {
|
||||
async fn get(&self, id: Uuid) -> ProxyServiceResult<AccessRuleConfig>;
|
||||
async fn list_by_server(&self, server_id: Uuid) -> ProxyServiceResult<Vec<AccessRuleConfig>>;
|
||||
async fn list_by_location(
|
||||
&self,
|
||||
location_id: Uuid,
|
||||
) -> ProxyServiceResult<Vec<AccessRuleConfig>>;
|
||||
async fn create(&self, params: CreateAccessRuleParams) -> ProxyServiceResult<AccessRuleConfig>;
|
||||
async fn update(
|
||||
&self,
|
||||
id: Uuid,
|
||||
params: UpdateAccessRuleParams,
|
||||
) -> ProxyServiceResult<AccessRuleConfig>;
|
||||
async fn delete(&self, id: Uuid) -> ProxyServiceResult<bool>;
|
||||
}
|
||||
|
||||
pub(crate) struct AccessRuleServiceImpl {
|
||||
db: DatabaseConnection,
|
||||
}
|
||||
|
||||
impl AccessRuleServiceImpl {
|
||||
pub fn new(db: DatabaseConnection) -> Self {
|
||||
Self { db }
|
||||
}
|
||||
}
|
||||
|
||||
#[async_trait::async_trait]
|
||||
impl AccessRuleService for AccessRuleServiceImpl {
|
||||
async fn get(&self, id: Uuid) -> ProxyServiceResult<AccessRuleConfig> {
|
||||
use crate::db::entities::access_rule;
|
||||
|
||||
let model = access_rule::Entity::find_by_id(id)
|
||||
.one(&self.db)
|
||||
.await?
|
||||
.ok_or(ProxyServiceError::ConfigNotFound)?;
|
||||
|
||||
Ok(model.into())
|
||||
}
|
||||
|
||||
async fn list_by_server(&self, server_id: Uuid) -> ProxyServiceResult<Vec<AccessRuleConfig>> {
|
||||
use crate::db::entities::access_rule;
|
||||
|
||||
let models = access_rule::Entity::find()
|
||||
.filter(access_rule::Column::ServerId.eq(server_id))
|
||||
.all(&self.db)
|
||||
.await?;
|
||||
|
||||
Ok(models.into_iter().map(Into::into).collect())
|
||||
}
|
||||
|
||||
async fn list_by_location(
|
||||
&self,
|
||||
location_id: Uuid,
|
||||
) -> ProxyServiceResult<Vec<AccessRuleConfig>> {
|
||||
use crate::db::entities::access_rule;
|
||||
|
||||
let models = access_rule::Entity::find()
|
||||
.filter(access_rule::Column::LocationId.eq(location_id))
|
||||
.all(&self.db)
|
||||
.await?;
|
||||
|
||||
Ok(models.into_iter().map(Into::into).collect())
|
||||
}
|
||||
|
||||
async fn create(&self, params: CreateAccessRuleParams) -> ProxyServiceResult<AccessRuleConfig> {
|
||||
use crate::db::entities::access_rule::ActiveModel;
|
||||
|
||||
let model = ActiveModel {
|
||||
id: Set(Uuid::new_v4()),
|
||||
server_id: Set(params.server_id),
|
||||
location_id: Set(params.location_id),
|
||||
r#type: Set(params.r#type),
|
||||
ip_cidr: Set(params.ip_cidr),
|
||||
description: Set(params.description),
|
||||
priority: Set(params.priority),
|
||||
is_deleted: Set(false),
|
||||
override_of_id: Set(params.override_of_id),
|
||||
};
|
||||
|
||||
let result = model.insert(&self.db).await?;
|
||||
Ok(result.into())
|
||||
}
|
||||
|
||||
async fn update(
|
||||
&self,
|
||||
id: Uuid,
|
||||
params: UpdateAccessRuleParams,
|
||||
) -> ProxyServiceResult<AccessRuleConfig> {
|
||||
use crate::db::entities::access_rule::{ActiveModel, Entity as AccessRuleEntity};
|
||||
|
||||
let existing = AccessRuleEntity::find_by_id(id)
|
||||
.one(&self.db)
|
||||
.await?
|
||||
.ok_or(ProxyServiceError::ConfigNotFound)?;
|
||||
|
||||
let mut model: ActiveModel = existing.into();
|
||||
if let Some(server_id) = params.server_id {
|
||||
model.server_id = Set(server_id);
|
||||
}
|
||||
if let Some(location_id) = params.location_id {
|
||||
model.location_id = Set(location_id);
|
||||
}
|
||||
if let Some(r#type) = params.r#type {
|
||||
model.r#type = Set(r#type);
|
||||
}
|
||||
if let Some(ip_cidr) = params.ip_cidr {
|
||||
model.ip_cidr = Set(ip_cidr);
|
||||
}
|
||||
if let Some(description) = params.description {
|
||||
model.description = Set(description);
|
||||
}
|
||||
if let Some(priority) = params.priority {
|
||||
model.priority = Set(priority);
|
||||
}
|
||||
if let Some(override_of_id) = params.override_of_id {
|
||||
model.override_of_id = Set(override_of_id);
|
||||
}
|
||||
|
||||
let result = model.update(&self.db).await?;
|
||||
Ok(result.into())
|
||||
}
|
||||
|
||||
async fn delete(&self, id: Uuid) -> ProxyServiceResult<bool> {
|
||||
let result = crate::db::entities::access_rule::Entity::delete_by_id(id)
|
||||
.exec(&self.db)
|
||||
.await?;
|
||||
Ok(result.rows_affected > 0)
|
||||
}
|
||||
}
|
||||
115
apps/nxmesh-master/src/service/proxy/cache_zone/mod.rs
Normal file
115
apps/nxmesh-master/src/service/proxy/cache_zone/mod.rs
Normal file
@@ -0,0 +1,115 @@
|
||||
use sea_orm::{ActiveModelTrait, ActiveValue::Set, DatabaseConnection, EntityTrait, prelude::*};
|
||||
use uuid::Uuid;
|
||||
|
||||
use crate::service::proxy::types::{CacheZoneConfig, ProxyServiceError, ProxyServiceResult};
|
||||
|
||||
pub struct CreateCacheZoneParams {
|
||||
pub name: String,
|
||||
pub path: String,
|
||||
pub size_limit: String,
|
||||
pub override_of_id: Option<Uuid>,
|
||||
}
|
||||
|
||||
pub struct UpdateCacheZoneParams {
|
||||
pub name: Option<String>,
|
||||
pub path: Option<String>,
|
||||
pub size_limit: Option<String>,
|
||||
pub override_of_id: Option<Option<Uuid>>,
|
||||
}
|
||||
|
||||
#[async_trait::async_trait]
|
||||
pub trait CacheZoneService: Send + Sync + 'static {
|
||||
async fn get(&self, id: Uuid) -> ProxyServiceResult<CacheZoneConfig>;
|
||||
async fn list(&self) -> ProxyServiceResult<Vec<CacheZoneConfig>>;
|
||||
async fn create(&self, params: CreateCacheZoneParams) -> ProxyServiceResult<CacheZoneConfig>;
|
||||
async fn update(
|
||||
&self,
|
||||
id: Uuid,
|
||||
params: UpdateCacheZoneParams,
|
||||
) -> ProxyServiceResult<CacheZoneConfig>;
|
||||
async fn delete(&self, id: Uuid) -> ProxyServiceResult<bool>;
|
||||
}
|
||||
|
||||
pub(crate) struct CacheZoneServiceImpl {
|
||||
db: DatabaseConnection,
|
||||
}
|
||||
|
||||
impl CacheZoneServiceImpl {
|
||||
pub fn new(db: DatabaseConnection) -> Self {
|
||||
Self { db }
|
||||
}
|
||||
}
|
||||
|
||||
#[async_trait::async_trait]
|
||||
impl CacheZoneService for CacheZoneServiceImpl {
|
||||
async fn get(&self, id: Uuid) -> ProxyServiceResult<CacheZoneConfig> {
|
||||
use crate::db::entities::cache_zone;
|
||||
|
||||
let model = cache_zone::Entity::find_by_id(id)
|
||||
.one(&self.db)
|
||||
.await?
|
||||
.ok_or(ProxyServiceError::ConfigNotFound)?;
|
||||
|
||||
Ok(model.into())
|
||||
}
|
||||
|
||||
async fn list(&self) -> ProxyServiceResult<Vec<CacheZoneConfig>> {
|
||||
use crate::db::entities::cache_zone;
|
||||
|
||||
let models = cache_zone::Entity::find().all(&self.db).await?;
|
||||
|
||||
Ok(models.into_iter().map(Into::into).collect())
|
||||
}
|
||||
|
||||
async fn create(&self, params: CreateCacheZoneParams) -> ProxyServiceResult<CacheZoneConfig> {
|
||||
use crate::db::entities::cache_zone::ActiveModel;
|
||||
|
||||
let model = ActiveModel {
|
||||
id: Set(Uuid::new_v4()),
|
||||
name: Set(params.name),
|
||||
path: Set(params.path),
|
||||
size_limit: Set(params.size_limit),
|
||||
override_of_id: Set(params.override_of_id),
|
||||
};
|
||||
|
||||
let result = model.insert(&self.db).await?;
|
||||
Ok(result.into())
|
||||
}
|
||||
|
||||
async fn update(
|
||||
&self,
|
||||
id: Uuid,
|
||||
params: UpdateCacheZoneParams,
|
||||
) -> ProxyServiceResult<CacheZoneConfig> {
|
||||
use crate::db::entities::cache_zone::{ActiveModel, Entity as CacheZoneEntity};
|
||||
|
||||
let existing = CacheZoneEntity::find_by_id(id)
|
||||
.one(&self.db)
|
||||
.await?
|
||||
.ok_or(ProxyServiceError::ConfigNotFound)?;
|
||||
|
||||
let mut model: ActiveModel = existing.into();
|
||||
if let Some(name) = params.name {
|
||||
model.name = Set(name);
|
||||
}
|
||||
if let Some(path) = params.path {
|
||||
model.path = Set(path);
|
||||
}
|
||||
if let Some(size_limit) = params.size_limit {
|
||||
model.size_limit = Set(size_limit);
|
||||
}
|
||||
if let Some(override_of_id) = params.override_of_id {
|
||||
model.override_of_id = Set(override_of_id);
|
||||
}
|
||||
|
||||
let result = model.update(&self.db).await?;
|
||||
Ok(result.into())
|
||||
}
|
||||
|
||||
async fn delete(&self, id: Uuid) -> ProxyServiceResult<bool> {
|
||||
let result = crate::db::entities::cache_zone::Entity::delete_by_id(id)
|
||||
.exec(&self.db)
|
||||
.await?;
|
||||
Ok(result.rows_affected > 0)
|
||||
}
|
||||
}
|
||||
143
apps/nxmesh-master/src/service/proxy/config_inheritance/mod.rs
Normal file
143
apps/nxmesh-master/src/service/proxy/config_inheritance/mod.rs
Normal file
@@ -0,0 +1,143 @@
|
||||
use sea_orm::{ActiveModelTrait, ActiveValue::Set, DatabaseConnection, EntityTrait, prelude::*};
|
||||
use uuid::Uuid;
|
||||
|
||||
use crate::service::proxy::types::ProxyServiceResult;
|
||||
|
||||
pub struct AddInheritanceParams {
|
||||
pub child_config_id: Uuid,
|
||||
pub parent_config_id: Uuid,
|
||||
pub priority: Option<i32>,
|
||||
}
|
||||
|
||||
pub struct ConfigInheritanceRecord {
|
||||
pub id: Uuid,
|
||||
pub child_config_id: Uuid,
|
||||
pub parent_config_id: Uuid,
|
||||
pub priority: Option<i32>,
|
||||
pub applied_at: chrono::NaiveDateTime,
|
||||
}
|
||||
|
||||
#[async_trait::async_trait]
|
||||
pub trait ConfigInheritanceService: Send + Sync + 'static {
|
||||
async fn add(
|
||||
&self,
|
||||
params: AddInheritanceParams,
|
||||
) -> ProxyServiceResult<ConfigInheritanceRecord>;
|
||||
async fn remove(
|
||||
&self,
|
||||
child_config_id: Uuid,
|
||||
parent_config_id: Uuid,
|
||||
) -> ProxyServiceResult<bool>;
|
||||
async fn list_parents(
|
||||
&self,
|
||||
child_config_id: Uuid,
|
||||
) -> ProxyServiceResult<Vec<ConfigInheritanceRecord>>;
|
||||
async fn list_children(
|
||||
&self,
|
||||
parent_config_id: Uuid,
|
||||
) -> ProxyServiceResult<Vec<ConfigInheritanceRecord>>;
|
||||
}
|
||||
|
||||
pub(crate) struct ConfigInheritanceServiceImpl {
|
||||
db: DatabaseConnection,
|
||||
}
|
||||
|
||||
impl ConfigInheritanceServiceImpl {
|
||||
pub fn new(db: DatabaseConnection) -> Self {
|
||||
Self { db }
|
||||
}
|
||||
}
|
||||
|
||||
#[async_trait::async_trait]
|
||||
impl ConfigInheritanceService for ConfigInheritanceServiceImpl {
|
||||
async fn add(
|
||||
&self,
|
||||
params: AddInheritanceParams,
|
||||
) -> ProxyServiceResult<ConfigInheritanceRecord> {
|
||||
use crate::db::entities::config_inheritance::ActiveModel;
|
||||
|
||||
let now = chrono::Utc::now().naive_utc();
|
||||
let model = ActiveModel {
|
||||
id: Set(Uuid::new_v4()),
|
||||
child_config_id: Set(params.child_config_id),
|
||||
parent_config_id: Set(params.parent_config_id),
|
||||
priority: Set(params.priority),
|
||||
applied_at: Set(now),
|
||||
};
|
||||
|
||||
let result = model.insert(&self.db).await?;
|
||||
Ok(ConfigInheritanceRecord {
|
||||
id: result.id,
|
||||
child_config_id: result.child_config_id,
|
||||
parent_config_id: result.parent_config_id,
|
||||
priority: result.priority,
|
||||
applied_at: result.applied_at,
|
||||
})
|
||||
}
|
||||
|
||||
async fn remove(
|
||||
&self,
|
||||
child_config_id: Uuid,
|
||||
parent_config_id: Uuid,
|
||||
) -> ProxyServiceResult<bool> {
|
||||
use crate::db::entities::config_inheritance::{Column, Entity as ConfigInheritanceEntity};
|
||||
use sea_orm::Condition;
|
||||
|
||||
let result = ConfigInheritanceEntity::delete_many()
|
||||
.filter(
|
||||
Condition::all()
|
||||
.add(Column::ChildConfigId.eq(child_config_id))
|
||||
.add(Column::ParentConfigId.eq(parent_config_id)),
|
||||
)
|
||||
.exec(&self.db)
|
||||
.await?;
|
||||
|
||||
Ok(result.rows_affected > 0)
|
||||
}
|
||||
|
||||
async fn list_parents(
|
||||
&self,
|
||||
child_config_id: Uuid,
|
||||
) -> ProxyServiceResult<Vec<ConfigInheritanceRecord>> {
|
||||
use crate::db::entities::config_inheritance;
|
||||
|
||||
let results = config_inheritance::Entity::find()
|
||||
.filter(config_inheritance::Column::ChildConfigId.eq(child_config_id))
|
||||
.all(&self.db)
|
||||
.await?;
|
||||
|
||||
Ok(results
|
||||
.into_iter()
|
||||
.map(|m| ConfigInheritanceRecord {
|
||||
id: m.id,
|
||||
child_config_id: m.child_config_id,
|
||||
parent_config_id: m.parent_config_id,
|
||||
priority: m.priority,
|
||||
applied_at: m.applied_at,
|
||||
})
|
||||
.collect())
|
||||
}
|
||||
|
||||
async fn list_children(
|
||||
&self,
|
||||
parent_config_id: Uuid,
|
||||
) -> ProxyServiceResult<Vec<ConfigInheritanceRecord>> {
|
||||
use crate::db::entities::config_inheritance;
|
||||
|
||||
let results = config_inheritance::Entity::find()
|
||||
.filter(config_inheritance::Column::ParentConfigId.eq(parent_config_id))
|
||||
.all(&self.db)
|
||||
.await?;
|
||||
|
||||
Ok(results
|
||||
.into_iter()
|
||||
.map(|m| ConfigInheritanceRecord {
|
||||
id: m.id,
|
||||
child_config_id: m.child_config_id,
|
||||
parent_config_id: m.parent_config_id,
|
||||
priority: m.priority,
|
||||
applied_at: m.applied_at,
|
||||
})
|
||||
.collect())
|
||||
}
|
||||
}
|
||||
129
apps/nxmesh-master/src/service/proxy/limit_rule/mod.rs
Normal file
129
apps/nxmesh-master/src/service/proxy/limit_rule/mod.rs
Normal file
@@ -0,0 +1,129 @@
|
||||
use sea_orm::{ActiveModelTrait, ActiveValue::Set, DatabaseConnection, EntityTrait, prelude::*};
|
||||
use uuid::Uuid;
|
||||
|
||||
use crate::service::proxy::types::{LimitRuleConfig, ProxyServiceError, ProxyServiceResult};
|
||||
|
||||
pub struct CreateLimitRuleParams {
|
||||
pub location_id: Uuid,
|
||||
pub zone_id: Uuid,
|
||||
pub burst: Option<i32>,
|
||||
pub nodelay: Option<bool>,
|
||||
pub override_of_id: Option<Uuid>,
|
||||
}
|
||||
|
||||
pub struct UpdateLimitRuleParams {
|
||||
pub location_id: Option<Uuid>,
|
||||
pub zone_id: Option<Uuid>,
|
||||
pub burst: Option<Option<i32>>,
|
||||
pub nodelay: Option<Option<bool>>,
|
||||
pub override_of_id: Option<Option<Uuid>>,
|
||||
}
|
||||
|
||||
#[async_trait::async_trait]
|
||||
pub trait LimitRuleService: Send + Sync + 'static {
|
||||
async fn get(&self, id: Uuid) -> ProxyServiceResult<LimitRuleConfig>;
|
||||
async fn list_by_location(&self, location_id: Uuid)
|
||||
-> ProxyServiceResult<Vec<LimitRuleConfig>>;
|
||||
async fn create(&self, params: CreateLimitRuleParams) -> ProxyServiceResult<LimitRuleConfig>;
|
||||
async fn update(
|
||||
&self,
|
||||
id: Uuid,
|
||||
params: UpdateLimitRuleParams,
|
||||
) -> ProxyServiceResult<LimitRuleConfig>;
|
||||
async fn delete(&self, id: Uuid) -> ProxyServiceResult<bool>;
|
||||
}
|
||||
|
||||
pub(crate) struct LimitRuleServiceImpl {
|
||||
db: DatabaseConnection,
|
||||
}
|
||||
|
||||
impl LimitRuleServiceImpl {
|
||||
pub fn new(db: DatabaseConnection) -> Self {
|
||||
Self { db }
|
||||
}
|
||||
}
|
||||
|
||||
#[async_trait::async_trait]
|
||||
impl LimitRuleService for LimitRuleServiceImpl {
|
||||
async fn get(&self, id: Uuid) -> ProxyServiceResult<LimitRuleConfig> {
|
||||
use crate::db::entities::limit_rule;
|
||||
|
||||
let model = limit_rule::Entity::find_by_id(id)
|
||||
.one(&self.db)
|
||||
.await?
|
||||
.ok_or(ProxyServiceError::ConfigNotFound)?;
|
||||
|
||||
Ok(model.into())
|
||||
}
|
||||
|
||||
async fn list_by_location(
|
||||
&self,
|
||||
location_id: Uuid,
|
||||
) -> ProxyServiceResult<Vec<LimitRuleConfig>> {
|
||||
use crate::db::entities::limit_rule;
|
||||
|
||||
let models = limit_rule::Entity::find()
|
||||
.filter(limit_rule::Column::LocationId.eq(location_id))
|
||||
.all(&self.db)
|
||||
.await?;
|
||||
|
||||
Ok(models.into_iter().map(Into::into).collect())
|
||||
}
|
||||
|
||||
async fn create(&self, params: CreateLimitRuleParams) -> ProxyServiceResult<LimitRuleConfig> {
|
||||
use crate::db::entities::limit_rule::ActiveModel;
|
||||
|
||||
let model = ActiveModel {
|
||||
id: Set(Uuid::new_v4()),
|
||||
location_id: Set(params.location_id),
|
||||
zone_id: Set(params.zone_id),
|
||||
burst: Set(params.burst),
|
||||
nodelay: Set(params.nodelay),
|
||||
is_deleted: Set(false),
|
||||
override_of_id: Set(params.override_of_id),
|
||||
};
|
||||
|
||||
let result = model.insert(&self.db).await?;
|
||||
Ok(result.into())
|
||||
}
|
||||
|
||||
async fn update(
|
||||
&self,
|
||||
id: Uuid,
|
||||
params: UpdateLimitRuleParams,
|
||||
) -> ProxyServiceResult<LimitRuleConfig> {
|
||||
use crate::db::entities::limit_rule::{ActiveModel, Entity as LimitRuleEntity};
|
||||
|
||||
let existing = LimitRuleEntity::find_by_id(id)
|
||||
.one(&self.db)
|
||||
.await?
|
||||
.ok_or(ProxyServiceError::ConfigNotFound)?;
|
||||
|
||||
let mut model: ActiveModel = existing.into();
|
||||
if let Some(location_id) = params.location_id {
|
||||
model.location_id = Set(location_id);
|
||||
}
|
||||
if let Some(zone_id) = params.zone_id {
|
||||
model.zone_id = Set(zone_id);
|
||||
}
|
||||
if let Some(burst) = params.burst {
|
||||
model.burst = Set(burst);
|
||||
}
|
||||
if let Some(nodelay) = params.nodelay {
|
||||
model.nodelay = Set(nodelay);
|
||||
}
|
||||
if let Some(override_of_id) = params.override_of_id {
|
||||
model.override_of_id = Set(override_of_id);
|
||||
}
|
||||
|
||||
let result = model.update(&self.db).await?;
|
||||
Ok(result.into())
|
||||
}
|
||||
|
||||
async fn delete(&self, id: Uuid) -> ProxyServiceResult<bool> {
|
||||
let result = crate::db::entities::limit_rule::Entity::delete_by_id(id)
|
||||
.exec(&self.db)
|
||||
.await?;
|
||||
Ok(result.rows_affected > 0)
|
||||
}
|
||||
}
|
||||
115
apps/nxmesh-master/src/service/proxy/limit_zone/mod.rs
Normal file
115
apps/nxmesh-master/src/service/proxy/limit_zone/mod.rs
Normal file
@@ -0,0 +1,115 @@
|
||||
use sea_orm::{ActiveModelTrait, ActiveValue::Set, DatabaseConnection, EntityTrait, prelude::*};
|
||||
use uuid::Uuid;
|
||||
|
||||
use crate::service::proxy::types::{LimitZoneConfig, ProxyServiceError, ProxyServiceResult};
|
||||
|
||||
pub struct CreateLimitZoneParams {
|
||||
pub name: String,
|
||||
pub key: String,
|
||||
pub rate: String,
|
||||
pub override_of_id: Option<Uuid>,
|
||||
}
|
||||
|
||||
pub struct UpdateLimitZoneParams {
|
||||
pub name: Option<String>,
|
||||
pub key: Option<String>,
|
||||
pub rate: Option<String>,
|
||||
pub override_of_id: Option<Option<Uuid>>,
|
||||
}
|
||||
|
||||
#[async_trait::async_trait]
|
||||
pub trait LimitZoneService: Send + Sync + 'static {
|
||||
async fn get(&self, id: Uuid) -> ProxyServiceResult<LimitZoneConfig>;
|
||||
async fn list(&self) -> ProxyServiceResult<Vec<LimitZoneConfig>>;
|
||||
async fn create(&self, params: CreateLimitZoneParams) -> ProxyServiceResult<LimitZoneConfig>;
|
||||
async fn update(
|
||||
&self,
|
||||
id: Uuid,
|
||||
params: UpdateLimitZoneParams,
|
||||
) -> ProxyServiceResult<LimitZoneConfig>;
|
||||
async fn delete(&self, id: Uuid) -> ProxyServiceResult<bool>;
|
||||
}
|
||||
|
||||
pub(crate) struct LimitZoneServiceImpl {
|
||||
db: DatabaseConnection,
|
||||
}
|
||||
|
||||
impl LimitZoneServiceImpl {
|
||||
pub fn new(db: DatabaseConnection) -> Self {
|
||||
Self { db }
|
||||
}
|
||||
}
|
||||
|
||||
#[async_trait::async_trait]
|
||||
impl LimitZoneService for LimitZoneServiceImpl {
|
||||
async fn get(&self, id: Uuid) -> ProxyServiceResult<LimitZoneConfig> {
|
||||
use crate::db::entities::limit_zone;
|
||||
|
||||
let model = limit_zone::Entity::find_by_id(id)
|
||||
.one(&self.db)
|
||||
.await?
|
||||
.ok_or(ProxyServiceError::ConfigNotFound)?;
|
||||
|
||||
Ok(model.into())
|
||||
}
|
||||
|
||||
async fn list(&self) -> ProxyServiceResult<Vec<LimitZoneConfig>> {
|
||||
use crate::db::entities::limit_zone;
|
||||
|
||||
let models = limit_zone::Entity::find().all(&self.db).await?;
|
||||
|
||||
Ok(models.into_iter().map(Into::into).collect())
|
||||
}
|
||||
|
||||
async fn create(&self, params: CreateLimitZoneParams) -> ProxyServiceResult<LimitZoneConfig> {
|
||||
use crate::db::entities::limit_zone::ActiveModel;
|
||||
|
||||
let model = ActiveModel {
|
||||
id: Set(Uuid::new_v4()),
|
||||
name: Set(params.name),
|
||||
key: Set(params.key),
|
||||
rate: Set(params.rate),
|
||||
override_of_id: Set(params.override_of_id),
|
||||
};
|
||||
|
||||
let result = model.insert(&self.db).await?;
|
||||
Ok(result.into())
|
||||
}
|
||||
|
||||
async fn update(
|
||||
&self,
|
||||
id: Uuid,
|
||||
params: UpdateLimitZoneParams,
|
||||
) -> ProxyServiceResult<LimitZoneConfig> {
|
||||
use crate::db::entities::limit_zone::{ActiveModel, Entity as LimitZoneEntity};
|
||||
|
||||
let existing = LimitZoneEntity::find_by_id(id)
|
||||
.one(&self.db)
|
||||
.await?
|
||||
.ok_or(ProxyServiceError::ConfigNotFound)?;
|
||||
|
||||
let mut model: ActiveModel = existing.into();
|
||||
if let Some(name) = params.name {
|
||||
model.name = Set(name);
|
||||
}
|
||||
if let Some(key) = params.key {
|
||||
model.key = Set(key);
|
||||
}
|
||||
if let Some(rate) = params.rate {
|
||||
model.rate = Set(rate);
|
||||
}
|
||||
if let Some(override_of_id) = params.override_of_id {
|
||||
model.override_of_id = Set(override_of_id);
|
||||
}
|
||||
|
||||
let result = model.update(&self.db).await?;
|
||||
Ok(result.into())
|
||||
}
|
||||
|
||||
async fn delete(&self, id: Uuid) -> ProxyServiceResult<bool> {
|
||||
let result = crate::db::entities::limit_zone::Entity::delete_by_id(id)
|
||||
.exec(&self.db)
|
||||
.await?;
|
||||
Ok(result.rows_affected > 0)
|
||||
}
|
||||
}
|
||||
205
apps/nxmesh-master/src/service/proxy/location_block/mod.rs
Normal file
205
apps/nxmesh-master/src/service/proxy/location_block/mod.rs
Normal file
@@ -0,0 +1,205 @@
|
||||
use sea_orm::{ActiveModelTrait, ActiveValue::Set, DatabaseConnection, EntityTrait, prelude::*};
|
||||
use uuid::Uuid;
|
||||
|
||||
use crate::service::proxy::types::{
|
||||
LocationBlockConfig, OverrideRef, ProxyServiceError, ProxyServiceResult,
|
||||
};
|
||||
|
||||
pub struct CreateLocationBlockParams {
|
||||
pub server_id: Uuid,
|
||||
pub path_pattern: String,
|
||||
pub proxy_pass_upstream_id: Option<Uuid>,
|
||||
pub metadata: Option<serde_json::Value>,
|
||||
pub override_of_id: Option<Uuid>,
|
||||
}
|
||||
|
||||
pub struct UpdateLocationBlockParams {
|
||||
pub server_id: Option<Uuid>,
|
||||
pub path_pattern: Option<String>,
|
||||
pub proxy_pass_upstream_id: Option<Option<Uuid>>,
|
||||
pub metadata: Option<Option<serde_json::Value>>,
|
||||
pub override_of_id: Option<Option<Uuid>>,
|
||||
}
|
||||
|
||||
#[async_trait::async_trait]
|
||||
pub trait LocationBlockService: Send + Sync + 'static {
|
||||
async fn get(&self, id: Uuid) -> ProxyServiceResult<LocationBlockConfig>;
|
||||
async fn list_by_server(&self, server_id: Uuid)
|
||||
-> ProxyServiceResult<Vec<LocationBlockConfig>>;
|
||||
async fn create(
|
||||
&self,
|
||||
params: CreateLocationBlockParams,
|
||||
) -> ProxyServiceResult<LocationBlockConfig>;
|
||||
async fn update(
|
||||
&self,
|
||||
id: Uuid,
|
||||
params: UpdateLocationBlockParams,
|
||||
) -> ProxyServiceResult<LocationBlockConfig>;
|
||||
async fn delete(&self, id: Uuid) -> ProxyServiceResult<bool>;
|
||||
}
|
||||
|
||||
pub(crate) struct LocationBlockServiceImpl {
|
||||
db: DatabaseConnection,
|
||||
}
|
||||
|
||||
impl LocationBlockServiceImpl {
|
||||
pub fn new(db: DatabaseConnection) -> Self {
|
||||
Self { db }
|
||||
}
|
||||
|
||||
async fn build_with_children(
|
||||
&self,
|
||||
model: crate::db::entities::location_block::Model,
|
||||
) -> ProxyServiceResult<LocationBlockConfig> {
|
||||
use crate::db::entities::{access_rule, limit_rule, proxy_setting, rewrite_rule};
|
||||
|
||||
let access_rules = access_rule::Entity::find()
|
||||
.filter(access_rule::Column::LocationId.eq(model.id))
|
||||
.all(&self.db)
|
||||
.await?
|
||||
.into_iter()
|
||||
.map(|a| OverrideRef {
|
||||
id: a.id,
|
||||
override_of_id: a.override_of_id,
|
||||
})
|
||||
.collect();
|
||||
|
||||
let limit_rules = limit_rule::Entity::find()
|
||||
.filter(limit_rule::Column::LocationId.eq(model.id))
|
||||
.all(&self.db)
|
||||
.await?
|
||||
.into_iter()
|
||||
.map(|l| OverrideRef {
|
||||
id: l.id,
|
||||
override_of_id: l.override_of_id,
|
||||
})
|
||||
.collect();
|
||||
|
||||
let proxy_settings = proxy_setting::Entity::find()
|
||||
.filter(proxy_setting::Column::LocationId.eq(model.id))
|
||||
.all(&self.db)
|
||||
.await?
|
||||
.into_iter()
|
||||
.map(|p| OverrideRef {
|
||||
id: p.id,
|
||||
override_of_id: p.override_of_id,
|
||||
})
|
||||
.collect();
|
||||
|
||||
let rewrite_rules = rewrite_rule::Entity::find()
|
||||
.filter(rewrite_rule::Column::LocationId.eq(model.id))
|
||||
.all(&self.db)
|
||||
.await?
|
||||
.into_iter()
|
||||
.map(|r| OverrideRef {
|
||||
id: r.id,
|
||||
override_of_id: r.override_of_id,
|
||||
})
|
||||
.collect();
|
||||
|
||||
Ok(LocationBlockConfig {
|
||||
id: model.id,
|
||||
server_id: model.server_id,
|
||||
path_pattern: model.path_pattern,
|
||||
proxy_pass_upstream_id: model.proxy_pass_upstream_id,
|
||||
metadata: model.metadata,
|
||||
override_of_id: model.override_of_id,
|
||||
access_rules,
|
||||
limit_rules,
|
||||
proxy_settings,
|
||||
rewrite_rules,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
#[async_trait::async_trait]
|
||||
impl LocationBlockService for LocationBlockServiceImpl {
|
||||
async fn get(&self, id: Uuid) -> ProxyServiceResult<LocationBlockConfig> {
|
||||
use crate::db::entities::location_block;
|
||||
|
||||
let model = location_block::Entity::find_by_id(id)
|
||||
.one(&self.db)
|
||||
.await?
|
||||
.ok_or(ProxyServiceError::ConfigNotFound)?;
|
||||
|
||||
self.build_with_children(model).await
|
||||
}
|
||||
|
||||
async fn list_by_server(
|
||||
&self,
|
||||
server_id: Uuid,
|
||||
) -> ProxyServiceResult<Vec<LocationBlockConfig>> {
|
||||
use crate::db::entities::location_block;
|
||||
|
||||
let models = location_block::Entity::find()
|
||||
.filter(location_block::Column::ServerId.eq(server_id))
|
||||
.all(&self.db)
|
||||
.await?;
|
||||
|
||||
let mut results = Vec::with_capacity(models.len());
|
||||
for m in models {
|
||||
results.push(self.build_with_children(m).await?);
|
||||
}
|
||||
Ok(results)
|
||||
}
|
||||
|
||||
async fn create(
|
||||
&self,
|
||||
params: CreateLocationBlockParams,
|
||||
) -> ProxyServiceResult<LocationBlockConfig> {
|
||||
use crate::db::entities::location_block::ActiveModel;
|
||||
|
||||
let id = Uuid::new_v4();
|
||||
let model = ActiveModel {
|
||||
id: Set(id),
|
||||
server_id: Set(params.server_id),
|
||||
path_pattern: Set(params.path_pattern),
|
||||
proxy_pass_upstream_id: Set(params.proxy_pass_upstream_id),
|
||||
metadata: Set(params.metadata),
|
||||
override_of_id: Set(params.override_of_id),
|
||||
};
|
||||
|
||||
let result = model.insert(&self.db).await?;
|
||||
self.build_with_children(result).await
|
||||
}
|
||||
|
||||
async fn update(
|
||||
&self,
|
||||
id: Uuid,
|
||||
params: UpdateLocationBlockParams,
|
||||
) -> ProxyServiceResult<LocationBlockConfig> {
|
||||
use crate::db::entities::location_block::{ActiveModel, Entity as LocationBlockEntity};
|
||||
|
||||
let existing = LocationBlockEntity::find_by_id(id)
|
||||
.one(&self.db)
|
||||
.await?
|
||||
.ok_or(ProxyServiceError::ConfigNotFound)?;
|
||||
|
||||
let mut model: ActiveModel = existing.into();
|
||||
if let Some(server_id) = params.server_id {
|
||||
model.server_id = Set(server_id);
|
||||
}
|
||||
if let Some(path_pattern) = params.path_pattern {
|
||||
model.path_pattern = Set(path_pattern);
|
||||
}
|
||||
if let Some(proxy_pass_upstream_id) = params.proxy_pass_upstream_id {
|
||||
model.proxy_pass_upstream_id = Set(proxy_pass_upstream_id);
|
||||
}
|
||||
if let Some(metadata) = params.metadata {
|
||||
model.metadata = Set(metadata);
|
||||
}
|
||||
if let Some(override_of_id) = params.override_of_id {
|
||||
model.override_of_id = Set(override_of_id);
|
||||
}
|
||||
|
||||
let result = model.update(&self.db).await?;
|
||||
self.build_with_children(result).await
|
||||
}
|
||||
|
||||
async fn delete(&self, id: Uuid) -> ProxyServiceResult<bool> {
|
||||
let result = crate::db::entities::location_block::Entity::delete_by_id(id)
|
||||
.exec(&self.db)
|
||||
.await?;
|
||||
Ok(result.rows_affected > 0)
|
||||
}
|
||||
}
|
||||
124
apps/nxmesh-master/src/service/proxy/log_setting/mod.rs
Normal file
124
apps/nxmesh-master/src/service/proxy/log_setting/mod.rs
Normal file
@@ -0,0 +1,124 @@
|
||||
use sea_orm::{ActiveModelTrait, ActiveValue::Set, DatabaseConnection, EntityTrait, prelude::*};
|
||||
use uuid::Uuid;
|
||||
|
||||
use crate::service::proxy::types::{LogSettingConfig, ProxyServiceError, ProxyServiceResult};
|
||||
|
||||
pub struct CreateLogSettingParams {
|
||||
pub server_id: Uuid,
|
||||
pub access_log_path: Option<String>,
|
||||
pub error_log_path: Option<String>,
|
||||
pub log_level: Option<String>,
|
||||
pub override_of_id: Option<Uuid>,
|
||||
}
|
||||
|
||||
pub struct UpdateLogSettingParams {
|
||||
pub server_id: Option<Uuid>,
|
||||
pub access_log_path: Option<Option<String>>,
|
||||
pub error_log_path: Option<Option<String>>,
|
||||
pub log_level: Option<Option<String>>,
|
||||
pub override_of_id: Option<Option<Uuid>>,
|
||||
}
|
||||
|
||||
#[async_trait::async_trait]
|
||||
pub trait LogSettingService: Send + Sync + 'static {
|
||||
async fn get(&self, id: Uuid) -> ProxyServiceResult<LogSettingConfig>;
|
||||
async fn list_by_server(&self, server_id: Uuid) -> ProxyServiceResult<Vec<LogSettingConfig>>;
|
||||
async fn create(&self, params: CreateLogSettingParams) -> ProxyServiceResult<LogSettingConfig>;
|
||||
async fn update(
|
||||
&self,
|
||||
id: Uuid,
|
||||
params: UpdateLogSettingParams,
|
||||
) -> ProxyServiceResult<LogSettingConfig>;
|
||||
async fn delete(&self, id: Uuid) -> ProxyServiceResult<bool>;
|
||||
}
|
||||
|
||||
pub(crate) struct LogSettingServiceImpl {
|
||||
db: DatabaseConnection,
|
||||
}
|
||||
|
||||
impl LogSettingServiceImpl {
|
||||
pub fn new(db: DatabaseConnection) -> Self {
|
||||
Self { db }
|
||||
}
|
||||
}
|
||||
|
||||
#[async_trait::async_trait]
|
||||
impl LogSettingService for LogSettingServiceImpl {
|
||||
async fn get(&self, id: Uuid) -> ProxyServiceResult<LogSettingConfig> {
|
||||
use crate::db::entities::log_setting;
|
||||
|
||||
let model = log_setting::Entity::find_by_id(id)
|
||||
.one(&self.db)
|
||||
.await?
|
||||
.ok_or(ProxyServiceError::ConfigNotFound)?;
|
||||
|
||||
Ok(model.into())
|
||||
}
|
||||
|
||||
async fn list_by_server(&self, server_id: Uuid) -> ProxyServiceResult<Vec<LogSettingConfig>> {
|
||||
use crate::db::entities::log_setting;
|
||||
|
||||
let models = log_setting::Entity::find()
|
||||
.filter(log_setting::Column::ServerId.eq(server_id))
|
||||
.all(&self.db)
|
||||
.await?;
|
||||
|
||||
Ok(models.into_iter().map(Into::into).collect())
|
||||
}
|
||||
|
||||
async fn create(&self, params: CreateLogSettingParams) -> ProxyServiceResult<LogSettingConfig> {
|
||||
use crate::db::entities::log_setting::ActiveModel;
|
||||
|
||||
let model = ActiveModel {
|
||||
id: Set(Uuid::new_v4()),
|
||||
server_id: Set(params.server_id),
|
||||
access_log_path: Set(params.access_log_path),
|
||||
error_log_path: Set(params.error_log_path),
|
||||
log_level: Set(params.log_level),
|
||||
override_of_id: Set(params.override_of_id),
|
||||
};
|
||||
|
||||
let result = model.insert(&self.db).await?;
|
||||
Ok(result.into())
|
||||
}
|
||||
|
||||
async fn update(
|
||||
&self,
|
||||
id: Uuid,
|
||||
params: UpdateLogSettingParams,
|
||||
) -> ProxyServiceResult<LogSettingConfig> {
|
||||
use crate::db::entities::log_setting::{ActiveModel, Entity as LogSettingEntity};
|
||||
|
||||
let existing = LogSettingEntity::find_by_id(id)
|
||||
.one(&self.db)
|
||||
.await?
|
||||
.ok_or(ProxyServiceError::ConfigNotFound)?;
|
||||
|
||||
let mut model: ActiveModel = existing.into();
|
||||
if let Some(server_id) = params.server_id {
|
||||
model.server_id = Set(server_id);
|
||||
}
|
||||
if let Some(access_log_path) = params.access_log_path {
|
||||
model.access_log_path = Set(access_log_path);
|
||||
}
|
||||
if let Some(error_log_path) = params.error_log_path {
|
||||
model.error_log_path = Set(error_log_path);
|
||||
}
|
||||
if let Some(log_level) = params.log_level {
|
||||
model.log_level = Set(log_level);
|
||||
}
|
||||
if let Some(override_of_id) = params.override_of_id {
|
||||
model.override_of_id = Set(override_of_id);
|
||||
}
|
||||
|
||||
let result = model.update(&self.db).await?;
|
||||
Ok(result.into())
|
||||
}
|
||||
|
||||
async fn delete(&self, id: Uuid) -> ProxyServiceResult<bool> {
|
||||
let result = crate::db::entities::log_setting::Entity::delete_by_id(id)
|
||||
.exec(&self.db)
|
||||
.await?;
|
||||
Ok(result.rows_affected > 0)
|
||||
}
|
||||
}
|
||||
@@ -1,10 +1,22 @@
|
||||
use crate::service::proxy::types::{
|
||||
AgentConfigBinding, CreateProxyConfigParams, ProxyConfig, ProxyConfigSummary,
|
||||
ProxyServiceResult, ProxyType, UpdateProxyConfigParams,
|
||||
ProxyServiceResult, UpdateProxyConfigParams,
|
||||
};
|
||||
|
||||
pub(crate) mod access_rule;
|
||||
pub(crate) mod cache_zone;
|
||||
pub(crate) mod config_inheritance;
|
||||
pub(crate) mod limit_rule;
|
||||
pub(crate) mod limit_zone;
|
||||
pub(crate) mod location_block;
|
||||
pub(crate) mod log_setting;
|
||||
pub(crate) mod nginx;
|
||||
pub(crate) mod proxy_setting;
|
||||
pub(crate) mod repo;
|
||||
pub(crate) mod rewrite_rule;
|
||||
pub(crate) mod server_block;
|
||||
pub(crate) mod ssl_certificate;
|
||||
pub(crate) mod upstream;
|
||||
|
||||
pub mod service;
|
||||
pub mod types;
|
||||
|
||||
@@ -187,6 +187,7 @@ impl ProxyConfigRenderer for NginxConfigRenderer {
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
#[allow(clippy::unwrap_used)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
use crate::service::proxy::types::*;
|
||||
@@ -271,13 +272,31 @@ mod tests {
|
||||
let renderer = NginxConfigRenderer;
|
||||
let output = renderer.render(&config);
|
||||
|
||||
assert!(output.contains("upstream backend {"), "should contain upstream block");
|
||||
assert!(output.contains("server 127.0.0.1:3000;"), "should contain upstream server");
|
||||
assert!(
|
||||
output.contains("upstream backend {"),
|
||||
"should contain upstream block"
|
||||
);
|
||||
assert!(
|
||||
output.contains("server 127.0.0.1:3000;"),
|
||||
"should contain upstream server"
|
||||
);
|
||||
assert!(output.contains("server {"), "should contain server block");
|
||||
assert!(output.contains("listen 80;"), "should contain listen directive");
|
||||
assert!(output.contains("server_name example.com;"), "should contain server name");
|
||||
assert!(output.contains("location /api {"), "should contain location block");
|
||||
assert!(output.contains("proxy_pass http://backend;"), "should contain proxy pass");
|
||||
assert!(
|
||||
output.contains("listen 80;"),
|
||||
"should contain listen directive"
|
||||
);
|
||||
assert!(
|
||||
output.contains("server_name example.com;"),
|
||||
"should contain server name"
|
||||
);
|
||||
assert!(
|
||||
output.contains("location /api {"),
|
||||
"should contain location block"
|
||||
);
|
||||
assert!(
|
||||
output.contains("proxy_pass http://backend;"),
|
||||
"should contain proxy pass"
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
@@ -296,7 +315,9 @@ mod tests {
|
||||
);
|
||||
let renderer = NginxConfigRenderer;
|
||||
let output = renderer.render(&config);
|
||||
assert!(output.contains("proxy_cache_path /var/cache/nginx levels=1:2 keys_zone=mycache:10m;"));
|
||||
assert!(
|
||||
output.contains("proxy_cache_path /var/cache/nginx levels=1:2 keys_zone=mycache:10m;")
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
||||
148
apps/nxmesh-master/src/service/proxy/proxy_setting/mod.rs
Normal file
148
apps/nxmesh-master/src/service/proxy/proxy_setting/mod.rs
Normal file
@@ -0,0 +1,148 @@
|
||||
use sea_orm::{ActiveModelTrait, ActiveValue::Set, DatabaseConnection, EntityTrait, prelude::*};
|
||||
use uuid::Uuid;
|
||||
|
||||
use crate::service::proxy::types::{ProxyServiceError, ProxyServiceResult, ProxySettingConfig};
|
||||
|
||||
pub struct CreateProxySettingParams {
|
||||
pub location_id: Uuid,
|
||||
pub read_timeout: Option<i32>,
|
||||
pub connect_timeout: Option<i32>,
|
||||
pub buffer_size: Option<i32>,
|
||||
pub cache_enabled: Option<bool>,
|
||||
pub cache_zone: Option<Uuid>,
|
||||
pub override_of_id: Option<Uuid>,
|
||||
}
|
||||
|
||||
pub struct UpdateProxySettingParams {
|
||||
pub location_id: Option<Uuid>,
|
||||
pub read_timeout: Option<Option<i32>>,
|
||||
pub connect_timeout: Option<Option<i32>>,
|
||||
pub buffer_size: Option<Option<i32>>,
|
||||
pub cache_enabled: Option<Option<bool>>,
|
||||
pub cache_zone: Option<Option<Uuid>>,
|
||||
pub override_of_id: Option<Option<Uuid>>,
|
||||
}
|
||||
|
||||
#[async_trait::async_trait]
|
||||
pub trait ProxySettingService: Send + Sync + 'static {
|
||||
async fn get(&self, id: Uuid) -> ProxyServiceResult<ProxySettingConfig>;
|
||||
async fn list_by_location(
|
||||
&self,
|
||||
location_id: Uuid,
|
||||
) -> ProxyServiceResult<Vec<ProxySettingConfig>>;
|
||||
async fn create(
|
||||
&self,
|
||||
params: CreateProxySettingParams,
|
||||
) -> ProxyServiceResult<ProxySettingConfig>;
|
||||
async fn update(
|
||||
&self,
|
||||
id: Uuid,
|
||||
params: UpdateProxySettingParams,
|
||||
) -> ProxyServiceResult<ProxySettingConfig>;
|
||||
async fn delete(&self, id: Uuid) -> ProxyServiceResult<bool>;
|
||||
}
|
||||
|
||||
pub(crate) struct ProxySettingServiceImpl {
|
||||
db: DatabaseConnection,
|
||||
}
|
||||
|
||||
impl ProxySettingServiceImpl {
|
||||
pub fn new(db: DatabaseConnection) -> Self {
|
||||
Self { db }
|
||||
}
|
||||
}
|
||||
|
||||
#[async_trait::async_trait]
|
||||
impl ProxySettingService for ProxySettingServiceImpl {
|
||||
async fn get(&self, id: Uuid) -> ProxyServiceResult<ProxySettingConfig> {
|
||||
use crate::db::entities::proxy_setting;
|
||||
|
||||
let model = proxy_setting::Entity::find_by_id(id)
|
||||
.one(&self.db)
|
||||
.await?
|
||||
.ok_or(ProxyServiceError::ConfigNotFound)?;
|
||||
|
||||
Ok(model.into())
|
||||
}
|
||||
|
||||
async fn list_by_location(
|
||||
&self,
|
||||
location_id: Uuid,
|
||||
) -> ProxyServiceResult<Vec<ProxySettingConfig>> {
|
||||
use crate::db::entities::proxy_setting;
|
||||
|
||||
let models = proxy_setting::Entity::find()
|
||||
.filter(proxy_setting::Column::LocationId.eq(location_id))
|
||||
.all(&self.db)
|
||||
.await?;
|
||||
|
||||
Ok(models.into_iter().map(Into::into).collect())
|
||||
}
|
||||
|
||||
async fn create(
|
||||
&self,
|
||||
params: CreateProxySettingParams,
|
||||
) -> ProxyServiceResult<ProxySettingConfig> {
|
||||
use crate::db::entities::proxy_setting::ActiveModel;
|
||||
|
||||
let model = ActiveModel {
|
||||
id: Set(Uuid::new_v4()),
|
||||
location_id: Set(params.location_id),
|
||||
read_timeout: Set(params.read_timeout),
|
||||
connect_timeout: Set(params.connect_timeout),
|
||||
buffer_size: Set(params.buffer_size),
|
||||
cache_enabled: Set(params.cache_enabled),
|
||||
cache_zone: Set(params.cache_zone),
|
||||
override_of_id: Set(params.override_of_id),
|
||||
};
|
||||
|
||||
let result = model.insert(&self.db).await?;
|
||||
Ok(result.into())
|
||||
}
|
||||
|
||||
async fn update(
|
||||
&self,
|
||||
id: Uuid,
|
||||
params: UpdateProxySettingParams,
|
||||
) -> ProxyServiceResult<ProxySettingConfig> {
|
||||
use crate::db::entities::proxy_setting::{ActiveModel, Entity as ProxySettingEntity};
|
||||
|
||||
let existing = ProxySettingEntity::find_by_id(id)
|
||||
.one(&self.db)
|
||||
.await?
|
||||
.ok_or(ProxyServiceError::ConfigNotFound)?;
|
||||
|
||||
let mut model: ActiveModel = existing.into();
|
||||
if let Some(location_id) = params.location_id {
|
||||
model.location_id = Set(location_id);
|
||||
}
|
||||
if let Some(read_timeout) = params.read_timeout {
|
||||
model.read_timeout = Set(read_timeout);
|
||||
}
|
||||
if let Some(connect_timeout) = params.connect_timeout {
|
||||
model.connect_timeout = Set(connect_timeout);
|
||||
}
|
||||
if let Some(buffer_size) = params.buffer_size {
|
||||
model.buffer_size = Set(buffer_size);
|
||||
}
|
||||
if let Some(cache_enabled) = params.cache_enabled {
|
||||
model.cache_enabled = Set(cache_enabled);
|
||||
}
|
||||
if let Some(cache_zone) = params.cache_zone {
|
||||
model.cache_zone = Set(cache_zone);
|
||||
}
|
||||
if let Some(override_of_id) = params.override_of_id {
|
||||
model.override_of_id = Set(override_of_id);
|
||||
}
|
||||
|
||||
let result = model.update(&self.db).await?;
|
||||
Ok(result.into())
|
||||
}
|
||||
|
||||
async fn delete(&self, id: Uuid) -> ProxyServiceResult<bool> {
|
||||
let result = crate::db::entities::proxy_setting::Entity::delete_by_id(id)
|
||||
.exec(&self.db)
|
||||
.await?;
|
||||
Ok(result.rows_affected > 0)
|
||||
}
|
||||
}
|
||||
143
apps/nxmesh-master/src/service/proxy/rewrite_rule/mod.rs
Normal file
143
apps/nxmesh-master/src/service/proxy/rewrite_rule/mod.rs
Normal file
@@ -0,0 +1,143 @@
|
||||
use sea_orm::{ActiveModelTrait, ActiveValue::Set, DatabaseConnection, EntityTrait, prelude::*};
|
||||
use uuid::Uuid;
|
||||
|
||||
use crate::service::proxy::types::{ProxyServiceError, ProxyServiceResult, RewriteRuleConfig};
|
||||
|
||||
pub struct CreateRewriteRuleParams {
|
||||
pub location_id: Uuid,
|
||||
pub pattern: String,
|
||||
pub replacement: String,
|
||||
pub flag: Option<String>,
|
||||
pub priority: i32,
|
||||
pub override_of_id: Option<Uuid>,
|
||||
}
|
||||
|
||||
pub struct UpdateRewriteRuleParams {
|
||||
pub location_id: Option<Uuid>,
|
||||
pub pattern: Option<String>,
|
||||
pub replacement: Option<String>,
|
||||
pub flag: Option<Option<String>>,
|
||||
pub priority: Option<i32>,
|
||||
pub override_of_id: Option<Option<Uuid>>,
|
||||
}
|
||||
|
||||
#[async_trait::async_trait]
|
||||
pub trait RewriteRuleService: Send + Sync + 'static {
|
||||
async fn get(&self, id: Uuid) -> ProxyServiceResult<RewriteRuleConfig>;
|
||||
async fn list_by_location(
|
||||
&self,
|
||||
location_id: Uuid,
|
||||
) -> ProxyServiceResult<Vec<RewriteRuleConfig>>;
|
||||
async fn create(
|
||||
&self,
|
||||
params: CreateRewriteRuleParams,
|
||||
) -> ProxyServiceResult<RewriteRuleConfig>;
|
||||
async fn update(
|
||||
&self,
|
||||
id: Uuid,
|
||||
params: UpdateRewriteRuleParams,
|
||||
) -> ProxyServiceResult<RewriteRuleConfig>;
|
||||
async fn delete(&self, id: Uuid) -> ProxyServiceResult<bool>;
|
||||
}
|
||||
|
||||
pub(crate) struct RewriteRuleServiceImpl {
|
||||
db: DatabaseConnection,
|
||||
}
|
||||
|
||||
impl RewriteRuleServiceImpl {
|
||||
pub fn new(db: DatabaseConnection) -> Self {
|
||||
Self { db }
|
||||
}
|
||||
}
|
||||
|
||||
#[async_trait::async_trait]
|
||||
impl RewriteRuleService for RewriteRuleServiceImpl {
|
||||
async fn get(&self, id: Uuid) -> ProxyServiceResult<RewriteRuleConfig> {
|
||||
use crate::db::entities::rewrite_rule;
|
||||
|
||||
let model = rewrite_rule::Entity::find_by_id(id)
|
||||
.one(&self.db)
|
||||
.await?
|
||||
.ok_or(ProxyServiceError::ConfigNotFound)?;
|
||||
|
||||
Ok(model.into())
|
||||
}
|
||||
|
||||
async fn list_by_location(
|
||||
&self,
|
||||
location_id: Uuid,
|
||||
) -> ProxyServiceResult<Vec<RewriteRuleConfig>> {
|
||||
use crate::db::entities::rewrite_rule;
|
||||
|
||||
let models = rewrite_rule::Entity::find()
|
||||
.filter(rewrite_rule::Column::LocationId.eq(location_id))
|
||||
.all(&self.db)
|
||||
.await?;
|
||||
|
||||
Ok(models.into_iter().map(Into::into).collect())
|
||||
}
|
||||
|
||||
async fn create(
|
||||
&self,
|
||||
params: CreateRewriteRuleParams,
|
||||
) -> ProxyServiceResult<RewriteRuleConfig> {
|
||||
use crate::db::entities::rewrite_rule::ActiveModel;
|
||||
|
||||
let model = ActiveModel {
|
||||
id: Set(Uuid::new_v4()),
|
||||
location_id: Set(params.location_id),
|
||||
pattern: Set(params.pattern),
|
||||
replacement: Set(params.replacement),
|
||||
flag: Set(params.flag),
|
||||
priority: Set(params.priority),
|
||||
is_deleted: Set(false),
|
||||
override_of_id: Set(params.override_of_id),
|
||||
};
|
||||
|
||||
let result = model.insert(&self.db).await?;
|
||||
Ok(result.into())
|
||||
}
|
||||
|
||||
async fn update(
|
||||
&self,
|
||||
id: Uuid,
|
||||
params: UpdateRewriteRuleParams,
|
||||
) -> ProxyServiceResult<RewriteRuleConfig> {
|
||||
use crate::db::entities::rewrite_rule::{ActiveModel, Entity as RewriteRuleEntity};
|
||||
|
||||
let existing = RewriteRuleEntity::find_by_id(id)
|
||||
.one(&self.db)
|
||||
.await?
|
||||
.ok_or(ProxyServiceError::ConfigNotFound)?;
|
||||
|
||||
let mut model: ActiveModel = existing.into();
|
||||
if let Some(location_id) = params.location_id {
|
||||
model.location_id = Set(location_id);
|
||||
}
|
||||
if let Some(pattern) = params.pattern {
|
||||
model.pattern = Set(pattern);
|
||||
}
|
||||
if let Some(replacement) = params.replacement {
|
||||
model.replacement = Set(replacement);
|
||||
}
|
||||
if let Some(flag) = params.flag {
|
||||
model.flag = Set(flag);
|
||||
}
|
||||
if let Some(priority) = params.priority {
|
||||
model.priority = Set(priority);
|
||||
}
|
||||
if let Some(override_of_id) = params.override_of_id {
|
||||
model.override_of_id = Set(override_of_id);
|
||||
}
|
||||
|
||||
let result = model.update(&self.db).await?;
|
||||
Ok(result.into())
|
||||
}
|
||||
|
||||
async fn delete(&self, id: Uuid) -> ProxyServiceResult<bool> {
|
||||
let result = crate::db::entities::rewrite_rule::Entity::delete_by_id(id)
|
||||
.exec(&self.db)
|
||||
.await?;
|
||||
Ok(result.rows_affected > 0)
|
||||
}
|
||||
}
|
||||
201
apps/nxmesh-master/src/service/proxy/server_block/mod.rs
Normal file
201
apps/nxmesh-master/src/service/proxy/server_block/mod.rs
Normal file
@@ -0,0 +1,201 @@
|
||||
use sea_orm::{ActiveModelTrait, ActiveValue::Set, DatabaseConnection, EntityTrait, prelude::*};
|
||||
use uuid::Uuid;
|
||||
|
||||
use crate::service::proxy::types::{
|
||||
OverrideRef, ProxyServiceError, ProxyServiceResult, ServerBlockConfig,
|
||||
};
|
||||
|
||||
pub struct CreateServerBlockParams {
|
||||
pub config_id: Uuid,
|
||||
pub server_name: Option<Vec<String>>,
|
||||
pub listen_port: i32,
|
||||
pub ssl_enabled: Option<bool>,
|
||||
pub ssl_cert_id: Option<Uuid>,
|
||||
pub override_of_id: Option<Uuid>,
|
||||
}
|
||||
|
||||
pub struct UpdateServerBlockParams {
|
||||
pub server_name: Option<Option<Vec<String>>>,
|
||||
pub listen_port: Option<i32>,
|
||||
pub ssl_enabled: Option<Option<bool>>,
|
||||
pub ssl_cert_id: Option<Option<Uuid>>,
|
||||
pub override_of_id: Option<Option<Uuid>>,
|
||||
}
|
||||
|
||||
#[async_trait::async_trait]
|
||||
pub trait ServerBlockService: Send + Sync + 'static {
|
||||
async fn get(&self, id: Uuid) -> ProxyServiceResult<ServerBlockConfig>;
|
||||
async fn list_by_config(&self, config_id: Uuid) -> ProxyServiceResult<Vec<ServerBlockConfig>>;
|
||||
async fn create(
|
||||
&self,
|
||||
params: CreateServerBlockParams,
|
||||
) -> ProxyServiceResult<ServerBlockConfig>;
|
||||
async fn update(
|
||||
&self,
|
||||
id: Uuid,
|
||||
params: UpdateServerBlockParams,
|
||||
) -> ProxyServiceResult<ServerBlockConfig>;
|
||||
async fn delete(&self, id: Uuid) -> ProxyServiceResult<bool>;
|
||||
}
|
||||
|
||||
pub(crate) struct ServerBlockServiceImpl {
|
||||
db: DatabaseConnection,
|
||||
}
|
||||
|
||||
impl ServerBlockServiceImpl {
|
||||
pub fn new(db: DatabaseConnection) -> Self {
|
||||
Self { db }
|
||||
}
|
||||
|
||||
async fn build_with_children(
|
||||
&self,
|
||||
model: crate::db::entities::server_block::Model,
|
||||
) -> ProxyServiceResult<ServerBlockConfig> {
|
||||
use crate::db::entities::{access_rule, location_block, log_setting};
|
||||
|
||||
let access_rules = access_rule::Entity::find()
|
||||
.filter(access_rule::Column::ServerId.eq(model.id))
|
||||
.all(&self.db)
|
||||
.await?
|
||||
.into_iter()
|
||||
.map(|a| OverrideRef {
|
||||
id: a.id,
|
||||
override_of_id: a.override_of_id,
|
||||
})
|
||||
.collect();
|
||||
|
||||
let location_blocks = location_block::Entity::find()
|
||||
.filter(location_block::Column::ServerId.eq(model.id))
|
||||
.all(&self.db)
|
||||
.await?
|
||||
.into_iter()
|
||||
.map(|l| OverrideRef {
|
||||
id: l.id,
|
||||
override_of_id: l.override_of_id,
|
||||
})
|
||||
.collect();
|
||||
|
||||
let log_settings = log_setting::Entity::find()
|
||||
.filter(log_setting::Column::ServerId.eq(model.id))
|
||||
.all(&self.db)
|
||||
.await?
|
||||
.into_iter()
|
||||
.map(|l| OverrideRef {
|
||||
id: l.id,
|
||||
override_of_id: l.override_of_id,
|
||||
})
|
||||
.collect();
|
||||
|
||||
let ssl_certificates = model
|
||||
.ssl_cert_id
|
||||
.map(|id| {
|
||||
vec![OverrideRef {
|
||||
id,
|
||||
override_of_id: None,
|
||||
}]
|
||||
})
|
||||
.unwrap_or_default();
|
||||
|
||||
Ok(ServerBlockConfig {
|
||||
id: model.id,
|
||||
server_name: model.server_name,
|
||||
listen_port: model.listen_port,
|
||||
ssl_enabled: model.ssl_enabled,
|
||||
override_of_id: model.override_of_id,
|
||||
access_rules,
|
||||
location_blocks,
|
||||
log_settings,
|
||||
ssl_certificates,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
#[async_trait::async_trait]
|
||||
impl ServerBlockService for ServerBlockServiceImpl {
|
||||
async fn get(&self, id: Uuid) -> ProxyServiceResult<ServerBlockConfig> {
|
||||
use crate::db::entities::server_block;
|
||||
|
||||
let model = server_block::Entity::find_by_id(id)
|
||||
.one(&self.db)
|
||||
.await?
|
||||
.ok_or(ProxyServiceError::ConfigNotFound)?;
|
||||
|
||||
self.build_with_children(model).await
|
||||
}
|
||||
|
||||
async fn list_by_config(&self, config_id: Uuid) -> ProxyServiceResult<Vec<ServerBlockConfig>> {
|
||||
use crate::db::entities::server_block;
|
||||
|
||||
let models = server_block::Entity::find()
|
||||
.filter(server_block::Column::ConfigId.eq(config_id))
|
||||
.all(&self.db)
|
||||
.await?;
|
||||
|
||||
let mut results = Vec::with_capacity(models.len());
|
||||
for m in models {
|
||||
results.push(self.build_with_children(m).await?);
|
||||
}
|
||||
Ok(results)
|
||||
}
|
||||
|
||||
async fn create(
|
||||
&self,
|
||||
params: CreateServerBlockParams,
|
||||
) -> ProxyServiceResult<ServerBlockConfig> {
|
||||
use crate::db::entities::server_block::ActiveModel;
|
||||
|
||||
let id = Uuid::new_v4();
|
||||
let model = ActiveModel {
|
||||
id: Set(id),
|
||||
config_id: Set(params.config_id),
|
||||
server_name: Set(params.server_name),
|
||||
listen_port: Set(params.listen_port),
|
||||
ssl_enabled: Set(params.ssl_enabled),
|
||||
ssl_cert_id: Set(params.ssl_cert_id),
|
||||
override_of_id: Set(params.override_of_id),
|
||||
};
|
||||
|
||||
let result = model.insert(&self.db).await?;
|
||||
self.build_with_children(result).await
|
||||
}
|
||||
|
||||
async fn update(
|
||||
&self,
|
||||
id: Uuid,
|
||||
params: UpdateServerBlockParams,
|
||||
) -> ProxyServiceResult<ServerBlockConfig> {
|
||||
use crate::db::entities::server_block::{ActiveModel, Entity as ServerBlockEntity};
|
||||
|
||||
let existing = ServerBlockEntity::find_by_id(id)
|
||||
.one(&self.db)
|
||||
.await?
|
||||
.ok_or(ProxyServiceError::ConfigNotFound)?;
|
||||
|
||||
let mut model: ActiveModel = existing.into();
|
||||
if let Some(server_name) = params.server_name {
|
||||
model.server_name = Set(server_name);
|
||||
}
|
||||
if let Some(listen_port) = params.listen_port {
|
||||
model.listen_port = Set(listen_port);
|
||||
}
|
||||
if let Some(ssl_enabled) = params.ssl_enabled {
|
||||
model.ssl_enabled = Set(ssl_enabled);
|
||||
}
|
||||
if let Some(ssl_cert_id) = params.ssl_cert_id {
|
||||
model.ssl_cert_id = Set(ssl_cert_id);
|
||||
}
|
||||
if let Some(override_of_id) = params.override_of_id {
|
||||
model.override_of_id = Set(override_of_id);
|
||||
}
|
||||
|
||||
let result = model.update(&self.db).await?;
|
||||
self.build_with_children(result).await
|
||||
}
|
||||
|
||||
async fn delete(&self, id: Uuid) -> ProxyServiceResult<bool> {
|
||||
let result = crate::db::entities::server_block::Entity::delete_by_id(id)
|
||||
.exec(&self.db)
|
||||
.await?;
|
||||
Ok(result.rows_affected > 0)
|
||||
}
|
||||
}
|
||||
122
apps/nxmesh-master/src/service/proxy/ssl_certificate/mod.rs
Normal file
122
apps/nxmesh-master/src/service/proxy/ssl_certificate/mod.rs
Normal file
@@ -0,0 +1,122 @@
|
||||
use chrono::Utc;
|
||||
use sea_orm::{ActiveModelTrait, ActiveValue::Set, DatabaseConnection, EntityTrait, prelude::*};
|
||||
use uuid::Uuid;
|
||||
|
||||
use crate::service::proxy::types::{ProxyServiceError, ProxyServiceResult, SslCertificateConfig};
|
||||
|
||||
pub struct CreateSslCertificateParams {
|
||||
pub name: String,
|
||||
pub cert_path: String,
|
||||
pub key_path: String,
|
||||
pub expiry_date: chrono::DateTime<Utc>,
|
||||
}
|
||||
|
||||
pub struct UpdateSslCertificateParams {
|
||||
pub name: Option<String>,
|
||||
pub cert_path: Option<String>,
|
||||
pub key_path: Option<String>,
|
||||
pub expiry_date: Option<chrono::DateTime<Utc>>,
|
||||
}
|
||||
|
||||
#[async_trait::async_trait]
|
||||
pub trait SslCertificateService: Send + Sync + 'static {
|
||||
async fn get(&self, id: Uuid) -> ProxyServiceResult<SslCertificateConfig>;
|
||||
async fn list(&self) -> ProxyServiceResult<Vec<SslCertificateConfig>>;
|
||||
async fn create(
|
||||
&self,
|
||||
params: CreateSslCertificateParams,
|
||||
) -> ProxyServiceResult<SslCertificateConfig>;
|
||||
async fn update(
|
||||
&self,
|
||||
id: Uuid,
|
||||
params: UpdateSslCertificateParams,
|
||||
) -> ProxyServiceResult<SslCertificateConfig>;
|
||||
async fn delete(&self, id: Uuid) -> ProxyServiceResult<bool>;
|
||||
}
|
||||
|
||||
pub(crate) struct SslCertificateServiceImpl {
|
||||
db: DatabaseConnection,
|
||||
}
|
||||
|
||||
impl SslCertificateServiceImpl {
|
||||
pub fn new(db: DatabaseConnection) -> Self {
|
||||
Self { db }
|
||||
}
|
||||
}
|
||||
|
||||
#[async_trait::async_trait]
|
||||
impl SslCertificateService for SslCertificateServiceImpl {
|
||||
async fn get(&self, id: Uuid) -> ProxyServiceResult<SslCertificateConfig> {
|
||||
use crate::db::entities::ssl_certificate;
|
||||
|
||||
let model = ssl_certificate::Entity::find_by_id(id)
|
||||
.one(&self.db)
|
||||
.await?
|
||||
.ok_or(ProxyServiceError::ConfigNotFound)?;
|
||||
|
||||
Ok(model.into())
|
||||
}
|
||||
|
||||
async fn list(&self) -> ProxyServiceResult<Vec<SslCertificateConfig>> {
|
||||
use crate::db::entities::ssl_certificate;
|
||||
|
||||
let models = ssl_certificate::Entity::find().all(&self.db).await?;
|
||||
|
||||
Ok(models.into_iter().map(Into::into).collect())
|
||||
}
|
||||
|
||||
async fn create(
|
||||
&self,
|
||||
params: CreateSslCertificateParams,
|
||||
) -> ProxyServiceResult<SslCertificateConfig> {
|
||||
use crate::db::entities::ssl_certificate::ActiveModel;
|
||||
|
||||
let model = ActiveModel {
|
||||
id: Set(Uuid::new_v4()),
|
||||
name: Set(params.name),
|
||||
cert_path: Set(params.cert_path),
|
||||
key_path: Set(params.key_path),
|
||||
expiry_date: Set(params.expiry_date.naive_utc()),
|
||||
};
|
||||
|
||||
let result = model.insert(&self.db).await?;
|
||||
Ok(result.into())
|
||||
}
|
||||
|
||||
async fn update(
|
||||
&self,
|
||||
id: Uuid,
|
||||
params: UpdateSslCertificateParams,
|
||||
) -> ProxyServiceResult<SslCertificateConfig> {
|
||||
use crate::db::entities::ssl_certificate::{ActiveModel, Entity as SslCertificateEntity};
|
||||
|
||||
let existing = SslCertificateEntity::find_by_id(id)
|
||||
.one(&self.db)
|
||||
.await?
|
||||
.ok_or(ProxyServiceError::ConfigNotFound)?;
|
||||
|
||||
let mut model: ActiveModel = existing.into();
|
||||
if let Some(name) = params.name {
|
||||
model.name = Set(name);
|
||||
}
|
||||
if let Some(cert_path) = params.cert_path {
|
||||
model.cert_path = Set(cert_path);
|
||||
}
|
||||
if let Some(key_path) = params.key_path {
|
||||
model.key_path = Set(key_path);
|
||||
}
|
||||
if let Some(expiry_date) = params.expiry_date {
|
||||
model.expiry_date = Set(expiry_date.naive_utc());
|
||||
}
|
||||
|
||||
let result = model.update(&self.db).await?;
|
||||
Ok(result.into())
|
||||
}
|
||||
|
||||
async fn delete(&self, id: Uuid) -> ProxyServiceResult<bool> {
|
||||
let result = crate::db::entities::ssl_certificate::Entity::delete_by_id(id)
|
||||
.exec(&self.db)
|
||||
.await?;
|
||||
Ok(result.rows_affected > 0)
|
||||
}
|
||||
}
|
||||
@@ -34,10 +34,8 @@ pub fn merge_override_vecs(
|
||||
mut child: Vec<OverrideRef>,
|
||||
parent: Vec<OverrideRef>,
|
||||
) -> Vec<OverrideRef> {
|
||||
let overridden_ids: std::collections::HashSet<uuid::Uuid> = child
|
||||
.iter()
|
||||
.filter_map(|r| r.override_of_id)
|
||||
.collect();
|
||||
let overridden_ids: std::collections::HashSet<uuid::Uuid> =
|
||||
child.iter().filter_map(|r| r.override_of_id).collect();
|
||||
for item in parent {
|
||||
if !overridden_ids.contains(&item.id) {
|
||||
child.push(item);
|
||||
@@ -76,7 +74,8 @@ impl Mergeable<ProxyConfig> for ProxyConfig {
|
||||
|
||||
macro_rules! merge_overridable_field {
|
||||
($field:ident) => {
|
||||
let overridden: HashSet<uuid::Uuid> = self.$field
|
||||
let overridden: HashSet<uuid::Uuid> = self
|
||||
.$field
|
||||
.values()
|
||||
.filter_map(|v| v.override_of_id())
|
||||
.collect();
|
||||
@@ -90,7 +89,8 @@ impl Mergeable<ProxyConfig> for ProxyConfig {
|
||||
|
||||
// server_blocks: merge matching entries (field-level), handle overrides
|
||||
{
|
||||
let overridden: HashSet<uuid::Uuid> = self.server_blocks
|
||||
let overridden: HashSet<uuid::Uuid> = self
|
||||
.server_blocks
|
||||
.values()
|
||||
.filter_map(|sb| sb.override_of_id)
|
||||
.collect();
|
||||
@@ -179,18 +179,14 @@ impl Mergeable<ServerBlockConfig> for ServerBlockConfig {
|
||||
self.override_of_id = other.override_of_id;
|
||||
}
|
||||
|
||||
self.access_rules = merge_override_vecs(
|
||||
std::mem::take(&mut self.access_rules),
|
||||
other.access_rules,
|
||||
);
|
||||
self.access_rules =
|
||||
merge_override_vecs(std::mem::take(&mut self.access_rules), other.access_rules);
|
||||
self.location_blocks = merge_override_vecs(
|
||||
std::mem::take(&mut self.location_blocks),
|
||||
other.location_blocks,
|
||||
);
|
||||
self.log_settings = merge_override_vecs(
|
||||
std::mem::take(&mut self.log_settings),
|
||||
other.log_settings,
|
||||
);
|
||||
self.log_settings =
|
||||
merge_override_vecs(std::mem::take(&mut self.log_settings), other.log_settings);
|
||||
self.ssl_certificates = merge_override_vecs(
|
||||
std::mem::take(&mut self.ssl_certificates),
|
||||
other.ssl_certificates,
|
||||
@@ -452,34 +448,54 @@ impl From<crate::db::entities::rewrite_rule::Model> for RewriteRuleConfig {
|
||||
// ── Overridable implementations ──
|
||||
|
||||
impl Overridable for ServerBlockConfig {
|
||||
fn override_of_id(&self) -> Option<uuid::Uuid> { self.override_of_id }
|
||||
fn override_of_id(&self) -> Option<uuid::Uuid> {
|
||||
self.override_of_id
|
||||
}
|
||||
}
|
||||
impl Overridable for UpstreamConfig {
|
||||
fn override_of_id(&self) -> Option<uuid::Uuid> { self.override_of_id }
|
||||
fn override_of_id(&self) -> Option<uuid::Uuid> {
|
||||
self.override_of_id
|
||||
}
|
||||
}
|
||||
impl Overridable for AccessRuleConfig {
|
||||
fn override_of_id(&self) -> Option<uuid::Uuid> { self.override_of_id }
|
||||
fn override_of_id(&self) -> Option<uuid::Uuid> {
|
||||
self.override_of_id
|
||||
}
|
||||
}
|
||||
impl Overridable for CacheZoneConfig {
|
||||
fn override_of_id(&self) -> Option<uuid::Uuid> { self.override_of_id }
|
||||
fn override_of_id(&self) -> Option<uuid::Uuid> {
|
||||
self.override_of_id
|
||||
}
|
||||
}
|
||||
impl Overridable for LimitRuleConfig {
|
||||
fn override_of_id(&self) -> Option<uuid::Uuid> { self.override_of_id }
|
||||
fn override_of_id(&self) -> Option<uuid::Uuid> {
|
||||
self.override_of_id
|
||||
}
|
||||
}
|
||||
impl Overridable for LimitZoneConfig {
|
||||
fn override_of_id(&self) -> Option<uuid::Uuid> { self.override_of_id }
|
||||
fn override_of_id(&self) -> Option<uuid::Uuid> {
|
||||
self.override_of_id
|
||||
}
|
||||
}
|
||||
impl Overridable for LocationBlockConfig {
|
||||
fn override_of_id(&self) -> Option<uuid::Uuid> { self.override_of_id }
|
||||
fn override_of_id(&self) -> Option<uuid::Uuid> {
|
||||
self.override_of_id
|
||||
}
|
||||
}
|
||||
impl Overridable for LogSettingConfig {
|
||||
fn override_of_id(&self) -> Option<uuid::Uuid> { self.override_of_id }
|
||||
fn override_of_id(&self) -> Option<uuid::Uuid> {
|
||||
self.override_of_id
|
||||
}
|
||||
}
|
||||
impl Overridable for ProxySettingConfig {
|
||||
fn override_of_id(&self) -> Option<uuid::Uuid> { self.override_of_id }
|
||||
fn override_of_id(&self) -> Option<uuid::Uuid> {
|
||||
self.override_of_id
|
||||
}
|
||||
}
|
||||
impl Overridable for RewriteRuleConfig {
|
||||
fn override_of_id(&self) -> Option<uuid::Uuid> { self.override_of_id }
|
||||
fn override_of_id(&self) -> Option<uuid::Uuid> {
|
||||
self.override_of_id
|
||||
}
|
||||
}
|
||||
|
||||
// ── CRUD types ──
|
||||
@@ -623,7 +639,10 @@ mod tests {
|
||||
};
|
||||
child.merge(parent);
|
||||
// child keeps its own values (self overrides other)
|
||||
assert_eq!(child.server_name, Some(vec!["child.example.com".to_string()]));
|
||||
assert_eq!(
|
||||
child.server_name,
|
||||
Some(vec!["child.example.com".to_string()])
|
||||
);
|
||||
assert_eq!(child.listen_port, 443);
|
||||
assert_eq!(child.ssl_enabled, Some(true));
|
||||
}
|
||||
@@ -655,7 +674,10 @@ mod tests {
|
||||
};
|
||||
child.merge(parent);
|
||||
// child fills missing optional fields from parent
|
||||
assert_eq!(child.server_name, Some(vec!["parent.example.com".to_string()]));
|
||||
assert_eq!(
|
||||
child.server_name,
|
||||
Some(vec!["parent.example.com".to_string()])
|
||||
);
|
||||
assert_eq!(child.listen_port, 443); // non-optional: child keeps its own
|
||||
assert_eq!(child.ssl_enabled, Some(false));
|
||||
}
|
||||
@@ -725,7 +747,10 @@ mod tests {
|
||||
child_proxy.merge(parent_proxy);
|
||||
assert_eq!(child_proxy.server_blocks.len(), 1);
|
||||
let merged_sb = &child_proxy.server_blocks[&sb_id];
|
||||
assert_eq!(merged_sb.server_name, Some(vec!["child.example.com".to_string()]));
|
||||
assert_eq!(
|
||||
merged_sb.server_name,
|
||||
Some(vec!["child.example.com".to_string()])
|
||||
);
|
||||
assert_eq!(merged_sb.listen_port, 443);
|
||||
assert_eq!(merged_sb.ssl_enabled, Some(true));
|
||||
}
|
||||
|
||||
140
apps/nxmesh-master/src/service/proxy/upstream/mod.rs
Normal file
140
apps/nxmesh-master/src/service/proxy/upstream/mod.rs
Normal file
@@ -0,0 +1,140 @@
|
||||
use sea_orm::{ActiveModelTrait, ActiveValue::Set, DatabaseConnection, EntityTrait, prelude::*};
|
||||
use uuid::Uuid;
|
||||
|
||||
use crate::service::proxy::types::{
|
||||
OverrideRef, ProxyServiceError, ProxyServiceResult, UpstreamConfig,
|
||||
};
|
||||
|
||||
pub struct CreateUpstreamParams {
|
||||
pub config_id: Uuid,
|
||||
pub name: String,
|
||||
pub target_host: String,
|
||||
pub target_port: i32,
|
||||
pub metadata: Option<serde_json::Value>,
|
||||
pub override_of_id: Option<Uuid>,
|
||||
}
|
||||
|
||||
pub struct UpdateUpstreamParams {
|
||||
pub name: Option<String>,
|
||||
pub target_host: Option<String>,
|
||||
pub target_port: Option<i32>,
|
||||
pub metadata: Option<Option<serde_json::Value>>,
|
||||
pub override_of_id: Option<Option<Uuid>>,
|
||||
}
|
||||
|
||||
fn model_to_config(model: crate::db::entities::upstream::Model) -> UpstreamConfig {
|
||||
UpstreamConfig {
|
||||
id: model.id,
|
||||
name: model.name,
|
||||
target_host: model.target_host,
|
||||
target_port: model.target_port,
|
||||
metadata: model.metadata,
|
||||
override_of_id: model.override_of_id,
|
||||
location_blocks: vec![],
|
||||
}
|
||||
}
|
||||
|
||||
#[async_trait::async_trait]
|
||||
pub trait UpstreamService: Send + Sync + 'static {
|
||||
async fn get(&self, id: Uuid) -> ProxyServiceResult<UpstreamConfig>;
|
||||
async fn list_by_config(&self, config_id: Uuid) -> ProxyServiceResult<Vec<UpstreamConfig>>;
|
||||
async fn create(&self, params: CreateUpstreamParams) -> ProxyServiceResult<UpstreamConfig>;
|
||||
async fn update(
|
||||
&self,
|
||||
id: Uuid,
|
||||
params: UpdateUpstreamParams,
|
||||
) -> ProxyServiceResult<UpstreamConfig>;
|
||||
async fn delete(&self, id: Uuid) -> ProxyServiceResult<bool>;
|
||||
}
|
||||
|
||||
pub(crate) struct UpstreamServiceImpl {
|
||||
db: DatabaseConnection,
|
||||
}
|
||||
|
||||
impl UpstreamServiceImpl {
|
||||
pub fn new(db: DatabaseConnection) -> Self {
|
||||
Self { db }
|
||||
}
|
||||
}
|
||||
|
||||
#[async_trait::async_trait]
|
||||
impl UpstreamService for UpstreamServiceImpl {
|
||||
async fn get(&self, id: Uuid) -> ProxyServiceResult<UpstreamConfig> {
|
||||
use crate::db::entities::upstream;
|
||||
|
||||
let model = upstream::Entity::find_by_id(id)
|
||||
.one(&self.db)
|
||||
.await?
|
||||
.ok_or(ProxyServiceError::ConfigNotFound)?;
|
||||
|
||||
Ok(model_to_config(model))
|
||||
}
|
||||
|
||||
async fn list_by_config(&self, config_id: Uuid) -> ProxyServiceResult<Vec<UpstreamConfig>> {
|
||||
use crate::db::entities::upstream;
|
||||
|
||||
let models = upstream::Entity::find()
|
||||
.filter(upstream::Column::ConfigId.eq(config_id))
|
||||
.all(&self.db)
|
||||
.await?;
|
||||
|
||||
Ok(models.into_iter().map(model_to_config).collect())
|
||||
}
|
||||
|
||||
async fn create(&self, params: CreateUpstreamParams) -> ProxyServiceResult<UpstreamConfig> {
|
||||
use crate::db::entities::upstream::ActiveModel;
|
||||
|
||||
let model = ActiveModel {
|
||||
id: Set(Uuid::new_v4()),
|
||||
config_id: Set(params.config_id),
|
||||
name: Set(params.name),
|
||||
target_host: Set(params.target_host),
|
||||
target_port: Set(params.target_port),
|
||||
metadata: Set(params.metadata),
|
||||
override_of_id: Set(params.override_of_id),
|
||||
};
|
||||
|
||||
let result = model.insert(&self.db).await?;
|
||||
Ok(model_to_config(result))
|
||||
}
|
||||
|
||||
async fn update(
|
||||
&self,
|
||||
id: Uuid,
|
||||
params: UpdateUpstreamParams,
|
||||
) -> ProxyServiceResult<UpstreamConfig> {
|
||||
use crate::db::entities::upstream::{ActiveModel, Entity as UpstreamEntity};
|
||||
|
||||
let existing = UpstreamEntity::find_by_id(id)
|
||||
.one(&self.db)
|
||||
.await?
|
||||
.ok_or(ProxyServiceError::ConfigNotFound)?;
|
||||
|
||||
let mut model: ActiveModel = existing.into();
|
||||
if let Some(name) = params.name {
|
||||
model.name = Set(name);
|
||||
}
|
||||
if let Some(target_host) = params.target_host {
|
||||
model.target_host = Set(target_host);
|
||||
}
|
||||
if let Some(target_port) = params.target_port {
|
||||
model.target_port = Set(target_port);
|
||||
}
|
||||
if let Some(metadata) = params.metadata {
|
||||
model.metadata = Set(metadata);
|
||||
}
|
||||
if let Some(override_of_id) = params.override_of_id {
|
||||
model.override_of_id = Set(override_of_id);
|
||||
}
|
||||
|
||||
let result = model.update(&self.db).await?;
|
||||
Ok(model_to_config(result))
|
||||
}
|
||||
|
||||
async fn delete(&self, id: Uuid) -> ProxyServiceResult<bool> {
|
||||
let result = crate::db::entities::upstream::Entity::delete_by_id(id)
|
||||
.exec(&self.db)
|
||||
.await?;
|
||||
Ok(result.rows_affected > 0)
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user