From b3daa80e72d5ac209ca6ca6597ee7c973e37c14e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=AE=89=E6=AD=A3=E8=B6=85?= Date: Fri, 13 Feb 2026 23:21:04 +0800 Subject: [PATCH] refactor(admin): extract kms management route registration (#1801) --- rustfs/src/admin/handlers/kms.rs | 54 +---------- rustfs/src/admin/handlers/kms_management.rs | 69 ++++++++++++++ rustfs/src/admin/handlers/mod.rs | 1 + rustfs/src/admin/mod.rs | 2 + rustfs/src/admin/route_registration_test.rs | 99 +++++++++++++++++++++ rustfs/src/admin/router.rs | 8 ++ 6 files changed, 183 insertions(+), 50 deletions(-) create mode 100644 rustfs/src/admin/handlers/kms_management.rs create mode 100644 rustfs/src/admin/route_registration_test.rs diff --git a/rustfs/src/admin/handlers/kms.rs b/rustfs/src/admin/handlers/kms.rs index 82f5eb61b..1f3b126f1 100644 --- a/rustfs/src/admin/handlers/kms.rs +++ b/rustfs/src/admin/handlers/kms.rs @@ -14,13 +14,13 @@ //! KMS admin handlers for HTTP API -use super::{kms_dynamic, kms_keys}; +use super::{kms_dynamic, kms_keys, kms_management}; use crate::admin::auth::validate_admin_request; use crate::admin::router::{AdminOperation, Operation, S3Router}; use crate::auth::{check_key_valid, get_session_token}; -use crate::server::{ADMIN_PREFIX, RemoteAddr}; +use crate::server::RemoteAddr; use base64::Engine; -use hyper::{HeaderMap, Method, StatusCode}; +use hyper::{HeaderMap, StatusCode}; use matchit::Params; use rustfs_config::MAX_ADMIN_REQUEST_BODY_SIZE; use rustfs_kms::{get_global_encryption_service, types::*}; @@ -111,59 +111,13 @@ fn extract_query_params(uri: &hyper::Uri) -> HashMap { } pub fn register_kms_route(r: &mut S3Router) -> std::io::Result<()> { - register_kms_management_route(r)?; + kms_management::register_kms_management_route(r)?; kms_dynamic::register_kms_dynamic_route(r)?; kms_keys::register_kms_key_route(r)?; Ok(()) } -fn register_kms_management_route(r: &mut S3Router) -> std::io::Result<()> { - r.insert( - Method::POST, - format!("{}{}", ADMIN_PREFIX, "/v3/kms/create-key").as_str(), - AdminOperation(&CreateKeyHandler {}), - )?; - - r.insert( - Method::GET, - format!("{}{}", ADMIN_PREFIX, "/v3/kms/describe-key").as_str(), - AdminOperation(&DescribeKeyHandler {}), - )?; - - r.insert( - Method::GET, - format!("{}{}", ADMIN_PREFIX, "/v3/kms/list-keys").as_str(), - AdminOperation(&ListKeysHandler {}), - )?; - - r.insert( - Method::POST, - format!("{}{}", ADMIN_PREFIX, "/v3/kms/generate-data-key").as_str(), - AdminOperation(&GenerateDataKeyHandler {}), - )?; - - r.insert( - Method::GET, - format!("{}{}", ADMIN_PREFIX, "/v3/kms/status").as_str(), - AdminOperation(&KmsStatusHandler {}), - )?; - - r.insert( - Method::GET, - format!("{}{}", ADMIN_PREFIX, "/v3/kms/config").as_str(), - AdminOperation(&KmsConfigHandler {}), - )?; - - r.insert( - Method::POST, - format!("{}{}", ADMIN_PREFIX, "/v3/kms/clear-cache").as_str(), - AdminOperation(&KmsClearCacheHandler {}), - )?; - - Ok(()) -} - /// Create a new KMS master key pub struct CreateKeyHandler {} diff --git a/rustfs/src/admin/handlers/kms_management.rs b/rustfs/src/admin/handlers/kms_management.rs new file mode 100644 index 000000000..ed39f0cbc --- /dev/null +++ b/rustfs/src/admin/handlers/kms_management.rs @@ -0,0 +1,69 @@ +// Copyright 2024 RustFS Team +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +//! KMS management route registration. + +use super::kms::{ + CreateKeyHandler, DescribeKeyHandler, GenerateDataKeyHandler, KmsClearCacheHandler, KmsConfigHandler, KmsStatusHandler, + ListKeysHandler, +}; +use crate::admin::router::{AdminOperation, S3Router}; +use crate::server::ADMIN_PREFIX; +use hyper::Method; + +pub fn register_kms_management_route(r: &mut S3Router) -> std::io::Result<()> { + r.insert( + Method::POST, + format!("{}{}", ADMIN_PREFIX, "/v3/kms/create-key").as_str(), + AdminOperation(&CreateKeyHandler {}), + )?; + + r.insert( + Method::GET, + format!("{}{}", ADMIN_PREFIX, "/v3/kms/describe-key").as_str(), + AdminOperation(&DescribeKeyHandler {}), + )?; + + r.insert( + Method::GET, + format!("{}{}", ADMIN_PREFIX, "/v3/kms/list-keys").as_str(), + AdminOperation(&ListKeysHandler {}), + )?; + + r.insert( + Method::POST, + format!("{}{}", ADMIN_PREFIX, "/v3/kms/generate-data-key").as_str(), + AdminOperation(&GenerateDataKeyHandler {}), + )?; + + r.insert( + Method::GET, + format!("{}{}", ADMIN_PREFIX, "/v3/kms/status").as_str(), + AdminOperation(&KmsStatusHandler {}), + )?; + + r.insert( + Method::GET, + format!("{}{}", ADMIN_PREFIX, "/v3/kms/config").as_str(), + AdminOperation(&KmsConfigHandler {}), + )?; + + r.insert( + Method::POST, + format!("{}{}", ADMIN_PREFIX, "/v3/kms/clear-cache").as_str(), + AdminOperation(&KmsClearCacheHandler {}), + )?; + + Ok(()) +} diff --git a/rustfs/src/admin/handlers/mod.rs b/rustfs/src/admin/handlers/mod.rs index e53a76d30..0d62ee65a 100644 --- a/rustfs/src/admin/handlers/mod.rs +++ b/rustfs/src/admin/handlers/mod.rs @@ -22,6 +22,7 @@ pub mod is_admin; pub mod kms; pub mod kms_dynamic; pub mod kms_keys; +pub mod kms_management; pub mod metrics; pub mod policies; pub mod pools; diff --git a/rustfs/src/admin/mod.rs b/rustfs/src/admin/mod.rs index d3e8d58cb..f5d42713d 100644 --- a/rustfs/src/admin/mod.rs +++ b/rustfs/src/admin/mod.rs @@ -21,6 +21,8 @@ pub mod utils; #[cfg(test)] mod console_test; +#[cfg(test)] +mod route_registration_test; use handlers::{bucket_meta, heal, health, kms, pools, profile_admin, quota, rebalance, replication, sts, system, tier, user}; use router::{AdminOperation, S3Router}; diff --git a/rustfs/src/admin/route_registration_test.rs b/rustfs/src/admin/route_registration_test.rs new file mode 100644 index 000000000..25f661fe0 --- /dev/null +++ b/rustfs/src/admin/route_registration_test.rs @@ -0,0 +1,99 @@ +// Copyright 2024 RustFS Team +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +use crate::admin::{ + handlers::{bucket_meta, heal, health, kms, pools, profile_admin, quota, rebalance, replication, sts, system, tier, user}, + router::{AdminOperation, S3Router}, +}; +use crate::server::{ADMIN_PREFIX, HEALTH_PREFIX, PROFILE_CPU_PATH, PROFILE_MEMORY_PATH}; +use hyper::Method; + +fn admin_path(path: &str) -> String { + format!("{}{}", ADMIN_PREFIX, path) +} + +fn assert_route(router: &S3Router, method: Method, path: &str) { + assert!( + router.contains_route(method.clone(), path), + "expected route missing: {} {}", + method.as_str(), + path + ); +} + +#[test] +fn test_register_routes_cover_representative_admin_paths() { + let mut router: S3Router = S3Router::new(false); + + health::register_health_route(&mut router).expect("register health route"); + sts::register_admin_auth_route(&mut router).expect("register sts route"); + user::register_user_route(&mut router).expect("register user route"); + system::register_system_route(&mut router).expect("register system route"); + pools::register_pool_route(&mut router).expect("register pool route"); + rebalance::register_rebalance_route(&mut router).expect("register rebalance route"); + heal::register_heal_route(&mut router).expect("register heal route"); + tier::register_tier_route(&mut router).expect("register tier route"); + quota::register_quota_route(&mut router).expect("register quota route"); + bucket_meta::register_bucket_meta_route(&mut router).expect("register bucket meta route"); + replication::register_replication_route(&mut router).expect("register replication route"); + profile_admin::register_profiling_route(&mut router).expect("register profile route"); + kms::register_kms_route(&mut router).expect("register kms route"); + + assert_route(&router, Method::GET, HEALTH_PREFIX); + assert_route(&router, Method::HEAD, HEALTH_PREFIX); + assert_route(&router, Method::GET, PROFILE_CPU_PATH); + assert_route(&router, Method::GET, PROFILE_MEMORY_PATH); + + assert_route(&router, Method::POST, "/"); + assert_route(&router, Method::GET, &admin_path("/v3/is-admin")); + + assert_route(&router, Method::GET, &admin_path("/v3/list-users")); + assert_route(&router, Method::PUT, &admin_path("/v3/add-user")); + assert_route(&router, Method::PUT, &admin_path("/v3/set-user-status")); + assert_route(&router, Method::GET, &admin_path("/v3/groups")); + assert_route(&router, Method::PUT, &admin_path("/v3/update-group-members")); + assert_route(&router, Method::PUT, &admin_path("/v3/add-service-accounts")); + assert_route(&router, Method::GET, &admin_path("/v3/export-iam")); + assert_route(&router, Method::PUT, &admin_path("/v3/import-iam")); + assert_route(&router, Method::GET, &admin_path("/v3/list-canned-policies")); + assert_route(&router, Method::GET, &admin_path("/v3/target/list")); + assert_route(&router, Method::GET, &admin_path("/v3/accountinfo")); + + assert_route(&router, Method::POST, &admin_path("/v3/service")); + assert_route(&router, Method::GET, &admin_path("/v3/info")); + assert_route(&router, Method::GET, &admin_path("/v3/storageinfo")); + assert_route(&router, Method::GET, &admin_path("/v3/metrics")); + + assert_route(&router, Method::GET, &admin_path("/v3/pools/list")); + assert_route(&router, Method::POST, &admin_path("/v3/rebalance/start")); + assert_route(&router, Method::GET, &admin_path("/v3/rebalance/status")); + assert_route(&router, Method::POST, &admin_path("/v3/heal/test-bucket")); + assert_route(&router, Method::POST, &admin_path("/v3/heal/test-bucket/prefix")); + + assert_route(&router, Method::GET, &admin_path("/v3/tier")); + assert_route(&router, Method::POST, &admin_path("/v3/tier/clear")); + assert_route(&router, Method::PUT, &admin_path("/v3/quota/test-bucket")); + assert_route(&router, Method::GET, &admin_path("/v3/quota-stats/test-bucket")); + + assert_route(&router, Method::GET, &admin_path("/export-bucket-metadata")); + assert_route(&router, Method::PUT, &admin_path("/import-bucket-metadata")); + assert_route(&router, Method::GET, &admin_path("/v3/list-remote-targets")); + assert_route(&router, Method::PUT, &admin_path("/v3/set-remote-target")); + assert_route(&router, Method::GET, &admin_path("/debug/pprof/profile")); + + assert_route(&router, Method::POST, &admin_path("/v3/kms/create-key")); + assert_route(&router, Method::POST, &admin_path("/v3/kms/configure")); + assert_route(&router, Method::POST, &admin_path("/v3/kms/keys")); + assert_route(&router, Method::GET, &admin_path("/v3/kms/keys/test-key")); +} diff --git a/rustfs/src/admin/router.rs b/rustfs/src/admin/router.rs index b01565b5b..697b90c63 100644 --- a/rustfs/src/admin/router.rs +++ b/rustfs/src/admin/router.rs @@ -71,6 +71,14 @@ impl S3Router { } } +#[cfg(test)] +impl S3Router { + pub(crate) fn contains_route(&self, method: Method, path: &str) -> bool { + let route = Self::make_route_str(method, path); + self.router.at(&route).is_ok() + } +} + impl Default for S3Router { fn default() -> Self { Self::new(false)