feature/upstream-service #13

Merged
GW_MC merged 43 commits from feature/upstream-service into master 2026-01-01 10:49:32 +08:00
4 changed files with 182 additions and 0 deletions
Showing only changes of commit f8b13be650 - Show all commits

View File

@@ -1,3 +1,4 @@
pub mod nginx;
pub mod user; pub mod user;
use std::sync::Arc; use std::sync::Arc;
@@ -9,6 +10,7 @@ use crate::{middlewares::require_auth::require_auth, routes::AppState};
pub fn get_restricted_router(state: Arc<AppState>) -> Router { pub fn get_restricted_router(state: Arc<AppState>) -> Router {
Router::new() Router::new()
.nest("/user", user::get_user_router(state.clone())) .nest("/user", user::get_user_router(state.clone()))
.nest("/nginx", nginx::get_nginx_router(state.clone()))
.layer(axum::middleware::from_fn_with_state( .layer(axum::middleware::from_fn_with_state(
state.clone(), state.clone(),
require_auth, require_auth,

View File

@@ -0,0 +1,11 @@
pub mod upstream;
use std::sync::Arc;
use axum::Router;
use crate::routes::AppState;
pub fn get_nginx_router(state: Arc<AppState>) -> Router {
Router::new().nest("/upstream", upstream::get_upstream_router(state.clone()))
}

View File

@@ -0,0 +1,14 @@
pub mod get_upstream;
use std::sync::Arc;
use axum::{Router, routing::get};
use crate::routes::AppState;
pub fn get_upstream_router(state: Arc<AppState>) -> Router {
Router::new()
.route("upstreams", get(get_upstream::get_upstream_list))
.route("upstreams/{upstream_id}", get(get_upstream::get_upstream))
.with_state(state)
}

View File

@@ -0,0 +1,155 @@
use std::sync::Arc;
use axum::{
Json,
extract::{Path, Query, State},
response::Result as AxumResult,
};
use chrono::{DateTime, Utc};
use serde::{Deserialize, Serialize};
use uuid::Uuid;
use crate::{
errors::service_error::ServiceError,
routes::{
AppState,
api::helper::pagination::{ExtractPagination, PaginationInfo},
},
services::nginx::upstream::GetUpstreamOptions,
};
#[derive(Serialize, Deserialize, utoipa::ToSchema)]
pub struct GetUpstreamParams {
pub include_targets: Option<bool>,
}
pub struct ConcreteGetUpstreamParams {
pub include_targets: bool,
}
impl From<GetUpstreamParams> for ConcreteGetUpstreamParams {
fn from(params: GetUpstreamParams) -> Self {
Self {
include_targets: params.include_targets.unwrap_or(false),
}
}
}
#[derive(Serialize, Deserialize, utoipa::ToSchema)]
pub struct UpstreamTargetBasicInfo {
pub id: uuid::Uuid,
pub target_host: String,
pub target_port: i64,
pub enabled: bool,
pub is_backup: bool,
pub weight: i32,
//
pub created_at: DateTime<Utc>,
pub updated_at: DateTime<Utc>,
}
impl From<crate::services::nginx::info::upstream_target::UpstreamTargetInfo>
for UpstreamTargetBasicInfo
{
fn from(info: crate::services::nginx::info::upstream_target::UpstreamTargetInfo) -> Self {
Self {
id: info.id,
target_host: info.target_host,
target_port: info.target_port,
enabled: info.enabled,
is_backup: info.is_backup,
weight: info.weight as i32,
//
created_at: info.created_at,
updated_at: info.updated_at,
}
}
}
#[derive(Serialize, Deserialize, utoipa::ToSchema)]
pub struct UpstreamInfoResponse {
pub id: uuid::Uuid,
pub name: String,
pub protocol: String,
pub algorithm: String,
pub sticky_session: bool,
pub created_by: Option<uuid::Uuid>,
pub created_at: DateTime<Utc>,
pub updated_at: DateTime<Utc>,
//
pub upstream_targets: Vec<UpstreamTargetBasicInfo>,
}
impl From<crate::services::nginx::info::upstream::UpstreamInfo> for UpstreamInfoResponse {
fn from(info: crate::services::nginx::info::upstream::UpstreamInfo) -> Self {
Self {
id: info.id,
name: info.name,
protocol: info.protocol,
algorithm: info.algorithm,
sticky_session: info.sticky_session,
created_by: info.created_by,
created_at: info.created_at,
updated_at: info.updated_at,
upstream_targets: info
.upstream_targets
.into_iter()
.map(|t| t.into())
.collect(),
}
}
}
#[derive(Serialize, Deserialize, utoipa::ToSchema)]
pub struct UpstreamListResponse {
pub items: Vec<UpstreamInfoResponse>,
pub pagination: PaginationInfo,
}
pub async fn get_upstream_list(
ExtractPagination(pagination): ExtractPagination,
State(state): State<Arc<AppState>>,
) -> AxumResult<Json<UpstreamListResponse>, ServiceError> {
let upstream_service = &state.service.nginx.get_upstream_service();
let upstreams = upstream_service
.get_upstreams(Some(pagination.clone().into()), None)
.await?;
//
Ok(Json(UpstreamListResponse {
items: upstreams.into_iter().map(|u| u.into()).collect(),
pagination: PaginationInfo {
total_items: 0,
total_pages: 0,
current_page: pagination.page,
per_page: pagination.per_page,
},
}))
}
pub async fn get_upstream(
Path(upstream_id): Path<Uuid>,
Query(params): Query<GetUpstreamParams>,
State(_state): State<Arc<AppState>>,
) -> AxumResult<Json<UpstreamInfoResponse>, ServiceError> {
let concrete_params: ConcreteGetUpstreamParams = params.into();
let upstream_service = &_state.service.nginx.get_upstream_service();
let upstream_info = if concrete_params.include_targets {
upstream_service
.get_upstream(
upstream_id,
Some(GetUpstreamOptions {
include_targets: true,
}),
None,
)
.await?
} else {
upstream_service
.get_upstream(upstream_id, None, None)
.await?
};
//
Ok(Json(upstream_info.into()))
}