From bb55e37b49744ffe90bc8f14f201de59f021957e Mon Sep 17 00:00:00 2001 From: GW_MC <72297530+GWMCwing@users.noreply.github.com> Date: Sun, 28 Dec 2025 15:15:42 +0800 Subject: [PATCH] feat: added openapi generation for agent --- Cargo.lock | 140 ++++++++++++------------- apps/agent/Cargo.toml | 1 + apps/agent/src/main.rs | 27 +++++ apps/agent/src/openapi.rs | 45 ++++++++ apps/agent/src/routes.rs | 47 ++++++++- apps/agent/swagger.json | 215 ++++++++++++++++++++++++++++++++++++++ justfile | 6 +- 7 files changed, 403 insertions(+), 78 deletions(-) create mode 100644 apps/agent/src/openapi.rs create mode 100644 apps/agent/swagger.json diff --git a/Cargo.lock b/Cargo.lock index 2aa5314..b4c3212 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -158,7 +158,7 @@ checksum = "c7c24de15d275a1ecfd47a380fb4d5ec9bfe0933f309ed5e705b775596a3574d" dependencies = [ "proc-macro2", "quote", - "syn 2.0.110", + "syn 2.0.111", ] [[package]] @@ -169,7 +169,7 @@ checksum = "9035ad2d096bed7955a320ee7e2230574d28fd3c3a0f186cbea1ff3c7eed5dbb" dependencies = [ "proc-macro2", "quote", - "syn 2.0.110", + "syn 2.0.111", ] [[package]] @@ -276,7 +276,7 @@ checksum = "604fde5e028fea851ce1d8570bbdc034bec850d157f7569d10f347d06808c05c" dependencies = [ "proc-macro2", "quote", - "syn 2.0.110", + "syn 2.0.111", ] [[package]] @@ -453,7 +453,7 @@ dependencies = [ "proc-macro-crate", "proc-macro2", "quote", - "syn 2.0.110", + "syn 2.0.111", ] [[package]] @@ -492,9 +492,9 @@ checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b" [[package]] name = "bytes" -version = "1.10.1" +version = "1.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d71b6127be86fdcfddb610f7182ac57211d4b18a3e9c82eb2d17662f2227ad6a" +checksum = "b35204fbdc0b3f4446b89fc1ac2cf84a8a68971995d0bf2e925ec7cd960f9cb3" [[package]] name = "cc" @@ -573,7 +573,7 @@ dependencies = [ "heck 0.5.0", "proc-macro2", "quote", - "syn 2.0.110", + "syn 2.0.111", ] [[package]] @@ -821,7 +821,7 @@ checksum = "f46882e17999c6cc590af592290432be3bce0428cb0d5f8b6715e4dc7b383eb3" dependencies = [ "proc-macro2", "quote", - "syn 2.0.110", + "syn 2.0.111", ] [[package]] @@ -855,7 +855,7 @@ dependencies = [ "proc-macro2", "quote", "strsim", - "syn 2.0.110", + "syn 2.0.111", ] [[package]] @@ -869,7 +869,7 @@ dependencies = [ "proc-macro2", "quote", "strsim", - "syn 2.0.110", + "syn 2.0.111", ] [[package]] @@ -880,7 +880,7 @@ checksum = "fc34b93ccb385b40dc71c6fceac4b2ad23662c7eeb248cf10d529b7e055b6ead" dependencies = [ "darling_core 0.20.11", "quote", - "syn 2.0.110", + "syn 2.0.111", ] [[package]] @@ -891,7 +891,7 @@ checksum = "d38308df82d1080de0afee5d069fa14b0326a88c14f15c5ccda35b4a6c414c81" dependencies = [ "darling_core 0.21.3", "quote", - "syn 2.0.110", + "syn 2.0.111", ] [[package]] @@ -947,7 +947,7 @@ dependencies = [ "darling 0.20.11", "proc-macro2", "quote", - "syn 2.0.110", + "syn 2.0.111", ] [[package]] @@ -957,7 +957,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ab63b0e2bf4d5928aff72e83a7dace85d7bba5fe12dcc3c5a572d78caffd3f3c" dependencies = [ "derive_builder_core", - "syn 2.0.110", + "syn 2.0.111", ] [[package]] @@ -977,7 +977,7 @@ checksum = "bda628edc44c4bb645fbe0f758797143e4e07926f7ebf4e9bdfbd3d2ce621df3" dependencies = [ "proc-macro2", "quote", - "syn 2.0.110", + "syn 2.0.111", "unicode-xid", ] @@ -1001,7 +1001,7 @@ checksum = "97369cbbc041bc366949bc74d34658d6cda5621039731c6310521892a3a20ae0" dependencies = [ "proc-macro2", "quote", - "syn 2.0.110", + "syn 2.0.111", ] [[package]] @@ -1343,7 +1343,7 @@ checksum = "162ee34ebcb7c64a8abebc059ce0fee27c2262618d7b60ed8faf72fef13c3650" dependencies = [ "proc-macro2", "quote", - "syn 2.0.110", + "syn 2.0.111", ] [[package]] @@ -1439,7 +1439,7 @@ dependencies = [ "futures-core", "futures-sink", "http", - "indexmap 2.12.0", + "indexmap 2.12.1", "slab", "tokio", "tokio-util", @@ -1474,9 +1474,9 @@ dependencies = [ [[package]] name = "hashbrown" -version = "0.16.0" +version = "0.16.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5419bdc4f6a9207fbeba6d11b604d481addf78ecd10c11ad51e76c2f6482748d" +checksum = "841d1cc9bed7f9236f321df977030373f4a4163ae1a7dbfe1a51a2c1a51d9100" [[package]] name = "hashlink" @@ -1534,12 +1534,11 @@ dependencies = [ [[package]] name = "http" -version = "1.3.1" +version = "1.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f4a85d31aea989eead29a3aaf9e1115a180df8282431156e533de47660892565" +checksum = "e3ba2a386d7f85a81f119ad7498ebe444d2e22c2af0b86b069416ace48b3311a" dependencies = [ "bytes", - "fnv", "itoa", ] @@ -1845,12 +1844,12 @@ dependencies = [ [[package]] name = "indexmap" -version = "2.12.0" +version = "2.12.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6717a8d2a5a929a1a2eb43a12812498ed141a0bcfb7e8f7844fbdbe4303bba9f" +checksum = "0ad4bb2b565bca0645f4d68c5c9af97fba094e9791da685bf83cb5f3ce74acf2" dependencies = [ "equivalent", - "hashbrown 0.16.0", + "hashbrown 0.16.1", "serde", "serde_core", ] @@ -1872,7 +1871,7 @@ checksum = "c727f80bfa4a6c6e2508d2f05b6f4bfce242030bd88ed15ae5331c5b5d30fba7" dependencies = [ "proc-macro2", "quote", - "syn 2.0.110", + "syn 2.0.111", ] [[package]] @@ -2179,7 +2178,7 @@ checksum = "ed3955f1a9c7c0c15e092f9c887db08b1fc683305fdf6eb6684f22555355e202" dependencies = [ "proc-macro2", "quote", - "syn 2.0.110", + "syn 2.0.111", ] [[package]] @@ -2258,7 +2257,7 @@ checksum = "a948666b637a0f465e8564c73e89d4dde00d72d4d473cc972f390fc3dcee7d9c" dependencies = [ "proc-macro2", "quote", - "syn 2.0.110", + "syn 2.0.111", ] [[package]] @@ -2319,7 +2318,7 @@ dependencies = [ "proc-macro2", "proc-macro2-diagnostics", "quote", - "syn 2.0.110", + "syn 2.0.111", ] [[package]] @@ -2397,7 +2396,7 @@ dependencies = [ "regex", "regex-syntax", "structmeta", - "syn 2.0.110", + "syn 2.0.111", ] [[package]] @@ -2478,7 +2477,7 @@ dependencies = [ "pest_meta", "proc-macro2", "quote", - "syn 2.0.110", + "syn 2.0.111", ] [[package]] @@ -2535,7 +2534,7 @@ checksum = "6e918e4ff8c4549eb882f14b3a4bc8c8bc93de829416eacf579f1207a8fbf861" dependencies = [ "proc-macro2", "quote", - "syn 2.0.110", + "syn 2.0.111", ] [[package]] @@ -2624,7 +2623,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "479ca8adacdd7ce8f1fb39ce9ecccbfe93a3f1344b3d0d97f20bc0196208f62b" dependencies = [ "proc-macro2", - "syn 2.0.110", + "syn 2.0.111", ] [[package]] @@ -2664,7 +2663,7 @@ dependencies = [ "proc-macro-error-attr2", "proc-macro2", "quote", - "syn 2.0.110", + "syn 2.0.111", ] [[package]] @@ -2684,7 +2683,7 @@ checksum = "af066a9c399a26e020ada66a034357a868728e72cd426f3adcd35f80d88d88c8" dependencies = [ "proc-macro2", "quote", - "syn 2.0.110", + "syn 2.0.111", "version_check", "yansi", ] @@ -2709,7 +2708,7 @@ dependencies = [ "itertools", "proc-macro2", "quote", - "syn 2.0.110", + "syn 2.0.111", ] [[package]] @@ -2847,7 +2846,7 @@ checksum = "b7186006dcb21920990093f30e3dea63b7d6e977bf1256be20c3563a5db070da" dependencies = [ "proc-macro2", "quote", - "syn 2.0.110", + "syn 2.0.111", ] [[package]] @@ -3146,7 +3145,7 @@ dependencies = [ "proc-macro-error2", "proc-macro2", "quote", - "syn 2.0.110", + "syn 2.0.111", ] [[package]] @@ -3214,7 +3213,7 @@ dependencies = [ "proc-macro2", "quote", "sea-query", - "syn 2.0.110", + "syn 2.0.111", "tracing", ] @@ -3228,7 +3227,7 @@ dependencies = [ "proc-macro2", "quote", "sea-bae", - "syn 2.0.110", + "syn 2.0.111", "unicode-ident", ] @@ -3275,7 +3274,7 @@ dependencies = [ "heck 0.4.1", "proc-macro2", "quote", - "syn 2.0.110", + "syn 2.0.111", "thiserror", ] @@ -3317,7 +3316,7 @@ dependencies = [ "heck 0.4.1", "proc-macro2", "quote", - "syn 2.0.110", + "syn 2.0.111", ] [[package]] @@ -3421,7 +3420,7 @@ checksum = "d540f220d3187173da220f885ab66608367b6574e925011a9353e4badda91d79" dependencies = [ "proc-macro2", "quote", - "syn 2.0.110", + "syn 2.0.111", ] [[package]] @@ -3456,7 +3455,7 @@ checksum = "175ee3e80ae9982737ca543e96133087cbd9a485eecc3bc4de9c1a37b47ea59c" dependencies = [ "proc-macro2", "quote", - "syn 2.0.110", + "syn 2.0.111", ] [[package]] @@ -3490,7 +3489,7 @@ dependencies = [ "chrono", "hex", "indexmap 1.9.3", - "indexmap 2.12.0", + "indexmap 2.12.1", "schemars 0.9.0", "schemars 1.1.0", "serde_core", @@ -3508,7 +3507,7 @@ dependencies = [ "darling 0.21.3", "proc-macro2", "quote", - "syn 2.0.110", + "syn 2.0.111", ] [[package]] @@ -3672,7 +3671,7 @@ dependencies = [ "futures-util", "hashbrown 0.15.5", "hashlink", - "indexmap 2.12.0", + "indexmap 2.12.1", "log", "memchr", "native-tls", @@ -3704,7 +3703,7 @@ dependencies = [ "quote", "sqlx-core", "sqlx-macros-core", - "syn 2.0.110", + "syn 2.0.111", ] [[package]] @@ -3727,7 +3726,7 @@ dependencies = [ "sqlx-mysql", "sqlx-postgres", "sqlx-sqlite", - "syn 2.0.110", + "syn 2.0.111", "tokio", "url", ] @@ -3887,7 +3886,7 @@ dependencies = [ "proc-macro2", "quote", "structmeta-derive", - "syn 2.0.110", + "syn 2.0.111", ] [[package]] @@ -3898,7 +3897,7 @@ checksum = "152a0b65a590ff6c3da95cabe2353ee04e6167c896b28e3b14478c2636c922fc" dependencies = [ "proc-macro2", "quote", - "syn 2.0.110", + "syn 2.0.111", ] [[package]] @@ -3919,7 +3918,7 @@ dependencies = [ "heck 0.5.0", "proc-macro2", "quote", - "syn 2.0.110", + "syn 2.0.111", ] [[package]] @@ -3941,9 +3940,9 @@ dependencies = [ [[package]] name = "syn" -version = "2.0.110" +version = "2.0.111" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a99801b5bd34ede4cf3fc688c5919368fea4e4814a4664359503e6015b280aea" +checksum = "390cc9a294ab71bdb1aa2e99d13be9c753cd2d7bd6560c77118597410c4d2e87" dependencies = [ "proc-macro2", "quote", @@ -3964,7 +3963,7 @@ checksum = "728a70f3dbaf5bab7f0c4b1ac8d7ae5ea60a4b5549c8a5914361c99147a709d2" dependencies = [ "proc-macro2", "quote", - "syn 2.0.110", + "syn 2.0.111", ] [[package]] @@ -4033,7 +4032,7 @@ checksum = "3ff15c8ecd7de3849db632e14d18d2571fa09dfc5ed93479bc4485c7a517c913" dependencies = [ "proc-macro2", "quote", - "syn 2.0.110", + "syn 2.0.111", ] [[package]] @@ -4152,7 +4151,7 @@ checksum = "af407857209536a95c8e56f8231ef2c2e2aff839b22e07a1ffcbc617e9db9fa5" dependencies = [ "proc-macro2", "quote", - "syn 2.0.110", + "syn 2.0.111", ] [[package]] @@ -4217,7 +4216,7 @@ version = "0.23.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6485ef6d0d9b5d0ec17244ff7eb05310113c3f316f2d14200d4de56b3cb98f8d" dependencies = [ - "indexmap 2.12.0", + "indexmap 2.12.1", "toml_datetime", "toml_parser", "winnow", @@ -4280,7 +4279,7 @@ checksum = "d039ad9159c98b70ecfd540b2573b97f7f52c3e8d9f8ad57a24b916a536975f9" dependencies = [ "futures-core", "futures-util", - "indexmap 2.12.0", + "indexmap 2.12.1", "pin-project-lite", "slab", "sync_wrapper", @@ -4337,7 +4336,7 @@ checksum = "81383ab64e72a7a8b8e13130c49e3dab29def6d0c7d76a03087b3cf71c5c6903" dependencies = [ "proc-macro2", "quote", - "syn 2.0.110", + "syn 2.0.111", ] [[package]] @@ -4533,7 +4532,7 @@ version = "5.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2fcc29c80c21c31608227e0912b2d7fddba57ad76b606890627ba8ee7964e993" dependencies = [ - "indexmap 2.12.0", + "indexmap 2.12.1", "serde", "serde_json", "utoipa-gen", @@ -4548,7 +4547,7 @@ dependencies = [ "proc-macro2", "quote", "regex", - "syn 2.0.110", + "syn 2.0.111", "uuid", ] @@ -4645,7 +4644,7 @@ dependencies = [ "bumpalo", "proc-macro2", "quote", - "syn 2.0.110", + "syn 2.0.111", "wasm-bindgen-shared", ] @@ -4739,7 +4738,7 @@ checksum = "053e2e040ab57b9dc951b72c264860db7eb3b0200ba345b4e4c3b14f67855ddf" dependencies = [ "proc-macro2", "quote", - "syn 2.0.110", + "syn 2.0.111", ] [[package]] @@ -4750,7 +4749,7 @@ checksum = "3f316c4a2570ba26bbec722032c4099d8c8bc095efccdc15688708623367e358" dependencies = [ "proc-macro2", "quote", - "syn 2.0.110", + "syn 2.0.111", ] [[package]] @@ -5072,6 +5071,7 @@ dependencies = [ "tokio-cron-scheduler", "tracing", "tracing-subscriber", + "utoipa", ] [[package]] @@ -5128,7 +5128,7 @@ checksum = "b659052874eb698efe5b9e8cf382204678a0086ebf46982b79d6ca3182927e5d" dependencies = [ "proc-macro2", "quote", - "syn 2.0.110", + "syn 2.0.111", "synstructure", ] @@ -5149,7 +5149,7 @@ checksum = "88d2b8d9c68ad2b9e4340d7832716a4d21a22a1154777ad56ea55c51a9cf3831" dependencies = [ "proc-macro2", "quote", - "syn 2.0.110", + "syn 2.0.111", ] [[package]] @@ -5169,7 +5169,7 @@ checksum = "d71e5d6e06ab090c67b5e44993ec16b72dcbaabc526db883a360057678b48502" dependencies = [ "proc-macro2", "quote", - "syn 2.0.110", + "syn 2.0.111", "synstructure", ] @@ -5209,5 +5209,5 @@ checksum = "eadce39539ca5cb3985590102671f2567e659fca9666581ad3411d59207951f3" dependencies = [ "proc-macro2", "quote", - "syn 2.0.110", + "syn 2.0.111", ] diff --git a/apps/agent/Cargo.toml b/apps/agent/Cargo.toml index 698c357..2153cbc 100644 --- a/apps/agent/Cargo.toml +++ b/apps/agent/Cargo.toml @@ -13,3 +13,4 @@ serde = { version = "1.0.228", features = ["std", "derive"] } tokio-cron-scheduler = { version = "0.15.1", features = ["signal"] } clap = { version = "4", features = ["derive", "env"] } nix = { version = "0.30.1", features = ["user", "fs"] } +utoipa = { version = "5.4.0", features = ["macros", "axum_extras", "chrono", "decimal", "uuid", "time", "openapi_extensions"] } diff --git a/apps/agent/src/main.rs b/apps/agent/src/main.rs index 149ec53..ced0a2d 100644 --- a/apps/agent/src/main.rs +++ b/apps/agent/src/main.rs @@ -1,6 +1,7 @@ #![forbid(unsafe_code)] mod commands; +mod openapi; mod routes; use axum::routing::get; @@ -13,6 +14,7 @@ use tokio::net::UnixListener; use tracing::{error, info, warn}; use crate::commands::NginxService; +use crate::openapi::{GenerateOpenapiArgs, generate_openapi_doc}; use crate::routes::{status, validate, validate_and_reload, write_config}; const SOCK_ENV: &str = "YANPM_AGENT_SOCK"; @@ -43,6 +45,19 @@ struct Args { /// GID to set on the unix socket, default: current user's primary group #[arg(long, default_value_t = String::from(SOCK_GID_DEFAULT), env = SOCK_GID_ENV)] sock_gid: String, + + #[command(subcommand)] + command: Option, +} + +#[derive(clap::Subcommand, Debug)] +pub enum SubCommand { + /// Generate OpenAPI spec to file or stdout + GenerateOpenapi { + /// Output file path. + #[arg(short = 'o', long)] + output: String, + }, } #[tokio::main] @@ -59,6 +74,18 @@ async fn main() -> Result<(), Box> { let args = Args::parse(); + if let Some(cmd) = &args.command { + match cmd { + SubCommand::GenerateOpenapi { output } => { + generate_openapi_doc(&GenerateOpenapiArgs { + output: output.clone(), + }) + .await?; + return Ok(()); + } + } + } + let (sock, nginx_config_dir, sock_perm, sock_gid) = get_args(&args).await?; let path = PathBuf::from(&sock); diff --git a/apps/agent/src/openapi.rs b/apps/agent/src/openapi.rs new file mode 100644 index 0000000..e52cb40 --- /dev/null +++ b/apps/agent/src/openapi.rs @@ -0,0 +1,45 @@ +use tracing::info; +use utoipa::OpenApi; + +pub mod tag { + /// nginx + pub const NGINX_TAG: &str = "Nginx Agent"; +} + +#[derive(utoipa::OpenApi)] +#[openapi( + paths( + crate::routes::status, + crate::routes::validate, + crate::routes::validate_and_reload, + crate::routes::write_config, + ), + components( + schemas(crate::routes::StatusResp), + schemas(crate::routes::ValidateAndReloadResp), + schemas(crate::routes::ValidateBody), + schemas(crate::routes::WriteConfigBody), + schemas(crate::routes::ValidateAndReloadBody), + ), + tags( + (name = tag::NGINX_TAG, description = "Nginx Agent API"), + ) +)] +struct ApiDoc; + +pub struct GenerateOpenapiArgs { + pub output: String, +} + +pub async fn generate_openapi_doc( + args: &GenerateOpenapiArgs, +) -> Result<(), Box> { + info!("Generating OpenAPI documentation..."); + let doc = ApiDoc::openapi(); + let json = doc + .to_pretty_json() + .expect("Failed to serialize OpenAPI doc to JSON"); + std::fs::write(&args.output, json).expect("Failed to write OpenAPI doc to file"); + info!("OpenAPI documentation generated at {}", args.output); + Ok(()) +} diff --git a/apps/agent/src/routes.rs b/apps/agent/src/routes.rs index 2577b1b..ee6ff46 100644 --- a/apps/agent/src/routes.rs +++ b/apps/agent/src/routes.rs @@ -9,28 +9,46 @@ use tracing::warn; use crate::commands::NginxService; -#[derive(Serialize)] +#[derive(Serialize, utoipa::ToSchema)] pub struct StatusResp { pub ok: bool, } +/// Health check endpoint +#[utoipa::path( + get, + path = "/status", + responses( + (status = 200, description = "Status response", body = StatusResp) + ), + tag = crate::openapi::tag::NGINX_TAG +)] pub async fn status() -> impl IntoResponse { let resp = StatusResp { ok: true }; (axum::http::StatusCode::OK, axum::Json(resp)) } -#[derive(Serialize)] +#[derive(Serialize, utoipa::ToSchema)] pub struct ValidateAndReloadResp { pub rc: i32, pub ro: String, } -#[derive(Deserialize)] +#[derive(Deserialize, utoipa::ToSchema)] pub struct ValidateBody { config_name: String, timestamp: u64, } +#[utoipa::path( + post, + path = "/validate", + request_body = ValidateBody, + responses( + (status = 200, description = "Validation response", body = serde_json::Value) + ), + tag = crate::openapi::tag::NGINX_TAG +)] pub async fn validate( State(nginx_controller): State>, Json(payload): Json, @@ -57,12 +75,21 @@ pub async fn validate( (axum::http::StatusCode::OK, axum::Json(resp)).into_response() } -#[derive(Deserialize)] +#[derive(Deserialize, utoipa::ToSchema)] pub struct ValidateAndReloadBody { config_name: String, timestamp: u64, } +#[utoipa::path( + post, + path = "/validate_and_reload", + request_body = ValidateAndReloadBody, + responses( + (status = 200, description = "Validate and reload response", body = ValidateAndReloadResp) + ), + tag = crate::openapi::tag::NGINX_TAG +)] pub async fn validate_and_reload( State(nginx_controller): State>, Json(payload): Json, @@ -96,13 +123,23 @@ pub async fn validate_and_reload( (axum::http::StatusCode::OK, axum::Json(resp)).into_response() } -#[derive(Deserialize)] +#[derive(Deserialize, utoipa::ToSchema)] pub struct WriteConfigBody { config_name: String, timestamp: u64, content: String, } +#[utoipa::path( + post, + path = "/write_config", + request_body = WriteConfigBody, + responses( + (status = 200, description = "Write config response"), + (status = 500, description = "Internal server error", body = serde_json::Value) + ), + tag = crate::openapi::tag::NGINX_TAG +)] pub async fn write_config( State(nginx_controller): State>, Json(payload): Json, diff --git a/apps/agent/swagger.json b/apps/agent/swagger.json new file mode 100644 index 0000000..44a1412 --- /dev/null +++ b/apps/agent/swagger.json @@ -0,0 +1,215 @@ +{ + "openapi": "3.1.0", + "info": { + "title": "yanpm-agent", + "description": "", + "license": { + "name": "" + }, + "version": "0.1.0" + }, + "paths": { + "/status": { + "get": { + "tags": [ + "Nginx Agent" + ], + "summary": "Health check endpoint", + "operationId": "status", + "responses": { + "200": { + "description": "Status response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/StatusResp" + } + } + } + } + } + } + }, + "/validate": { + "post": { + "tags": [ + "Nginx Agent" + ], + "operationId": "validate", + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ValidateBody" + } + } + }, + "required": true + }, + "responses": { + "200": { + "description": "Validation response", + "content": { + "application/json": { + "schema": {} + } + } + } + } + } + }, + "/validate_and_reload": { + "post": { + "tags": [ + "Nginx Agent" + ], + "operationId": "validate_and_reload", + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ValidateAndReloadBody" + } + } + }, + "required": true + }, + "responses": { + "200": { + "description": "Validate and reload response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ValidateAndReloadResp" + } + } + } + } + } + } + }, + "/write_config": { + "post": { + "tags": [ + "Nginx Agent" + ], + "operationId": "write_config", + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/WriteConfigBody" + } + } + }, + "required": true + }, + "responses": { + "200": { + "description": "Write config response" + }, + "500": { + "description": "Internal server error", + "content": { + "application/json": { + "schema": {} + } + } + } + } + } + } + }, + "components": { + "schemas": { + "StatusResp": { + "type": "object", + "required": [ + "ok" + ], + "properties": { + "ok": { + "type": "boolean" + } + } + }, + "ValidateAndReloadBody": { + "type": "object", + "required": [ + "config_name", + "timestamp" + ], + "properties": { + "config_name": { + "type": "string" + }, + "timestamp": { + "type": "integer", + "format": "int64", + "minimum": 0 + } + } + }, + "ValidateAndReloadResp": { + "type": "object", + "required": [ + "rc", + "ro" + ], + "properties": { + "rc": { + "type": "integer", + "format": "int32" + }, + "ro": { + "type": "string" + } + } + }, + "ValidateBody": { + "type": "object", + "required": [ + "config_name", + "timestamp" + ], + "properties": { + "config_name": { + "type": "string" + }, + "timestamp": { + "type": "integer", + "format": "int64", + "minimum": 0 + } + } + }, + "WriteConfigBody": { + "type": "object", + "required": [ + "config_name", + "timestamp", + "content" + ], + "properties": { + "config_name": { + "type": "string" + }, + "content": { + "type": "string" + }, + "timestamp": { + "type": "integer", + "format": "int64", + "minimum": 0 + } + } + } + } + }, + "tags": [ + { + "name": "Nginx Agent", + "description": "Nginx Agent API" + } + ] +} \ No newline at end of file diff --git a/justfile b/justfile index a27a0e4..f60cd82 100644 --- a/justfile +++ b/justfile @@ -50,9 +50,9 @@ generate-openapi: # Generate API client for frontend cd apps/frontend && \ pnpm generate:openapi - - -generate-all: generate-entity generate-openapi + # Generate API client for agent + cd apps/agent && \ + cargo run -- generate-openapi --output swagger.json build-frontend: # build frontend assets