diff options
27 files changed, 491 insertions, 101 deletions
diff --git a/.sqlx/query-27de60282a980d2f107066d7743c845e998bf059c6962a4da64cd12c37ea33c9.json b/.sqlx/query-27de60282a980d2f107066d7743c845e998bf059c6962a4da64cd12c37ea33c9.json new file mode 100644 index 0000000..cacaaba --- /dev/null +++ b/.sqlx/query-27de60282a980d2f107066d7743c845e998bf059c6962a4da64cd12c37ea33c9.json @@ -0,0 +1,15 @@ +{ + "db_name": "PostgreSQL", + "query": "insert into rule (uuid, configuration) values ($1, $2)", + "describe": { + "columns": [], + "parameters": { + "Left": [ + "Uuid", + "Jsonb" + ] + }, + "nullable": [] + }, + "hash": "27de60282a980d2f107066d7743c845e998bf059c6962a4da64cd12c37ea33c9" +} diff --git a/.sqlx/query-7b3c6c6cb69c31aa97840c9aec48b72055275ad524568a9578f5cabb76101e82.json b/.sqlx/query-7b3c6c6cb69c31aa97840c9aec48b72055275ad524568a9578f5cabb76101e82.json new file mode 100644 index 0000000..16d8178 --- /dev/null +++ b/.sqlx/query-7b3c6c6cb69c31aa97840c9aec48b72055275ad524568a9578f5cabb76101e82.json @@ -0,0 +1,16 @@ +{ + "db_name": "PostgreSQL", + "query": "\n update rule\n set configuration = $1\n where id = $2 and version = $3\n ", + "describe": { + "columns": [], + "parameters": { + "Left": [ + "Jsonb", + "Text", + "Text" + ] + }, + "nullable": [] + }, + "hash": "7b3c6c6cb69c31aa97840c9aec48b72055275ad524568a9578f5cabb76101e82" +} diff --git a/.sqlx/query-7cff078d0d3b77228a5f4b407e56d09cdb28ed976721da2c943e78cfbf361fb9.json b/.sqlx/query-7cff078d0d3b77228a5f4b407e56d09cdb28ed976721da2c943e78cfbf361fb9.json new file mode 100644 index 0000000..7ecea18 --- /dev/null +++ b/.sqlx/query-7cff078d0d3b77228a5f4b407e56d09cdb28ed976721da2c943e78cfbf361fb9.json @@ -0,0 +1,41 @@ +{ + "db_name": "PostgreSQL", + "query": "\n delete from rule\n where id = $1 and version = $2\n returning id, uuid, version, configuration as \"configuration: sqlx::types::Json<RuleConfiguration>\"\n ", + "describe": { + "columns": [ + { + "ordinal": 0, + "name": "id", + "type_info": "Text" + }, + { + "ordinal": 1, + "name": "uuid", + "type_info": "Uuid" + }, + { + "ordinal": 2, + "name": "version", + "type_info": "Text" + }, + { + "ordinal": 3, + "name": "configuration: sqlx::types::Json<RuleConfiguration>", + "type_info": "Jsonb" + } + ], + "parameters": { + "Left": [ + "Text", + "Text" + ] + }, + "nullable": [ + true, + false, + true, + false + ] + }, + "hash": "7cff078d0d3b77228a5f4b407e56d09cdb28ed976721da2c943e78cfbf361fb9" +} diff --git a/.sqlx/query-a853983577557f990db0631812e477619d05d6efe6990e3b62569037d4a22192.json b/.sqlx/query-a853983577557f990db0631812e477619d05d6efe6990e3b62569037d4a22192.json new file mode 100644 index 0000000..23d3c4f --- /dev/null +++ b/.sqlx/query-a853983577557f990db0631812e477619d05d6efe6990e3b62569037d4a22192.json @@ -0,0 +1,41 @@ +{ + "db_name": "PostgreSQL", + "query": "select uuid, version, id, configuration as \"configuration: sqlx::types::Json<RuleConfiguration>\" from rule where\n id = $1 and version = $2", + "describe": { + "columns": [ + { + "ordinal": 0, + "name": "uuid", + "type_info": "Uuid" + }, + { + "ordinal": 1, + "name": "version", + "type_info": "Text" + }, + { + "ordinal": 2, + "name": "id", + "type_info": "Text" + }, + { + "ordinal": 3, + "name": "configuration: sqlx::types::Json<RuleConfiguration>", + "type_info": "Jsonb" + } + ], + "parameters": { + "Left": [ + "Text", + "Text" + ] + }, + "nullable": [ + false, + true, + true, + false + ] + }, + "hash": "a853983577557f990db0631812e477619d05d6efe6990e3b62569037d4a22192" +} @@ -96,9 +96,9 @@ dependencies = [ [[package]] name = "anyhow" -version = "1.0.98" +version = "1.0.99" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e16d2d3311acee920a9eb8d33b8cbc1787ce4a264e85f964c2404b969bdcd487" +checksum = "b0674a1ddeecb70197781e945de4b3b8ffb61fa939a5597bcf48503737663100" [[package]] name = "arbitrary" @@ -337,9 +337,9 @@ dependencies = [ [[package]] name = "bon" -version = "3.6.5" +version = "3.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "33d9ef19ae5263a138da9a86871eca537478ab0332a7770bac7e3f08b801f89f" +checksum = "67a0c21249ad725ebcadcb1b1885f8e3d56e8e6b8924f560268aab000982d637" dependencies = [ "bon-macros", "rustversion", @@ -347,9 +347,9 @@ dependencies = [ [[package]] name = "bon-macros" -version = "3.6.5" +version = "3.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "577ae008f2ca11ca7641bd44601002ee5ab49ef0af64846ce1ab6057218a5cc1" +checksum = "a660ebdea4d4d3ec7788cfc9c035b66efb66028b9b97bf6cde7023ccc8e77e28" dependencies = [ "darling", "ident_case", @@ -404,9 +404,9 @@ checksum = "613afe47fcd5fac7ccf1db93babcb082c5994d996f20b8b159f2ad1658eb5724" [[package]] name = "clap" -version = "4.5.43" +version = "4.5.45" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "50fd97c9dc2399518aa331917ac6f274280ec5eb34e555dd291899745c48ec6f" +checksum = "1fc0e74a703892159f5ae7d3aac52c8e6c392f5ae5f359c70b5881d60aaac318" dependencies = [ "clap_builder", "clap_derive", @@ -414,9 +414,9 @@ dependencies = [ [[package]] name = "clap_builder" -version = "4.5.43" +version = "4.5.44" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c35b5830294e1fa0462034af85cc95225a4cb07092c088c55bda3147cfcd8f65" +checksum = "b3e7f4214277f3c7aa526a59dd3fbe306a370daee1f8b7b8c987069cd8e888a8" dependencies = [ "anstream", "anstyle", @@ -426,9 +426,9 @@ dependencies = [ [[package]] name = "clap_derive" -version = "4.5.41" +version = "4.5.45" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ef4f52386a59ca4c860f7393bcf8abd8dfd91ecccc0f774635ff68e92eeef491" +checksum = "14cb31bb0a7d536caef2639baa7fad459e15c3144efefa6dbd1c84562c4739f6" dependencies = [ "heck", "proc-macro2", @@ -473,9 +473,9 @@ dependencies = [ [[package]] name = "config" -version = "0.15.13" +version = "0.15.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5b1eb4fb07bc7f012422df02766c7bd5971effb894f573865642f06fa3265440" +checksum = "aa4092bf3922a966e2bd74640b80f36c73eaa7251a4fd0fbcda1f8a4de401352" dependencies = [ "convert_case", "pathdiff", @@ -1413,9 +1413,9 @@ dependencies = [ [[package]] name = "libc" -version = "0.2.174" +version = "0.2.175" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1171693293099992e19cddea4e8b849964e9846f4acee11b3948bcc337be8776" +checksum = "6a82ae493e598baaea5209805c49bbf2ea7de956d50d7da0da1164f9c6d28543" [[package]] name = "libm" @@ -1424,6 +1424,17 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f9fbbcab51052fe104eb5e5d351cf728d30a5be1fe14d9be8a3b097481fb97de" [[package]] +name = "libredox" +version = "0.1.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "391290121bad3d37fbddad76d8f5d1c1c314cfc646d143d7e07a3086ddff0ce3" +dependencies = [ + "bitflags", + "libc", + "redox_syscall", +] + +[[package]] name = "libsqlite3-sys" version = "0.30.1" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -1551,7 +1562,7 @@ dependencies = [ "metrics", "metrics-util", "quanta", - "thiserror 2.0.12", + "thiserror 2.0.14", ] [[package]] @@ -1768,7 +1779,7 @@ dependencies = [ "futures-sink", "js-sys", "pin-project-lite", - "thiserror 2.0.12", + "thiserror 2.0.14", "tracing", ] @@ -1796,7 +1807,7 @@ dependencies = [ "opentelemetry-proto", "opentelemetry_sdk", "prost 0.13.5", - "thiserror 2.0.12", + "thiserror 2.0.14", "tokio", "tonic 0.13.1", ] @@ -1831,7 +1842,7 @@ dependencies = [ "opentelemetry", "percent-encoding", "rand 0.9.2", - "thiserror 2.0.12", + "thiserror 2.0.14", "tokio", "tokio-stream", ] @@ -2009,9 +2020,9 @@ dependencies = [ [[package]] name = "proc-macro2" -version = "1.0.95" +version = "1.0.97" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "02b3e5e68a3a1a02aad3ec490a98007cbc13c37cbe84a3cd7b8e406d76e7f778" +checksum = "d61789d7719defeb74ea5fe81f2fdfdbd28a803847077cecce2ff14e1472f6f1" dependencies = [ "unicode-ident", ] @@ -2151,7 +2162,7 @@ dependencies = [ "rustc-hash", "rustls", "socket2 0.5.10", - "thiserror 2.0.12", + "thiserror 2.0.14", "tokio", "tracing", "web-time", @@ -2172,7 +2183,7 @@ dependencies = [ "rustls", "rustls-pki-types", "slab", - "thiserror 2.0.12", + "thiserror 2.0.14", "tinyvec", "tracing", "web-time", @@ -2367,9 +2378,9 @@ checksum = "2b15c43186be67a4fd63bee50d0303afffcef381492ebe2c5d87f324e1b8815c" [[package]] name = "reqwest" -version = "0.12.22" +version = "0.12.23" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cbc931937e6ca3a06e3b6c0aa7841849b160a90351d6ab467a8b9b9959767531" +checksum = "d429f34c8092b2d42c7c93cec323bb4adeb7c67698f70839adec842ec10c7ceb" dependencies = [ "base64", "bytes", @@ -2574,9 +2585,9 @@ dependencies = [ [[package]] name = "rustversion" -version = "1.0.21" +version = "1.0.22" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8a0d197bd2c9dc6e53b84da9556a69ba4cdfab8619eb41a8bd1cc2027a0f6b1d" +checksum = "b39cdef0fa800fc44525c84ccb54a029961a8215f9619753635a9c0d2538d46d" [[package]] name = "ryu" @@ -2775,9 +2786,9 @@ checksum = "0fda2ff0d084019ba4d7c6f371c95d8fd75ce3524c3cb8fb653a3023f6323e64" [[package]] name = "signal-hook-registry" -version = "1.4.5" +version = "1.4.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9203b8055f63a2a00e2f593bb0510367fe707d7ff1e5c872de2f537b339e5410" +checksum = "b2a4719bff48cee6b39d12c020eeb490953ad2443b7055bd0b21fca26bd8c28b" dependencies = [ "libc", ] @@ -2818,9 +2829,9 @@ checksum = "c1e9a774a6c28142ac54bb25d25562e6bcf957493a184f15ad4eebccb23e410a" [[package]] name = "slab" -version = "0.4.10" +version = "0.4.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "04dc19736151f35336d325007ac991178d504a119863a2fcb3758cdb5e52c50d" +checksum = "7a2ae44ef20feb57a68b23d846850f861394c2e02dc425a50098ae8c90267589" [[package]] name = "smallvec" @@ -2917,7 +2928,7 @@ dependencies = [ "serde_json", "sha2", "smallvec", - "thiserror 2.0.12", + "thiserror 2.0.14", "time", "tokio", "tokio-stream", @@ -3002,7 +3013,7 @@ dependencies = [ "smallvec", "sqlx-core", "stringprep", - "thiserror 2.0.12", + "thiserror 2.0.14", "time", "tracing", "uuid", @@ -3041,7 +3052,7 @@ dependencies = [ "smallvec", "sqlx-core", "stringprep", - "thiserror 2.0.12", + "thiserror 2.0.14", "time", "tracing", "uuid", @@ -3067,7 +3078,7 @@ dependencies = [ "serde", "serde_urlencoded", "sqlx-core", - "thiserror 2.0.12", + "thiserror 2.0.14", "time", "tracing", "url", @@ -3105,9 +3116,9 @@ checksum = "13c2bddecc57b384dee18652358fb23172facb8a2c51ccc10d74c157bdea3292" [[package]] name = "syn" -version = "2.0.104" +version = "2.0.105" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "17b6f705963418cdb9927482fa304bc562ece2fdd4f616084c50b7023b435a40" +checksum = "7bc3fcb250e53458e712715cf74285c1f889686520d79294a9ef3bd7aa1fc619" dependencies = [ "proc-macro2", "quote", @@ -3164,11 +3175,11 @@ dependencies = [ [[package]] name = "thiserror" -version = "2.0.12" +version = "2.0.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "567b8a2dae586314f7be2a752ec7474332959c6460e02bde30d702a66d488708" +checksum = "0b0949c3a6c842cbde3f1686d6eea5a010516deb7085f79db747562d4102f41e" dependencies = [ - "thiserror-impl 2.0.12", + "thiserror-impl 2.0.14", ] [[package]] @@ -3184,9 +3195,9 @@ dependencies = [ [[package]] name = "thiserror-impl" -version = "2.0.12" +version = "2.0.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7f7cf42b4507d8ea322120659672cf1b9dbb93f8f2d4ecfd6e51350ff5b17a1d" +checksum = "cc5b44b4ab9c2fdd0e0512e6bece8388e214c0749f5862b114cc5b7a25daf227" dependencies = [ "proc-macro2", "quote", @@ -3403,9 +3414,9 @@ dependencies = [ [[package]] name = "tonic" -version = "0.14.0" +version = "0.14.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "308e1db96abdccdf0a9150fb69112bf6ea72640e0bd834ef0c4a618ccc8c8ddc" +checksum = "67ac5a8627ada0968acec063a4746bf79588aa03ccb66db2f75d7dce26722a40" dependencies = [ "async-trait", "axum", @@ -3432,9 +3443,9 @@ dependencies = [ [[package]] name = "tonic-build" -version = "0.14.0" +version = "0.14.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "18262cdd13dec66e8e3f2e3fe535e4b2cc706fab444a7d3678d75d8ac2557329" +checksum = "49e323d8bba3be30833707e36d046deabf10a35ae8ad3cae576943ea8933e25d" dependencies = [ "prettyplease", "proc-macro2", @@ -3450,14 +3461,14 @@ checksum = "b9c511b9a96d40cb12b7d5d00464446acf3b9105fd3ce25437cfe41c92b1c87d" dependencies = [ "bytes", "prost 0.14.1", - "tonic 0.14.0", + "tonic 0.14.1", ] [[package]] name = "tonic-prost-build" -version = "0.14.0" +version = "0.14.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "114cca66d757d72422ef8cccf8be3065321860ac9fa4be73aab37a8a20a9a805" +checksum = "8ef298fcd01b15e135440c4b8c974460ceca4e6a5af7f1c933b08e4d2875efa1" dependencies = [ "prettyplease", "proc-macro2", @@ -3479,19 +3490,19 @@ dependencies = [ "prost-types 0.14.1", "tokio", "tokio-stream", - "tonic 0.14.0", + "tonic 0.14.1", "tonic-prost", ] [[package]] name = "tonic-types" -version = "0.14.0" +version = "0.14.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "115f961025595f53ded3af4f977d6f2ce041b8e4662252ce6ccf0f2e2fab28b1" +checksum = "2830bdf6d112fe42b060125a5eaf9242e1f63cc48085951879d7c4ae21247daa" dependencies = [ "prost 0.14.1", "prost-types 0.14.1", - "tonic 0.14.0", + "tonic 0.14.1", ] [[package]] @@ -3841,9 +3852,9 @@ dependencies = [ [[package]] name = "uuid" -version = "1.17.0" +version = "1.18.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3cf4199d1e5d15ddd86a694e4d0dffa9c323ce759fea589f00fef9d81cc1931d" +checksum = "f33196643e165781c20a5ead5582283a7dacbb87855d867fbc2df3f81eddc1be" dependencies = [ "getrandom 0.3.3", "js-sys", @@ -3907,7 +3918,7 @@ dependencies = [ "sqlx", "time", "tokio", - "tonic 0.14.0", + "tonic 0.14.1", "tower", "tower-http", "tracing", @@ -3943,7 +3954,7 @@ dependencies = [ "sqlx", "time", "tokio", - "tonic 0.14.0", + "tonic 0.14.1", "tonic-reflection", "tower", "tower-http", @@ -3969,7 +3980,7 @@ dependencies = [ "serde", "serde_json", "time", - "tonic 0.14.0", + "tonic 0.14.1", "tonic-prost", "tonic-prost-build", "tonic-types", @@ -4001,7 +4012,7 @@ dependencies = [ "sqlx", "time", "tokio", - "tonic 0.14.0", + "tonic 0.14.1", "tracing", "warden-core", "warden-stack", @@ -4024,7 +4035,7 @@ dependencies = [ "serde", "serde_json", "tokio", - "tonic 0.14.0", + "tonic 0.14.1", "tracing", "tracing-opentelemetry", "uuid", @@ -4050,9 +4061,9 @@ dependencies = [ "serde", "serde_json", "sqlx", - "thiserror 2.0.12", + "thiserror 2.0.14", "tokio", - "tonic 0.14.0", + "tonic 0.14.1", "tracing", "tracing-loki", "tracing-opentelemetry", @@ -4192,11 +4203,11 @@ dependencies = [ [[package]] name = "whoami" -version = "1.6.0" +version = "1.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6994d13118ab492c3c80c1f81928718159254c53c472bf9ce36f8dae4add02a7" +checksum = "5d4a4db5077702ca3015d3d02d74974948aba2ad9e12ab7df718ee64ccd7e97d" dependencies = [ - "redox_syscall", + "libredox", "wasite", ] diff --git a/crates/configuration/src/server/http_svc.rs b/crates/configuration/src/server/http_svc.rs index 45cdcfa..b07aece 100644 --- a/crates/configuration/src/server/http_svc.rs +++ b/crates/configuration/src/server/http_svc.rs @@ -11,6 +11,7 @@ use utoipa_scalar::Servable as _; use crate::state::AppHandle; const TAG_ROUTING: &str = "Routing"; +const TAG_RULES: &str = "Rules"; #[derive(OpenApi)] #[openapi( diff --git a/crates/configuration/src/server/http_svc/routes.rs b/crates/configuration/src/server/http_svc/routes.rs index bec7c77..281b231 100644 --- a/crates/configuration/src/server/http_svc/routes.rs +++ b/crates/configuration/src/server/http_svc/routes.rs @@ -1,4 +1,5 @@ mod routing; +mod rule; use utoipa_axum::{router::OpenApiRouter, routes}; @@ -7,8 +8,16 @@ use crate::state::AppHandle; pub fn router(store: AppHandle) -> OpenApiRouter { OpenApiRouter::new() .routes(routes!( + /* routing */ routing::get_active::active_routing, - routing::post_routing::post_routing + routing::post_routing::post_routing, + routing::delete_routing::delete, + routing::replace_routing::replace, + /* rule */ + rule::create::create_rule, + rule::update::update_rule_config, + rule::delete::delete_rule_config, + rule::get::get_rule, )) .with_state(store) } diff --git a/crates/configuration/src/server/http_svc/routes/routing/delete_routing.rs b/crates/configuration/src/server/http_svc/routes/routing/delete_routing.rs index 07148cc..23733d3 100644 --- a/crates/configuration/src/server/http_svc/routes/routing/delete_routing.rs +++ b/crates/configuration/src/server/http_svc/routes/routing/delete_routing.rs @@ -28,6 +28,7 @@ use crate::{ #[axum::debug_handler] #[tracing::instrument(skip(state))] pub async fn delete( + version: Version, State(state): State<AppHandle>, Path(id): Path<String>, axum::Json(body): axum::Json<RoutingConfiguration>, diff --git a/crates/configuration/src/server/http_svc/routes/routing/replace_routing.rs b/crates/configuration/src/server/http_svc/routes/routing/replace_routing.rs index ccf184f..5c7cd02 100644 --- a/crates/configuration/src/server/http_svc/routes/routing/replace_routing.rs +++ b/crates/configuration/src/server/http_svc/routes/routing/replace_routing.rs @@ -27,6 +27,7 @@ use crate::{ #[axum::debug_handler] #[tracing::instrument(skip(state))] pub async fn replace( + version: Version, State(state): State<AppHandle>, Path(id): Path<String>, axum::Json(body): axum::Json<RoutingConfiguration>, diff --git a/crates/configuration/src/server/http_svc/routes/rule.rs b/crates/configuration/src/server/http_svc/routes/rule.rs new file mode 100644 index 0000000..f4b0d33 --- /dev/null +++ b/crates/configuration/src/server/http_svc/routes/rule.rs @@ -0,0 +1,4 @@ +pub mod create; +pub mod delete; +pub mod get; +pub mod update; diff --git a/crates/configuration/src/server/http_svc/routes/rule/create.rs b/crates/configuration/src/server/http_svc/routes/rule/create.rs new file mode 100644 index 0000000..809c00b --- /dev/null +++ b/crates/configuration/src/server/http_svc/routes/rule/create.rs @@ -0,0 +1,38 @@ +use axum::{extract::State, response::IntoResponse}; +use warden_core::configuration::rule::{ + RuleConfiguration, mutate_rule_configuration_server::MutateRuleConfiguration, +}; + +use crate::{ + server::{error::AppError, http_svc::TAG_RULES, version::Version}, + state::AppHandle, +}; + +/// Create rule configuration +#[utoipa::path( + post, + path = "/{version}/rule", + params( + ("version" = Version, Path, description = "API version, e.g., v1, v2, v3"), + ), + responses(( + status = CREATED, + body = RuleConfiguration, + )), + operation_id = "create_rule_configuration", // https://github.com/juhaku/utoipa/issues/1170 + tag = TAG_RULES, + ) +] +#[axum::debug_handler] +#[tracing::instrument(skip(state))] +pub async fn create_rule( + version: Version, + State(state): State<AppHandle>, + axum::Json(body): axum::Json<RuleConfiguration>, +) -> Result<impl IntoResponse, AppError> { + let response = state + .create_rule_configuration(tonic::Request::new(body)) + .await? + .into_inner(); + Ok((axum::http::StatusCode::CREATED, axum::Json(response))) +} diff --git a/crates/configuration/src/server/http_svc/routes/rule/delete.rs b/crates/configuration/src/server/http_svc/routes/rule/delete.rs new file mode 100644 index 0000000..2352fba --- /dev/null +++ b/crates/configuration/src/server/http_svc/routes/rule/delete.rs @@ -0,0 +1,42 @@ +use axum::extract::{Query, State}; +use tonic::IntoRequest; +use warden_core::configuration::rule::{ + DeleteRuleConfigurationRequest, RuleConfiguration, + mutate_rule_configuration_server::MutateRuleConfiguration, +}; + +use crate::{ + server::{error::AppError, http_svc::TAG_RULES, version::Version}, + state::AppHandle, +}; + +/// Delete rule configuration +#[utoipa::path( + delete, + path = "/{version}/rule", + responses(( + status = OK, + body = RuleConfiguration + )), + params( + ("version" = Version, Path, description = "API version, e.g., v1, v2, v3"), + DeleteRuleConfigurationRequest, + ), + operation_id = "delete_rule_configuration", // https://github.com/juhaku/utoipa/issues/1170 + tag = TAG_RULES, + ) +] +#[axum::debug_handler] +#[tracing::instrument(skip(state))] +pub async fn delete_rule_config( + version: Version, + State(state): State<AppHandle>, + Query(body): Query<DeleteRuleConfigurationRequest>, +) -> Result<axum::Json<RuleConfiguration>, AppError> { + let body = state + .delete_rule_configuration(body.into_request()) + .await? + .into_inner(); + + Ok(axum::Json(body)) +} diff --git a/crates/configuration/src/server/http_svc/routes/rule/get.rs b/crates/configuration/src/server/http_svc/routes/rule/get.rs new file mode 100644 index 0000000..935eefb --- /dev/null +++ b/crates/configuration/src/server/http_svc/routes/rule/get.rs @@ -0,0 +1,42 @@ +use axum::extract::{Query, State}; +use warden_core::configuration::rule::{ + RuleConfiguration, RuleConfigurationRequest, + query_rule_configuration_server::QueryRuleConfiguration, +}; + +use crate::{ + server::{error::AppError, http_svc::TAG_RULES, version::Version}, + state::AppHandle, +}; + +/// Get rule configuration +#[utoipa::path( + get, + path = "/{version}/rule", + responses(( + status = OK, + body = RuleConfiguration + )), + params( + ("version" = Version, Path, description = "API version, e.g., v1, v2, v3"), + RuleConfigurationRequest + ), + operation_id = "get_rule_configuration", // https://github.com/juhaku/utoipa/issues/1170 + tag = TAG_RULES, + ) +] +#[axum::debug_handler] +#[tracing::instrument(skip(state))] +pub async fn get_rule( + version: Version, + State(state): State<AppHandle>, + Query(body): Query<RuleConfigurationRequest>, +) -> Result<axum::Json<Option<RuleConfiguration>>, AppError> { + let response = state + .get_rule_configuration(tonic::Request::new(body)) + .await? + .into_inner() + .configuration; + + Ok(axum::Json(response)) +} diff --git a/crates/configuration/src/server/http_svc/routes/rule/update.rs b/crates/configuration/src/server/http_svc/routes/rule/update.rs new file mode 100644 index 0000000..7bf3fe0 --- /dev/null +++ b/crates/configuration/src/server/http_svc/routes/rule/update.rs @@ -0,0 +1,45 @@ +use axum::extract::State; +use tonic::IntoRequest; +use warden_core::configuration::rule::{ + RuleConfiguration, UpdateRuleRequest, mutate_rule_configuration_server::MutateRuleConfiguration, +}; + +use crate::{ + server::{error::AppError, http_svc::TAG_RULES, version::Version}, + state::AppHandle, +}; + +/// Update the routing configuration +#[utoipa::path( + put, + path = "/{version}/rule", + params( + ("version" = Version, Path, description = "API version, e.g., v1, v2, v3"), + ), + responses(( + status = OK, + body = RuleConfiguration + )), + operation_id = "update rule configuration", // https://github.com/juhaku/utoipa/issues/1170 + tag = TAG_RULES, + ) +] +#[axum::debug_handler] +#[tracing::instrument(skip(state))] +pub async fn update_rule_config( + version: Version, + State(state): State<AppHandle>, + axum::Json(body): axum::Json<RuleConfiguration>, +) -> Result<axum::Json<RuleConfiguration>, AppError> { + let config = state + .update_rule_configuration( + UpdateRuleRequest { + configuration: Some(body), + } + .into_request(), + ) + .await? + .into_inner(); + + Ok(axum::Json(config)) +} diff --git a/crates/router/src/main.rs b/crates/router/src/main.rs index cc4c927..ad81700 100644 --- a/crates/router/src/main.rs +++ b/crates/router/src/main.rs @@ -52,9 +52,7 @@ async fn main() -> Result<()> { .take() .ok_or_else(|| anyhow::anyhow!("jetstream is not ready"))?; - let services = state::Services { - jetstream, - }; + let services = state::Services { jetstream }; processor::serve(services, config, provider) .await diff --git a/crates/router/src/processor.rs b/crates/router/src/processor.rs index b8c69f3..9afe726 100644 --- a/crates/router/src/processor.rs +++ b/crates/router/src/processor.rs @@ -1,20 +1,25 @@ pub mod grpc; +mod load; +mod publish; mod reload; mod route; -mod publish; -mod load; use std::sync::Arc; use anyhow::Result; -use async_nats::jetstream::{consumer::{pull, Consumer}, Context}; +use async_nats::jetstream::{ + Context, + consumer::{Consumer, pull}, +}; +use futures_util::StreamExt; use tokio::signal; use tracing::{error, trace}; use warden_stack::{Configuration, tracing::SdkTracerProvider}; -use futures_util::StreamExt; - -use crate::{cnfg::Nats, state::{AppHandle, AppState, Services}}; +use crate::{ + cnfg::Nats, + state::{AppHandle, AppState, Services}, +}; pub async fn serve( services: Services, @@ -31,7 +36,6 @@ pub async fn serve( Ok(()) } - async fn run(state: AppHandle) -> anyhow::Result<()> { let config = Arc::clone(&state); let (consumer, _) = tokio::join!( @@ -77,7 +81,6 @@ async fn get_or_create_stream( .await?) } - async fn shutdown_signal(provider: SdkTracerProvider) -> Result<()> { let ctrl_c = async { signal::ctrl_c() diff --git a/crates/router/src/processor/load.rs b/crates/router/src/processor/load.rs index 9d3fd0d..b3fdf1c 100644 --- a/crates/router/src/processor/load.rs +++ b/crates/router/src/processor/load.rs @@ -1,7 +1,7 @@ use opentelemetry_semantic_conventions::attribute; -use tracing_opentelemetry::OpenTelemetrySpanExt; use tracing::{Instrument, debug, info, info_span, instrument, warn}; -use warden_core::{configuration::routing::RoutingConfiguration, google }; +use tracing_opentelemetry::OpenTelemetrySpanExt; +use warden_core::{configuration::routing::RoutingConfiguration, google}; use crate::{cnfg::CACHE_KEY, state::AppHandle}; diff --git a/crates/router/src/processor/publish.rs b/crates/router/src/processor/publish.rs index 16dcec8..277b674 100644 --- a/crates/router/src/processor/publish.rs +++ b/crates/router/src/processor/publish.rs @@ -1,7 +1,7 @@ -use opentelemetry::global; +use opentelemetry::global; use opentelemetry_semantic_conventions::attribute; -use tracing_opentelemetry::OpenTelemetrySpanExt; use tracing::{Instrument, Span, debug, info, info_span, warn}; +use tracing_opentelemetry::OpenTelemetrySpanExt; use warden_core::{configuration::routing::RoutingConfiguration, message::Payload}; use warden_stack::tracing::telemetry::nats::injector; diff --git a/crates/router/src/processor/reload.rs b/crates/router/src/processor/reload.rs index c75465c..900b7ce 100644 --- a/crates/router/src/processor/reload.rs +++ b/crates/router/src/processor/reload.rs @@ -1,6 +1,6 @@ -use futures_util::StreamExt; use async_nats::jetstream::consumer; -use tracing::{trace, debug, error, info}; +use futures_util::StreamExt; +use tracing::{debug, error, info, trace}; use uuid::Uuid; use warden_core::configuration::ReloadEvent; diff --git a/crates/router/src/processor/route.rs b/crates/router/src/processor/route.rs index 404c2ca..d51a86a 100644 --- a/crates/router/src/processor/route.rs +++ b/crates/router/src/processor/route.rs @@ -3,7 +3,7 @@ use std::{collections::HashSet, sync::Arc}; use opentelemetry::global; use prost::Message; -use tracing::{info_span, instrument, trace, trace_span, warn, Instrument, Span}; +use tracing::{Instrument, Span, info_span, instrument, trace, trace_span, warn}; use tracing_opentelemetry::OpenTelemetrySpanExt; use warden_core::{google, message::Payload}; use warden_stack::tracing::telemetry::nats; diff --git a/crates/router/src/state.rs b/crates/router/src/state.rs index e01629e..4ede2de 100644 --- a/crates/router/src/state.rs +++ b/crates/router/src/state.rs @@ -8,7 +8,7 @@ use tracing::error; use warden_core::configuration::routing::{ RoutingConfiguration, query_routing_client::QueryRoutingClient, }; -use warden_stack::{Configuration}; +use warden_stack::Configuration; use crate::{ cnfg::LocalConfig, diff --git a/lib/warden-core/build.rs b/lib/warden-core/build.rs index 83b0407..c0496d9 100644 --- a/lib/warden-core/build.rs +++ b/lib/warden-core/build.rs @@ -20,18 +20,16 @@ impl Entity { #[cfg(feature = "configuration")] fn configuration_protos() -> Vec<&'static str> { + let mut base = vec![ + "proto/configuration/reload_event.proto", + "proto/configuration/rule.proto", + ]; if cfg!(feature = "message") { - vec![ - "proto/configuration/reload_event.proto", - ] + base } else { - vec![ - "proto/configuration/routing.proto", - "proto/configuration/reload_event.proto", - ] - + base.extend(["proto/configuration/routing.proto"]); + base } - } #[cfg(feature = "pseudonyms")] @@ -131,5 +129,14 @@ fn add_serde(config: tonic_prost_build::Builder) -> tonic_prost_build::Builder { any(feature = "message", feature = "pseudonyms", feature = "configuration") ))] fn add_openapi(config: tonic_prost_build::Builder) -> tonic_prost_build::Builder { - config.type_attribute(".", "#[derive(utoipa::ToSchema)]") + config + .type_attribute(".", "#[derive(utoipa::ToSchema)]") + .type_attribute( + ".configuration.rule.RuleConfigurationRequest", + "#[derive(utoipa::IntoParams)]", + ) + .type_attribute( + ".configuration.rule.DeleteRuleConfigurationRequest", + "#[derive(utoipa::IntoParams)]", + ) } diff --git a/lib/warden-core/src/configuration.rs b/lib/warden-core/src/configuration.rs index b620914..798c079 100644 --- a/lib/warden-core/src/configuration.rs +++ b/lib/warden-core/src/configuration.rs @@ -3,3 +3,7 @@ tonic::include_proto!("configuration"); pub mod routing { tonic::include_proto!("configuration.routing"); } + +pub mod rule { + tonic::include_proto!("configuration.rule"); +} diff --git a/lib/warden-stack/src/tracing/loki.rs b/lib/warden-stack/src/tracing/loki.rs index cbf4e40..be4968b 100644 --- a/lib/warden-stack/src/tracing/loki.rs +++ b/lib/warden-stack/src/tracing/loki.rs @@ -14,7 +14,7 @@ impl<S: State> TracingBuilder<S> { S::LokiTask: IsUnset, { use std::str::FromStr; - let url = FromStr::from_str(&monitoring.loki_endpoint.as_ref()) + let url = FromStr::from_str(monitoring.loki_endpoint.as_ref()) .map_err(|_e| crate::ServiceError::Unknown)?; let (layer, task) = tracing_loki::builder() diff --git a/lib/warden-stack/src/tracing/telemetry.rs b/lib/warden-stack/src/tracing/telemetry.rs index b024937..838d758 100644 --- a/lib/warden-stack/src/tracing/telemetry.rs +++ b/lib/warden-stack/src/tracing/telemetry.rs @@ -55,10 +55,10 @@ pub mod tonic { impl opentelemetry::propagation::Injector for MetadataMap<'_> { /// Set a key and value in the MetadataMap. Does nothing if the key or value are not valid inputs fn set(&mut self, key: &str, value: String) { - if let Ok(key) = tonic::metadata::MetadataKey::from_bytes(key.as_bytes()) { - if let Ok(val) = tonic::metadata::MetadataValue::try_from(&value) { - self.0.insert(key, val); - } + if let Ok(key) = tonic::metadata::MetadataKey::from_bytes(key.as_bytes()) + && let Ok(val) = tonic::metadata::MetadataValue::try_from(&value) + { + self.0.insert(key, val); } } } diff --git a/proto/configuration/reload_event.proto b/proto/configuration/reload_event.proto index a77645f..569de80 100644 --- a/proto/configuration/reload_event.proto +++ b/proto/configuration/reload_event.proto @@ -4,4 +4,5 @@ package configuration; enum ReloadEvent { ROUTING = 0; + RULE = 1; } diff --git a/proto/configuration/rule.proto b/proto/configuration/rule.proto new file mode 100644 index 0000000..f963fde --- /dev/null +++ b/proto/configuration/rule.proto @@ -0,0 +1,70 @@ +syntax = "proto3"; + +package configuration.rule; + +import "google/protobuf/struct.proto"; + +message Timeframe { + double threshold = 1; +} + +message OutcomeResult { + string sub_rule_ref = 1; + string reason = 2; +} + +message Band { + string sub_rule_ref = 1; + string reason = 2; + optional double lower_limit = 3; + optional double upper_limit = 4; +} + +message Case { + string sub_rule_ref = 1; + string reason = 2; + double value = 3; +} + +message Config { + optional google.protobuf.Value parameters = 1; + repeated OutcomeResult exit_conditions = 2; + repeated Band bands = 3; + repeated Case cases = 4; + repeated Timeframe time_frames = 5; +} + +message RuleConfiguration { + string id = 1; + string version = 2; + Config configuration = 3; + string description = 4; +} + +message RuleConfigurationRequest { + string id = 1; + string version = 2; +} + +message DeleteRuleConfigurationRequest { + string id = 1; + string version = 2; +} + +message UpdateRuleRequest { + RuleConfiguration configuration = 1; +} + +message GetRuleConfigResponse { + optional RuleConfiguration configuration = 1; +} + +service QueryRuleConfiguration { + rpc GetRuleConfiguration (RuleConfigurationRequest) returns (GetRuleConfigResponse); +} + +service MutateRuleConfiguration { + rpc CreateRuleConfiguration (RuleConfiguration) returns (RuleConfiguration); + rpc UpdateRuleConfiguration (UpdateRuleRequest) returns (RuleConfiguration); + rpc DeleteRuleConfiguration (DeleteRuleConfigurationRequest) returns (RuleConfiguration); +} |