feat: implement Nginx service with upstream management and configuration generation
This commit is contained in:
226
apps/api/src/services/nginx/upstream.rs
Normal file
226
apps/api/src/services/nginx/upstream.rs
Normal file
@@ -0,0 +1,226 @@
|
||||
use std::{option, sync::Arc};
|
||||
|
||||
use sea_orm::{
|
||||
ActiveModelTrait, ColumnTrait, DatabaseConnection, DatabaseTransaction, EntityTrait,
|
||||
ModelTrait, QueryFilter, QuerySelect,
|
||||
};
|
||||
|
||||
use database::generated::entities::{upstream, upstream_target};
|
||||
|
||||
use crate::{
|
||||
errors::service_error::ServiceError,
|
||||
helpers::database::PaginationFilter,
|
||||
services::nginx::info::{
|
||||
upstream::{UpdateUpstreamInfo, UpstreamCreateInfo, UpstreamInfo},
|
||||
upstream_target::{UpdateUpstreamTargetInfo, UpstreamTargetCreateInfo, UpstreamTargetInfo},
|
||||
},
|
||||
with_conn,
|
||||
};
|
||||
|
||||
pub struct UpstreamService {
|
||||
connection: Arc<DatabaseConnection>,
|
||||
}
|
||||
|
||||
#[derive(Default)]
|
||||
pub struct GetUpstreamOptions {
|
||||
pub include_targets: bool,
|
||||
}
|
||||
|
||||
impl UpstreamService {
|
||||
pub fn new(connection: Arc<DatabaseConnection>) -> Self {
|
||||
Self { connection }
|
||||
}
|
||||
//
|
||||
//
|
||||
pub async fn create_upstream(
|
||||
&self,
|
||||
create_info: UpstreamCreateInfo,
|
||||
tx: Option<&mut DatabaseTransaction>,
|
||||
) -> Result<UpstreamInfo, ServiceError> {
|
||||
let model: upstream::ActiveModel = create_info.into();
|
||||
let r = with_conn!(&*self.connection, tx, conn, { model.insert(*conn).await? });
|
||||
Ok(r.into())
|
||||
}
|
||||
|
||||
pub async fn get_upstream(
|
||||
&self,
|
||||
upstream_id: uuid::Uuid,
|
||||
options: Option<GetUpstreamOptions>,
|
||||
tx: Option<&mut DatabaseTransaction>,
|
||||
) -> Result<UpstreamInfo, ServiceError> {
|
||||
let concrete_options = options.unwrap_or_default();
|
||||
let info: UpstreamInfo = if concrete_options.include_targets {
|
||||
let (up_model, targets) = with_conn!(&*self.connection, tx, conn, {
|
||||
let up = upstream::Entity::find_by_id(upstream_id)
|
||||
.one(*conn)
|
||||
.await?
|
||||
.ok_or(ServiceError::NotFound(format!(
|
||||
"Upstream with id {} not found",
|
||||
upstream_id
|
||||
)))?;
|
||||
let targets = upstream_target::Entity::find()
|
||||
.filter(upstream_target::Column::UpstreamId.eq(upstream_id))
|
||||
.all(*conn)
|
||||
.await?;
|
||||
(up, targets)
|
||||
});
|
||||
(up_model, targets).into()
|
||||
} else {
|
||||
with_conn!(&*self.connection, tx, conn, {
|
||||
upstream::Entity::find_by_id(upstream_id)
|
||||
.one(*conn)
|
||||
.await?
|
||||
.ok_or(ServiceError::NotFound(format!(
|
||||
"Upstream with id {} not found",
|
||||
upstream_id
|
||||
)))?
|
||||
})
|
||||
.into()
|
||||
};
|
||||
Ok(info)
|
||||
}
|
||||
|
||||
pub async fn get_upstreams(
|
||||
&self,
|
||||
pagination: Option<PaginationFilter>,
|
||||
tx: Option<&mut DatabaseTransaction>,
|
||||
) -> Result<Vec<UpstreamInfo>, ServiceError> {
|
||||
let r = with_conn!(&*self.connection, tx, conn, {
|
||||
let find_query = upstream::Entity::find();
|
||||
let find_query = if let Some(pagination) = pagination {
|
||||
let (offset, limit) = pagination.get_offset_limit();
|
||||
find_query.offset(offset).limit(limit)
|
||||
} else {
|
||||
find_query
|
||||
};
|
||||
find_query.all(*conn).await?
|
||||
});
|
||||
|
||||
Ok(r.into_iter().map(|m| m.into()).collect())
|
||||
}
|
||||
|
||||
pub async fn update_upstream(
|
||||
&self,
|
||||
id: uuid::Uuid,
|
||||
upstream: UpdateUpstreamInfo,
|
||||
tx: Option<&mut DatabaseTransaction>,
|
||||
) -> Result<UpstreamInfo, ServiceError> {
|
||||
let current_model = with_conn!(&*self.connection, tx, conn, {
|
||||
upstream::Entity::find_by_id(id)
|
||||
.one(*conn)
|
||||
.await?
|
||||
.ok_or(ServiceError::NotFound(format!(
|
||||
"Upstream with id {} not found",
|
||||
id
|
||||
)))?
|
||||
});
|
||||
let active_model = upstream.apply_to_model(current_model);
|
||||
|
||||
let r = active_model.update(&*self.connection).await?;
|
||||
Ok(r.into())
|
||||
}
|
||||
|
||||
pub async fn delete_upstream(
|
||||
&self,
|
||||
upstream_id: uuid::Uuid,
|
||||
tx: Option<&mut DatabaseTransaction>,
|
||||
) -> Result<(), ServiceError> {
|
||||
let model = with_conn!(&*self.connection, tx, conn, {
|
||||
upstream::Entity::find_by_id(upstream_id)
|
||||
.one(*conn)
|
||||
.await?
|
||||
.ok_or(ServiceError::NotFound(format!(
|
||||
"Upstream with id {} not found",
|
||||
upstream_id
|
||||
)))?
|
||||
});
|
||||
with_conn!(&*self.connection, tx, conn, {
|
||||
model.delete(*conn).await?;
|
||||
Ok(())
|
||||
})
|
||||
}
|
||||
|
||||
//
|
||||
//
|
||||
pub async fn create_upstream_target(
|
||||
&self,
|
||||
create_info: UpstreamTargetCreateInfo,
|
||||
tx: Option<&mut DatabaseTransaction>,
|
||||
) -> Result<UpstreamTargetInfo, ServiceError> {
|
||||
let model: upstream_target::ActiveModel = create_info.into();
|
||||
let r = with_conn!(&*self.connection, tx, conn, { model.insert(*conn).await? });
|
||||
Ok(r.into())
|
||||
}
|
||||
|
||||
pub async fn get_upstream_target(
|
||||
&self,
|
||||
target_id: uuid::Uuid,
|
||||
tx: Option<&mut DatabaseTransaction>,
|
||||
) -> Result<UpstreamTargetInfo, ServiceError> {
|
||||
let r = with_conn!(&*self.connection, tx, conn, {
|
||||
upstream_target::Entity::find_by_id(target_id)
|
||||
.one(*conn)
|
||||
.await?
|
||||
.ok_or(ServiceError::NotFound(format!(
|
||||
"Upstream target with id {} not found",
|
||||
target_id
|
||||
)))?
|
||||
});
|
||||
Ok(r.into())
|
||||
}
|
||||
|
||||
pub async fn get_upstream_targets_by_upstream(
|
||||
&self,
|
||||
upstream_id: uuid::Uuid,
|
||||
tx: Option<&mut DatabaseTransaction>,
|
||||
) -> Result<Vec<UpstreamTargetInfo>, ServiceError> {
|
||||
let r = with_conn!(&*self.connection, tx, conn, {
|
||||
upstream_target::Entity::find()
|
||||
.filter(upstream_target::Column::UpstreamId.eq(upstream_id))
|
||||
.all(*conn)
|
||||
.await?
|
||||
});
|
||||
Ok(r.into_iter().map(|m| m.into()).collect())
|
||||
}
|
||||
|
||||
pub async fn update_upstream_target(
|
||||
&self,
|
||||
id: uuid::Uuid,
|
||||
target: UpdateUpstreamTargetInfo,
|
||||
tx: Option<&mut DatabaseTransaction>,
|
||||
) -> Result<UpstreamTargetInfo, ServiceError> {
|
||||
let current_model = with_conn!(&*self.connection, tx, conn, {
|
||||
upstream_target::Entity::find_by_id(id)
|
||||
.one(*conn)
|
||||
.await?
|
||||
.ok_or(ServiceError::NotFound(format!(
|
||||
"Upstream target with id {} not found",
|
||||
id
|
||||
)))?
|
||||
});
|
||||
let active_model = target.apply_to_model(current_model);
|
||||
|
||||
let r = active_model.update(&*self.connection).await?;
|
||||
Ok(r.into())
|
||||
}
|
||||
|
||||
pub async fn delete_upstream_target(
|
||||
&self,
|
||||
target_id: uuid::Uuid,
|
||||
tx: Option<&mut DatabaseTransaction>,
|
||||
) -> Result<(), ServiceError> {
|
||||
let model = with_conn!(&*self.connection, tx, conn, {
|
||||
upstream_target::Entity::find_by_id(target_id)
|
||||
.one(*conn)
|
||||
.await?
|
||||
.ok_or(ServiceError::NotFound(format!(
|
||||
"Upstream target with id {} not found",
|
||||
target_id
|
||||
)))?
|
||||
});
|
||||
with_conn!(&*self.connection, tx, conn, {
|
||||
model.delete(*conn).await?;
|
||||
Ok(())
|
||||
})
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user