- Add /api routes for agents and proxy resources - Wire all services into ApiState in service/mod.rs - Update route tests with all mock services
165 lines
4.6 KiB
Rust
165 lines
4.6 KiB
Rust
use std::sync::Arc;
|
|
|
|
use axum::{
|
|
Json,
|
|
extract::{Path, State},
|
|
http::StatusCode,
|
|
response::IntoResponse,
|
|
};
|
|
use serde::{Deserialize, Serialize};
|
|
use uuid::Uuid;
|
|
|
|
use crate::routes::api::{AppError, ApiRouter};
|
|
use crate::service::proxy::access_rule::{
|
|
AccessRuleService, CreateAccessRuleParams, UpdateAccessRuleParams,
|
|
};
|
|
use crate::service::proxy::types::AccessRuleConfig;
|
|
|
|
#[derive(Serialize)]
|
|
pub(crate) struct AccessRuleResponse {
|
|
pub id: Uuid,
|
|
pub r#type: String,
|
|
pub ip_cidr: String,
|
|
pub description: Option<String>,
|
|
pub priority: i32,
|
|
pub override_of_id: Option<Uuid>,
|
|
}
|
|
|
|
impl From<AccessRuleConfig> for AccessRuleResponse {
|
|
fn from(c: AccessRuleConfig) -> Self {
|
|
Self {
|
|
id: c.id,
|
|
r#type: c.r#type,
|
|
ip_cidr: c.ip_cidr,
|
|
description: c.description,
|
|
priority: c.priority,
|
|
override_of_id: c.override_of_id,
|
|
}
|
|
}
|
|
}
|
|
|
|
#[derive(Deserialize)]
|
|
pub(crate) struct CreateAccessRuleRequest {
|
|
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>,
|
|
}
|
|
|
|
impl From<CreateAccessRuleRequest> for CreateAccessRuleParams {
|
|
fn from(r: CreateAccessRuleRequest) -> Self {
|
|
Self {
|
|
server_id: r.server_id,
|
|
location_id: r.location_id,
|
|
r#type: r.r#type,
|
|
ip_cidr: r.ip_cidr,
|
|
description: r.description,
|
|
priority: r.priority,
|
|
override_of_id: r.override_of_id,
|
|
}
|
|
}
|
|
}
|
|
|
|
#[derive(Deserialize)]
|
|
pub(crate) struct UpdateAccessRuleRequest {
|
|
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>>,
|
|
}
|
|
|
|
impl From<UpdateAccessRuleRequest> for UpdateAccessRuleParams {
|
|
fn from(r: UpdateAccessRuleRequest) -> Self {
|
|
Self {
|
|
server_id: r.server_id,
|
|
location_id: r.location_id,
|
|
r#type: r.r#type,
|
|
ip_cidr: r.ip_cidr,
|
|
description: r.description,
|
|
priority: r.priority,
|
|
override_of_id: r.override_of_id,
|
|
}
|
|
}
|
|
}
|
|
|
|
async fn list_access_rules_by_server(
|
|
State(svc): State<Arc<dyn AccessRuleService>>,
|
|
Path(server_id): Path<Uuid>,
|
|
) -> Result<Json<Vec<AccessRuleResponse>>, AppError> {
|
|
let rules = svc.list_by_server(server_id).await?;
|
|
Ok(Json(rules.into_iter().map(Into::into).collect()))
|
|
}
|
|
|
|
async fn list_access_rules_by_location(
|
|
State(svc): State<Arc<dyn AccessRuleService>>,
|
|
Path(location_id): Path<Uuid>,
|
|
) -> Result<Json<Vec<AccessRuleResponse>>, AppError> {
|
|
let rules = svc.list_by_location(location_id).await?;
|
|
Ok(Json(rules.into_iter().map(Into::into).collect()))
|
|
}
|
|
|
|
async fn create_access_rule(
|
|
State(svc): State<Arc<dyn AccessRuleService>>,
|
|
Json(body): Json<CreateAccessRuleRequest>,
|
|
) -> Result<impl IntoResponse, AppError> {
|
|
let rule = svc.create(body.into()).await?;
|
|
Ok((StatusCode::CREATED, Json(AccessRuleResponse::from(rule))))
|
|
}
|
|
|
|
async fn get_access_rule(
|
|
State(svc): State<Arc<dyn AccessRuleService>>,
|
|
Path(id): Path<Uuid>,
|
|
) -> Result<Json<AccessRuleResponse>, AppError> {
|
|
let rule = svc.get(id).await?;
|
|
Ok(Json(rule.into()))
|
|
}
|
|
|
|
async fn update_access_rule(
|
|
State(svc): State<Arc<dyn AccessRuleService>>,
|
|
Path(id): Path<Uuid>,
|
|
Json(body): Json<UpdateAccessRuleRequest>,
|
|
) -> Result<Json<AccessRuleResponse>, AppError> {
|
|
let rule = svc.update(id, body.into()).await?;
|
|
Ok(Json(rule.into()))
|
|
}
|
|
|
|
async fn delete_access_rule(
|
|
State(svc): State<Arc<dyn AccessRuleService>>,
|
|
Path(id): Path<Uuid>,
|
|
) -> Result<impl IntoResponse, AppError> {
|
|
let deleted = svc.delete(id).await?;
|
|
if deleted {
|
|
Ok((StatusCode::NO_CONTENT,))
|
|
} else {
|
|
Err(AppError::NotFound)
|
|
}
|
|
}
|
|
|
|
pub(super) fn routes() -> ApiRouter {
|
|
ApiRouter::new()
|
|
.route(
|
|
"/server-blocks/{server_id}/access-rules",
|
|
axum::routing::get(list_access_rules_by_server),
|
|
)
|
|
.route(
|
|
"/locations/{location_id}/access-rules",
|
|
axum::routing::get(list_access_rules_by_location),
|
|
)
|
|
.route(
|
|
"/access-rules",
|
|
axum::routing::post(create_access_rule),
|
|
)
|
|
.route(
|
|
"/access-rules/{id}",
|
|
axum::routing::get(get_access_rule)
|
|
.put(update_access_rule)
|
|
.delete(delete_access_rule),
|
|
)
|
|
}
|