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:
GW_MC
2026-06-21 12:14:26 +00:00
parent 2e758c67fc
commit 7c233b5f77
15 changed files with 1833 additions and 35 deletions

View 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)
}
}