diff --git a/rustfs/src/admin/handlers/bucket_meta.rs b/rustfs/src/admin/handlers/bucket_meta.rs index b011cb98c..94e75cb0e 100644 --- a/rustfs/src/admin/handlers/bucket_meta.rs +++ b/rustfs/src/admin/handlers/bucket_meta.rs @@ -13,11 +13,15 @@ // limitations under the License. use crate::{ - admin::{auth::validate_admin_request, router::Operation}, + admin::{ + auth::validate_admin_request, + router::{AdminOperation, Operation, S3Router}, + }, auth::{check_key_valid, get_session_token}, - server::RemoteAddr, + server::{ADMIN_PREFIX, RemoteAddr}, }; use http::{HeaderMap, StatusCode}; +use hyper::Method; use matchit::Params; use rustfs_config::MAX_BUCKET_METADATA_IMPORT_SIZE; use rustfs_ecstore::{ @@ -71,6 +75,22 @@ pub struct ExportBucketMetadataQuery { pub struct ExportBucketMetadata {} +pub fn register_bucket_meta_route(r: &mut S3Router) -> std::io::Result<()> { + r.insert( + Method::GET, + format!("{}{}", ADMIN_PREFIX, "/export-bucket-metadata").as_str(), + AdminOperation(&ExportBucketMetadata {}), + )?; + + r.insert( + Method::PUT, + format!("{}{}", ADMIN_PREFIX, "/import-bucket-metadata").as_str(), + AdminOperation(&ImportBucketMetadata {}), + )?; + + Ok(()) +} + #[async_trait::async_trait] impl Operation for ExportBucketMetadata { async fn call(&self, req: S3Request, _params: Params<'_, '_>) -> S3Result> { diff --git a/rustfs/src/admin/handlers/event.rs b/rustfs/src/admin/handlers/event.rs index 76ac4163a..1a5b29d47 100644 --- a/rustfs/src/admin/handlers/event.rs +++ b/rustfs/src/admin/handlers/event.rs @@ -12,10 +12,12 @@ // See the License for the specific language governing permissions and // limitations under the License. -use crate::admin::router::Operation; +use crate::admin::router::{AdminOperation, Operation, S3Router}; use crate::auth::{check_key_valid, get_session_token}; +use crate::server::ADMIN_PREFIX; use futures::stream::{FuturesUnordered, StreamExt}; use http::{HeaderMap, StatusCode}; +use hyper::Method; use matchit::Params; use rustfs_config::notify::{NOTIFY_MQTT_SUB_SYS, NOTIFY_WEBHOOK_SUB_SYS}; use rustfs_config::{ENABLE_KEY, EnableState, MAX_ADMIN_REQUEST_BODY_SIZE}; @@ -34,6 +36,34 @@ use tokio::time::{Duration, sleep, timeout}; use tracing::{Span, info, warn}; use url::Url; +pub fn register_notification_target_route(r: &mut S3Router) -> std::io::Result<()> { + r.insert( + Method::GET, + format!("{}{}", ADMIN_PREFIX, "/v3/target/list").as_str(), + AdminOperation(&ListNotificationTargets {}), + )?; + + r.insert( + Method::PUT, + format!("{}{}", ADMIN_PREFIX, "/v3/target/{target_type}/{target_name}").as_str(), + AdminOperation(&NotificationTarget {}), + )?; + + r.insert( + Method::DELETE, + format!("{}{}", ADMIN_PREFIX, "/v3/target/{target_type}/{target_name}/reset").as_str(), + AdminOperation(&RemoveNotificationTarget {}), + )?; + + r.insert( + Method::GET, + format!("{}{}", ADMIN_PREFIX, "/v3/target/arns").as_str(), + AdminOperation(&ListTargetsArns {}), + )?; + + Ok(()) +} + #[derive(Debug, Deserialize)] pub struct KeyValue { pub key: String, diff --git a/rustfs/src/admin/handlers/group.rs b/rustfs/src/admin/handlers/group.rs index 89c140c32..721dce6f2 100644 --- a/rustfs/src/admin/handlers/group.rs +++ b/rustfs/src/admin/handlers/group.rs @@ -13,11 +13,16 @@ // limitations under the License. use crate::{ - admin::{auth::validate_admin_request, router::Operation, utils::has_space_be}, + admin::{ + auth::validate_admin_request, + router::{AdminOperation, Operation, S3Router}, + utils::has_space_be, + }, auth::{check_key_valid, constant_time_eq, get_session_token}, - server::RemoteAddr, + server::{ADMIN_PREFIX, RemoteAddr}, }; use http::{HeaderMap, StatusCode}; +use hyper::Method; use matchit::Params; use rustfs_config::MAX_ADMIN_REQUEST_BODY_SIZE; use rustfs_credentials::get_global_action_cred; @@ -33,6 +38,34 @@ use serde::Deserialize; use serde_urlencoded::from_bytes; use tracing::warn; +pub fn register_group_management_route(r: &mut S3Router) -> std::io::Result<()> { + r.insert( + Method::GET, + format!("{}{}", ADMIN_PREFIX, "/v3/groups").as_str(), + AdminOperation(&ListGroups {}), + )?; + + r.insert( + Method::GET, + format!("{}{}", ADMIN_PREFIX, "/v3/group").as_str(), + AdminOperation(&GetGroup {}), + )?; + + r.insert( + Method::PUT, + format!("{}{}", ADMIN_PREFIX, "/v3/set-group-status").as_str(), + AdminOperation(&SetGroupStatus {}), + )?; + + r.insert( + Method::PUT, + format!("{}{}", ADMIN_PREFIX, "/v3/update-group-members").as_str(), + AdminOperation(&UpdateGroupMembers {}), + )?; + + Ok(()) +} + #[derive(Debug, Deserialize, Default)] pub struct GroupQuery { pub group: String, diff --git a/rustfs/src/admin/handlers/heal.rs b/rustfs/src/admin/handlers/heal.rs index 4262b5316..797f34aea 100644 --- a/rustfs/src/admin/handlers/heal.rs +++ b/rustfs/src/admin/handlers/heal.rs @@ -12,10 +12,11 @@ // See the License for the specific language governing permissions and // limitations under the License. -use crate::admin::router::Operation; +use crate::admin::router::{AdminOperation, Operation, S3Router}; +use crate::server::ADMIN_PREFIX; use bytes::Bytes; use http::Uri; -use hyper::StatusCode; +use hyper::{Method, StatusCode}; use matchit::Params; use rustfs_common::heal_channel::HealOpts; use rustfs_config::MAX_HEAL_REQUEST_SIZE; @@ -93,6 +94,30 @@ fn extract_heal_init_params(body: &Bytes, uri: &Uri, params: Params<'_, '_>) -> Ok(hip) } +pub fn register_heal_route(r: &mut S3Router) -> std::io::Result<()> { + // Some APIs are only available in EC mode + // if is_dist_erasure().await || is_erasure().await { + r.insert( + Method::POST, + format!("{}{}", ADMIN_PREFIX, "/v3/heal/{bucket}").as_str(), + AdminOperation(&HealHandler {}), + )?; + + r.insert( + Method::POST, + format!("{}{}", ADMIN_PREFIX, "/v3/heal/{bucket}/{prefix}").as_str(), + AdminOperation(&HealHandler {}), + )?; + + r.insert( + Method::POST, + format!("{}{}", ADMIN_PREFIX, "/v3/background-heal/status").as_str(), + AdminOperation(&BackgroundHealStatusHandler {}), + )?; + + Ok(()) +} + pub struct HealHandler {} #[async_trait::async_trait] diff --git a/rustfs/src/admin/handlers/health.rs b/rustfs/src/admin/handlers/health.rs index ff78e8831..f8830afa1 100644 --- a/rustfs/src/admin/handlers/health.rs +++ b/rustfs/src/admin/handlers/health.rs @@ -12,13 +12,25 @@ // See the License for the specific language governing permissions and // limitations under the License. -use crate::admin::router::Operation; +use super::profile::{TriggerProfileCPU, TriggerProfileMemory}; +use crate::admin::router::{AdminOperation, Operation, S3Router}; +use crate::server::{HEALTH_PREFIX, PROFILE_CPU_PATH, PROFILE_MEMORY_PATH}; use http::{HeaderMap, HeaderValue}; -use hyper::StatusCode; +use hyper::{Method, StatusCode}; use matchit::Params; use s3s::header::CONTENT_TYPE; use s3s::{Body, S3Request, S3Response, S3Result}; +pub fn register_health_route(r: &mut S3Router) -> std::io::Result<()> { + // Health check endpoint for monitoring and orchestration + r.insert(Method::GET, HEALTH_PREFIX, AdminOperation(&HealthCheckHandler {}))?; + r.insert(Method::HEAD, HEALTH_PREFIX, AdminOperation(&HealthCheckHandler {}))?; + r.insert(Method::GET, PROFILE_CPU_PATH, AdminOperation(&TriggerProfileCPU {}))?; + r.insert(Method::GET, PROFILE_MEMORY_PATH, AdminOperation(&TriggerProfileMemory {}))?; + + Ok(()) +} + /// Health check handler for endpoint monitoring pub struct HealthCheckHandler {} diff --git a/rustfs/src/admin/handlers/kms.rs b/rustfs/src/admin/handlers/kms.rs index 37e6815de..4f40c5e64 100644 --- a/rustfs/src/admin/handlers/kms.rs +++ b/rustfs/src/admin/handlers/kms.rs @@ -14,12 +14,13 @@ //! KMS admin handlers for HTTP API +use super::{kms_dynamic, kms_keys}; use crate::admin::auth::validate_admin_request; -use crate::admin::router::Operation; +use crate::admin::router::{AdminOperation, Operation, S3Router}; use crate::auth::{check_key_valid, get_session_token}; -use crate::server::RemoteAddr; +use crate::server::{ADMIN_PREFIX, RemoteAddr}; use base64::Engine; -use hyper::{HeaderMap, StatusCode}; +use hyper::{HeaderMap, Method, StatusCode}; use matchit::Params; use rustfs_config::MAX_ADMIN_REQUEST_BODY_SIZE; use rustfs_kms::{get_global_encryption_service, types::*}; @@ -109,6 +110,128 @@ fn extract_query_params(uri: &hyper::Uri) -> HashMap { params } +pub fn register_kms_route(r: &mut S3Router) -> std::io::Result<()> { + register_kms_management_route(r)?; + register_kms_dynamic_route(r)?; + 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(()) +} + +fn register_kms_dynamic_route(r: &mut S3Router) -> std::io::Result<()> { + r.insert( + Method::POST, + format!("{}{}", ADMIN_PREFIX, "/v3/kms/configure").as_str(), + AdminOperation(&kms_dynamic::ConfigureKmsHandler {}), + )?; + + r.insert( + Method::POST, + format!("{}{}", ADMIN_PREFIX, "/v3/kms/start").as_str(), + AdminOperation(&kms_dynamic::StartKmsHandler {}), + )?; + + r.insert( + Method::POST, + format!("{}{}", ADMIN_PREFIX, "/v3/kms/stop").as_str(), + AdminOperation(&kms_dynamic::StopKmsHandler {}), + )?; + + r.insert( + Method::GET, + format!("{}{}", ADMIN_PREFIX, "/v3/kms/service-status").as_str(), + AdminOperation(&kms_dynamic::GetKmsStatusHandler {}), + )?; + + r.insert( + Method::POST, + format!("{}{}", ADMIN_PREFIX, "/v3/kms/reconfigure").as_str(), + AdminOperation(&kms_dynamic::ReconfigureKmsHandler {}), + )?; + + Ok(()) +} + +fn register_kms_key_route(r: &mut S3Router) -> std::io::Result<()> { + r.insert( + Method::POST, + format!("{}{}", ADMIN_PREFIX, "/v3/kms/keys").as_str(), + AdminOperation(&kms_keys::CreateKmsKeyHandler {}), + )?; + + r.insert( + Method::DELETE, + format!("{}{}", ADMIN_PREFIX, "/v3/kms/keys/delete").as_str(), + AdminOperation(&kms_keys::DeleteKmsKeyHandler {}), + )?; + + r.insert( + Method::POST, + format!("{}{}", ADMIN_PREFIX, "/v3/kms/keys/cancel-deletion").as_str(), + AdminOperation(&kms_keys::CancelKmsKeyDeletionHandler {}), + )?; + + r.insert( + Method::GET, + format!("{}{}", ADMIN_PREFIX, "/v3/kms/keys").as_str(), + AdminOperation(&kms_keys::ListKmsKeysHandler {}), + )?; + + r.insert( + Method::GET, + format!("{}{}", ADMIN_PREFIX, "/v3/kms/keys/{key_id}").as_str(), + AdminOperation(&kms_keys::DescribeKmsKeyHandler {}), + )?; + + Ok(()) +} + /// Create a new KMS master key pub struct CreateKeyHandler {} diff --git a/rustfs/src/admin/handlers/mod.rs b/rustfs/src/admin/handlers/mod.rs index 195858c32..9f4ad4ce6 100644 --- a/rustfs/src/admin/handlers/mod.rs +++ b/rustfs/src/admin/handlers/mod.rs @@ -37,15 +37,6 @@ pub mod tier; pub mod trace; pub mod user; -pub use account_info::AccountInfoHandler; -pub use heal::{BackgroundHealStatusHandler, HealHandler}; -pub use health::HealthCheckHandler; -pub use is_admin::IsAdminHandler; -pub use metrics::MetricsHandler; -pub use profile_admin::{ProfileHandler, ProfileStatusHandler}; -pub use replication::{GetReplicationMetricsHandler, ListRemoteTargetHandler, RemoveRemoteTargetHandler, SetRemoteTargetHandler}; -pub use system::{DataUsageInfoHandler, InspectDataHandler, ServerInfoHandler, ServiceHandle, StorageInfoHandler}; - #[cfg(test)] mod tests { use super::*; @@ -53,19 +44,21 @@ mod tests { #[test] fn test_handler_struct_creation() { // Test that handler structs can be created - let _account_handler = AccountInfoHandler {}; - let _service_handler = ServiceHandle {}; - let _server_info_handler = ServerInfoHandler {}; - let _inspect_data_handler = InspectDataHandler {}; - let _storage_info_handler = StorageInfoHandler {}; - let _data_usage_handler = DataUsageInfoHandler {}; - let _metrics_handler = MetricsHandler {}; - let _heal_handler = HealHandler {}; - let _bg_heal_handler = BackgroundHealStatusHandler {}; - let _replication_metrics_handler = GetReplicationMetricsHandler {}; - let _set_remote_target_handler = SetRemoteTargetHandler {}; - let _list_remote_target_handler = ListRemoteTargetHandler {}; - let _remove_remote_target_handler = RemoveRemoteTargetHandler {}; + let _account_handler = account_info::AccountInfoHandler {}; + let _service_handler = system::ServiceHandle {}; + let _server_info_handler = system::ServerInfoHandler {}; + let _inspect_data_handler = system::InspectDataHandler {}; + let _storage_info_handler = system::StorageInfoHandler {}; + let _data_usage_handler = system::DataUsageInfoHandler {}; + let _metrics_handler = metrics::MetricsHandler {}; + let _profile_handler = profile_admin::ProfileHandler {}; + let _profile_status_handler = profile_admin::ProfileStatusHandler {}; + let _heal_handler = heal::HealHandler {}; + let _bg_heal_handler = heal::BackgroundHealStatusHandler {}; + let _replication_metrics_handler = replication::GetReplicationMetricsHandler {}; + let _set_remote_target_handler = replication::SetRemoteTargetHandler {}; + let _list_remote_target_handler = replication::ListRemoteTargetHandler {}; + let _remove_remote_target_handler = replication::RemoveRemoteTargetHandler {}; // Just verify they can be created without panicking // Test passes if we reach this point without panicking diff --git a/rustfs/src/admin/handlers/policies.rs b/rustfs/src/admin/handlers/policies.rs index be6a5dbae..0ab37c6e9 100644 --- a/rustfs/src/admin/handlers/policies.rs +++ b/rustfs/src/admin/handlers/policies.rs @@ -13,11 +13,16 @@ // limitations under the License. use crate::{ - admin::{auth::validate_admin_request, router::Operation, utils::has_space_be}, + admin::{ + auth::validate_admin_request, + router::{AdminOperation, Operation, S3Router}, + utils::has_space_be, + }, auth::{check_key_valid, get_session_token}, - server::RemoteAddr, + server::{ADMIN_PREFIX, RemoteAddr}, }; use http::{HeaderMap, StatusCode}; +use hyper::Method; use matchit::Params; use rustfs_config::MAX_ADMIN_REQUEST_BODY_SIZE; use rustfs_credentials::get_global_action_cred; @@ -37,6 +42,40 @@ use serde_urlencoded::from_bytes; use std::collections::HashMap; use tracing::warn; +pub fn register_iam_policy_route(r: &mut S3Router) -> std::io::Result<()> { + r.insert( + Method::GET, + format!("{}{}", ADMIN_PREFIX, "/v3/list-canned-policies").as_str(), + AdminOperation(&ListCannedPolicies {}), + )?; + + r.insert( + Method::GET, + format!("{}{}", ADMIN_PREFIX, "/v3/info-canned-policy").as_str(), + AdminOperation(&InfoCannedPolicy {}), + )?; + + r.insert( + Method::PUT, + format!("{}{}", ADMIN_PREFIX, "/v3/add-canned-policy").as_str(), + AdminOperation(&AddCannedPolicy {}), + )?; + + r.insert( + Method::DELETE, + format!("{}{}", ADMIN_PREFIX, "/v3/remove-canned-policy").as_str(), + AdminOperation(&RemoveCannedPolicy {}), + )?; + + r.insert( + Method::PUT, + format!("{}{}", ADMIN_PREFIX, "/v3/set-user-or-group-policy").as_str(), + AdminOperation(&SetPolicyForUserOrGroup {}), + )?; + + Ok(()) +} + #[derive(Debug, Deserialize, Default)] pub struct BucketQuery { pub bucket: String, diff --git a/rustfs/src/admin/handlers/pools.rs b/rustfs/src/admin/handlers/pools.rs index 17c149716..0809468b5 100644 --- a/rustfs/src/admin/handlers/pools.rs +++ b/rustfs/src/admin/handlers/pools.rs @@ -23,11 +23,43 @@ use tokio_util::sync::CancellationToken; use tracing::warn; use crate::{ - admin::{auth::validate_admin_request, router::Operation}, + admin::{ + auth::validate_admin_request, + router::{AdminOperation, Operation, S3Router}, + }, auth::{check_key_valid, get_session_token}, error::ApiError, - server::RemoteAddr, + server::{ADMIN_PREFIX, RemoteAddr}, }; +use hyper::Method; + +pub fn register_pool_route(r: &mut S3Router) -> std::io::Result<()> { + r.insert( + Method::GET, + format!("{}{}", ADMIN_PREFIX, "/v3/pools/list").as_str(), + AdminOperation(&ListPools {}), + )?; + + r.insert( + Method::GET, + format!("{}{}", ADMIN_PREFIX, "/v3/pools/status").as_str(), + AdminOperation(&StatusPool {}), + )?; + + r.insert( + Method::POST, + format!("{}{}", ADMIN_PREFIX, "/v3/pools/decommission").as_str(), + AdminOperation(&StartDecommission {}), + )?; + + r.insert( + Method::POST, + format!("{}{}", ADMIN_PREFIX, "/v3/pools/cancel").as_str(), + AdminOperation(&CancelDecommission {}), + )?; + + Ok(()) +} pub struct ListPools {} diff --git a/rustfs/src/admin/handlers/profile_admin.rs b/rustfs/src/admin/handlers/profile_admin.rs index 025e63831..9198070d9 100644 --- a/rustfs/src/admin/handlers/profile_admin.rs +++ b/rustfs/src/admin/handlers/profile_admin.rs @@ -12,9 +12,10 @@ // See the License for the specific language governing permissions and // limitations under the License. -use crate::admin::router::Operation; +use crate::admin::router::{AdminOperation, Operation, S3Router}; +use crate::server::ADMIN_PREFIX; use http::{HeaderMap, HeaderValue, Uri}; -use hyper::StatusCode; +use hyper::{Method, StatusCode}; use matchit::Params; use s3s::header::CONTENT_TYPE; use s3s::{Body, S3Request, S3Response, S3Result}; @@ -34,6 +35,22 @@ fn extract_query_params(uri: &Uri) -> HashMap { params } +pub fn register_profiling_route(r: &mut S3Router) -> std::io::Result<()> { + r.insert( + Method::GET, + format!("{}{}", ADMIN_PREFIX, "/debug/pprof/profile").as_str(), + AdminOperation(&ProfileHandler {}), + )?; + + r.insert( + Method::GET, + format!("{}{}", ADMIN_PREFIX, "/debug/pprof/status").as_str(), + AdminOperation(&ProfileStatusHandler {}), + )?; + + Ok(()) +} + pub struct ProfileHandler {} #[async_trait::async_trait] diff --git a/rustfs/src/admin/handlers/quota.rs b/rustfs/src/admin/handlers/quota.rs index 89df6b309..0ddd1332b 100644 --- a/rustfs/src/admin/handlers/quota.rs +++ b/rustfs/src/admin/handlers/quota.rs @@ -15,9 +15,10 @@ //! Quota admin handlers for HTTP API use crate::admin::auth::validate_admin_request; -use crate::admin::router::Operation; +use crate::admin::router::{AdminOperation, Operation, S3Router}; use crate::auth::{check_key_valid, get_session_token}; -use hyper::StatusCode; +use crate::server::ADMIN_PREFIX; +use hyper::{Method, StatusCode}; use matchit::Params; use rustfs_ecstore::bucket::quota::checker::QuotaChecker; use rustfs_ecstore::bucket::quota::{BucketQuota, QuotaError, QuotaOperation}; @@ -80,6 +81,40 @@ pub struct ClearBucketQuotaHandler; pub struct GetBucketQuotaStatsHandler; pub struct CheckBucketQuotaHandler; +pub fn register_quota_route(r: &mut S3Router) -> std::io::Result<()> { + r.insert( + Method::PUT, + format!("{}{}", ADMIN_PREFIX, "/v3/quota/{bucket}").as_str(), + AdminOperation(&SetBucketQuotaHandler {}), + )?; + + r.insert( + Method::GET, + format!("{}{}", ADMIN_PREFIX, "/v3/quota/{bucket}").as_str(), + AdminOperation(&GetBucketQuotaHandler {}), + )?; + + r.insert( + Method::DELETE, + format!("{}{}", ADMIN_PREFIX, "/v3/quota/{bucket}").as_str(), + AdminOperation(&ClearBucketQuotaHandler {}), + )?; + + r.insert( + Method::GET, + format!("{}{}", ADMIN_PREFIX, "/v3/quota-stats/{bucket}").as_str(), + AdminOperation(&GetBucketQuotaStatsHandler {}), + )?; + + r.insert( + Method::POST, + format!("{}{}", ADMIN_PREFIX, "/v3/quota-check/{bucket}").as_str(), + AdminOperation(&CheckBucketQuotaHandler {}), + )?; + + Ok(()) +} + #[async_trait::async_trait] impl Operation for SetBucketQuotaHandler { #[tracing::instrument(skip_all)] diff --git a/rustfs/src/admin/handlers/rebalance.rs b/rustfs/src/admin/handlers/rebalance.rs index a96efe0c0..9be46f8bc 100644 --- a/rustfs/src/admin/handlers/rebalance.rs +++ b/rustfs/src/admin/handlers/rebalance.rs @@ -13,11 +13,15 @@ // limitations under the License. use crate::{ - admin::{auth::validate_admin_request, router::Operation}, + admin::{ + auth::validate_admin_request, + router::{AdminOperation, Operation, S3Router}, + }, auth::{check_key_valid, get_session_token}, - server::RemoteAddr, + server::{ADMIN_PREFIX, RemoteAddr}, }; use http::{HeaderMap, StatusCode}; +use hyper::Method; use matchit::Params; use rustfs_ecstore::rebalance::RebalanceMeta; use rustfs_ecstore::{ @@ -39,6 +43,28 @@ use std::time::Duration; use time::OffsetDateTime; use tracing::warn; +pub fn register_rebalance_route(r: &mut S3Router) -> std::io::Result<()> { + r.insert( + Method::POST, + format!("{}{}", ADMIN_PREFIX, "/v3/rebalance/start").as_str(), + AdminOperation(&RebalanceStart {}), + )?; + + r.insert( + Method::GET, + format!("{}{}", ADMIN_PREFIX, "/v3/rebalance/status").as_str(), + AdminOperation(&RebalanceStatus {}), + )?; + + r.insert( + Method::POST, + format!("{}{}", ADMIN_PREFIX, "/v3/rebalance/stop").as_str(), + AdminOperation(&RebalanceStop {}), + )?; + + Ok(()) +} + #[derive(Debug, Clone, Deserialize, Serialize)] pub struct RebalanceResp { pub id: String, diff --git a/rustfs/src/admin/handlers/replication.rs b/rustfs/src/admin/handlers/replication.rs index 6952adc86..b07145267 100644 --- a/rustfs/src/admin/handlers/replication.rs +++ b/rustfs/src/admin/handlers/replication.rs @@ -13,12 +13,12 @@ // limitations under the License. use crate::admin::auth::validate_admin_request; -use crate::admin::router::Operation; +use crate::admin::router::{AdminOperation, Operation, S3Router}; use crate::auth::{check_key_valid, get_session_token}; use crate::error::ApiError; -use crate::server::RemoteAddr; +use crate::server::{ADMIN_PREFIX, RemoteAddr}; use http::{HeaderMap, HeaderValue, Uri}; -use hyper::StatusCode; +use hyper::{Method, StatusCode}; use matchit::Params; use rustfs_config::MAX_ADMIN_REQUEST_BODY_SIZE; use rustfs_ecstore::bucket::bucket_target_sys::BucketTargetSys; @@ -47,6 +47,34 @@ fn extract_query_params(uri: &Uri) -> HashMap { params } +pub fn register_replication_route(r: &mut S3Router) -> std::io::Result<()> { + r.insert( + Method::GET, + format!("{}{}", ADMIN_PREFIX, "/v3/list-remote-targets").as_str(), + AdminOperation(&ListRemoteTargetHandler {}), + )?; + + r.insert( + Method::GET, + format!("{}{}", ADMIN_PREFIX, "/v3/replicationmetrics").as_str(), + AdminOperation(&GetReplicationMetricsHandler {}), + )?; + + r.insert( + Method::PUT, + format!("{}{}", ADMIN_PREFIX, "/v3/set-remote-target").as_str(), + AdminOperation(&SetRemoteTargetHandler {}), + )?; + + r.insert( + Method::DELETE, + format!("{}{}", ADMIN_PREFIX, "/v3/remove-remote-target").as_str(), + AdminOperation(&RemoveRemoteTargetHandler {}), + )?; + + Ok(()) +} + async fn validate_replication_admin_request(req: &S3Request, action: AdminAction) -> S3Result<()> { let Some(input_cred) = req.credentials.as_ref() else { return Err(s3_error!(InvalidRequest, "get cred failed")); diff --git a/rustfs/src/admin/handlers/service_account.rs b/rustfs/src/admin/handlers/service_account.rs index 503bc0052..29aef0fa6 100644 --- a/rustfs/src/admin/handlers/service_account.rs +++ b/rustfs/src/admin/handlers/service_account.rs @@ -14,10 +14,13 @@ use crate::admin::utils::has_space_be; use crate::auth::{constant_time_eq, get_condition_values, get_session_token}; -use crate::server::RemoteAddr; -use crate::{admin::router::Operation, auth::check_key_valid}; +use crate::server::{ADMIN_PREFIX, RemoteAddr}; +use crate::{ + admin::router::{AdminOperation, Operation, S3Router}, + auth::check_key_valid, +}; use http::HeaderMap; -use hyper::StatusCode; +use hyper::{Method, StatusCode}; use matchit::Params; use rustfs_config::MAX_ADMIN_REQUEST_BODY_SIZE; use rustfs_credentials::get_global_action_cred; @@ -37,6 +40,40 @@ use serde_urlencoded::from_bytes; use std::collections::HashMap; use tracing::{debug, warn}; +pub fn register_service_account_route(r: &mut S3Router) -> std::io::Result<()> { + r.insert( + Method::POST, + format!("{}{}", ADMIN_PREFIX, "/v3/update-service-account").as_str(), + AdminOperation(&UpdateServiceAccount {}), + )?; + + r.insert( + Method::GET, + format!("{}{}", ADMIN_PREFIX, "/v3/info-service-account").as_str(), + AdminOperation(&InfoServiceAccount {}), + )?; + + r.insert( + Method::GET, + format!("{}{}", ADMIN_PREFIX, "/v3/list-service-accounts").as_str(), + AdminOperation(&ListServiceAccount {}), + )?; + + r.insert( + Method::DELETE, + format!("{}{}", ADMIN_PREFIX, "/v3/delete-service-accounts").as_str(), + AdminOperation(&DeleteServiceAccount {}), + )?; + + r.insert( + Method::PUT, + format!("{}{}", ADMIN_PREFIX, "/v3/add-service-accounts").as_str(), + AdminOperation(&AddServiceAccount {}), + )?; + + Ok(()) +} + pub struct AddServiceAccount {} #[async_trait::async_trait] impl Operation for AddServiceAccount { diff --git a/rustfs/src/admin/handlers/sts.rs b/rustfs/src/admin/handlers/sts.rs index 550a90d9e..53001b988 100644 --- a/rustfs/src/admin/handlers/sts.rs +++ b/rustfs/src/admin/handlers/sts.rs @@ -12,11 +12,14 @@ // See the License for the specific language governing permissions and // limitations under the License. +use super::is_admin::IsAdminHandler; use crate::{ - admin::router::Operation, + admin::router::{AdminOperation, Operation, S3Router}, auth::{check_key_valid, get_session_token}, + server::ADMIN_PREFIX, }; use http::StatusCode; +use hyper::Method; use matchit::Params; use rustfs_config::MAX_ADMIN_REQUEST_BODY_SIZE; use rustfs_ecstore::bucket::utils::serialize; @@ -37,6 +40,18 @@ use tracing::{error, info, warn}; const ASSUME_ROLE_ACTION: &str = "AssumeRole"; const ASSUME_ROLE_VERSION: &str = "2011-06-15"; +pub fn register_admin_auth_route(r: &mut S3Router) -> std::io::Result<()> { + r.insert(Method::POST, "/", AdminOperation(&AssumeRoleHandle {}))?; + + r.insert( + Method::GET, + format!("{}{}", ADMIN_PREFIX, "/v3/is-admin").as_str(), + AdminOperation(&IsAdminHandler {}), + )?; + + Ok(()) +} + #[derive(Deserialize, Debug, Default)] #[serde(rename_all = "PascalCase", default)] pub struct AssumeRoleRequest { diff --git a/rustfs/src/admin/handlers/system.rs b/rustfs/src/admin/handlers/system.rs index fd3eb2617..19ec614c0 100644 --- a/rustfs/src/admin/handlers/system.rs +++ b/rustfs/src/admin/handlers/system.rs @@ -12,12 +12,13 @@ // See the License for the specific language governing permissions and // limitations under the License. +use super::metrics; use crate::admin::auth::validate_admin_request; -use crate::admin::router::Operation; +use crate::admin::router::{AdminOperation, Operation, S3Router}; use crate::auth::{check_key_valid, get_session_token}; -use crate::server::RemoteAddr; +use crate::server::{ADMIN_PREFIX, RemoteAddr}; use http::{HeaderMap, HeaderValue}; -use hyper::StatusCode; +use hyper::{Method, StatusCode}; use matchit::Params; use rustfs_ecstore::admin_server_info::get_server_info; use rustfs_ecstore::data_usage::load_data_usage_from_backend; @@ -29,6 +30,52 @@ use s3s::header::CONTENT_TYPE; use s3s::{Body, S3Error, S3ErrorCode, S3Request, S3Response, S3Result, s3_error}; use tracing::{debug, error, info, warn}; +pub fn register_system_route(r: &mut S3Router) -> std::io::Result<()> { + r.insert( + Method::POST, + format!("{}{}", ADMIN_PREFIX, "/v3/service").as_str(), + AdminOperation(&ServiceHandle {}), + )?; + + r.insert( + Method::GET, + format!("{}{}", ADMIN_PREFIX, "/v3/info").as_str(), + AdminOperation(&ServerInfoHandler {}), + )?; + + r.insert( + Method::GET, + format!("{}{}", ADMIN_PREFIX, "/v3/inspect-data").as_str(), + AdminOperation(&InspectDataHandler {}), + )?; + + r.insert( + Method::POST, + format!("{}{}", ADMIN_PREFIX, "/v3/inspect-data").as_str(), + AdminOperation(&InspectDataHandler {}), + )?; + + r.insert( + Method::GET, + format!("{}{}", ADMIN_PREFIX, "/v3/storageinfo").as_str(), + AdminOperation(&StorageInfoHandler {}), + )?; + + r.insert( + Method::GET, + format!("{}{}", ADMIN_PREFIX, "/v3/datausageinfo").as_str(), + AdminOperation(&DataUsageInfoHandler {}), + )?; + + r.insert( + Method::GET, + format!("{}{}", ADMIN_PREFIX, "/v3/metrics").as_str(), + AdminOperation(&metrics::MetricsHandler {}), + )?; + + Ok(()) +} + pub struct ServiceHandle {} #[async_trait::async_trait] diff --git a/rustfs/src/admin/handlers/tier.rs b/rustfs/src/admin/handlers/tier.rs index 62516f917..a36ba730b 100644 --- a/rustfs/src/admin/handlers/tier.rs +++ b/rustfs/src/admin/handlers/tier.rs @@ -14,11 +14,15 @@ #![allow(unused_variables, unused_mut, unused_must_use)] use crate::{ - admin::{auth::validate_admin_request, router::Operation}, + admin::{ + auth::validate_admin_request, + router::{AdminOperation, Operation, S3Router}, + }, auth::{check_key_valid, get_session_token}, - server::RemoteAddr, + server::{ADMIN_PREFIX, RemoteAddr}, }; use http::{HeaderMap, StatusCode}; +use hyper::Method; use matchit::Params; use rustfs_config::MAX_ADMIN_REQUEST_BODY_SIZE; use rustfs_ecstore::{ @@ -71,6 +75,47 @@ pub struct AddTierQuery { } pub struct AddTier {} + +pub fn register_tier_route(r: &mut S3Router) -> std::io::Result<()> { + r.insert( + Method::GET, + format!("{}{}", ADMIN_PREFIX, "/v3/tier").as_str(), + AdminOperation(&ListTiers {}), + )?; + + r.insert( + Method::GET, + format!("{}{}", ADMIN_PREFIX, "/v3/tier-stats").as_str(), + AdminOperation(&GetTierInfo {}), + )?; + + r.insert( + Method::DELETE, + format!("{}{}", ADMIN_PREFIX, "/v3/tier/{tiername}").as_str(), + AdminOperation(&RemoveTier {}), + )?; + + r.insert( + Method::PUT, + format!("{}{}", ADMIN_PREFIX, "/v3/tier").as_str(), + AdminOperation(&AddTier {}), + )?; + + r.insert( + Method::POST, + format!("{}{}", ADMIN_PREFIX, "/v3/tier/{tiername}").as_str(), + AdminOperation(&EditTier {}), + )?; + + r.insert( + Method::POST, + format!("{}{}", ADMIN_PREFIX, "/v3/tier/clear").as_str(), + AdminOperation(&ClearTier {}), + )?; + + Ok(()) +} + #[async_trait::async_trait] impl Operation for AddTier { async fn call(&self, req: S3Request, _params: Params<'_, '_>) -> S3Result> { diff --git a/rustfs/src/admin/handlers/user.rs b/rustfs/src/admin/handlers/user.rs index e7ddf1be3..bde3af6e7 100644 --- a/rustfs/src/admin/handlers/user.rs +++ b/rustfs/src/admin/handlers/user.rs @@ -12,12 +12,18 @@ // See the License for the specific language governing permissions and // limitations under the License. +use super::{account_info::AccountInfoHandler, event, group, policies, service_account}; use crate::{ - admin::{auth::validate_admin_request, router::Operation, utils::has_space_be}, + admin::{ + auth::validate_admin_request, + router::{AdminOperation, Operation, S3Router}, + utils::has_space_be, + }, auth::{check_key_valid, constant_time_eq, get_session_token}, - server::RemoteAddr, + server::{ADMIN_PREFIX, RemoteAddr}, }; use http::{HeaderMap, StatusCode}; +use hyper::Method; use matchit::Params; use rustfs_config::{MAX_ADMIN_REQUEST_BODY_SIZE, MAX_IAM_IMPORT_SIZE}; use rustfs_credentials::get_global_action_cred; @@ -50,6 +56,73 @@ pub struct AddUserQuery { pub status: Option, } +pub fn register_user_route(r: &mut S3Router) -> std::io::Result<()> { + register_user_management_route(r)?; + group::register_group_management_route(r)?; + service_account::register_service_account_route(r)?; + register_user_iam_route(r)?; + policies::register_iam_policy_route(r)?; + event::register_notification_target_route(r)?; + + Ok(()) +} + +fn register_user_management_route(r: &mut S3Router) -> std::io::Result<()> { + r.insert( + Method::GET, + format!("{}{}", ADMIN_PREFIX, "/v3/accountinfo").as_str(), + AdminOperation(&AccountInfoHandler {}), + )?; + + r.insert( + Method::GET, + format!("{}{}", ADMIN_PREFIX, "/v3/list-users").as_str(), + AdminOperation(&ListUsers {}), + )?; + + r.insert( + Method::GET, + format!("{}{}", ADMIN_PREFIX, "/v3/user-info").as_str(), + AdminOperation(&GetUserInfo {}), + )?; + + r.insert( + Method::DELETE, + format!("{}{}", ADMIN_PREFIX, "/v3/remove-user").as_str(), + AdminOperation(&RemoveUser {}), + )?; + + r.insert( + Method::PUT, + format!("{}{}", ADMIN_PREFIX, "/v3/add-user").as_str(), + AdminOperation(&AddUser {}), + )?; + + r.insert( + Method::PUT, + format!("{}{}", ADMIN_PREFIX, "/v3/set-user-status").as_str(), + AdminOperation(&SetUserStatus {}), + )?; + + Ok(()) +} + +fn register_user_iam_route(r: &mut S3Router) -> std::io::Result<()> { + r.insert( + Method::GET, + format!("{}{}", ADMIN_PREFIX, "/v3/export-iam").as_str(), + AdminOperation(&ExportIam {}), + )?; + + r.insert( + Method::PUT, + format!("{}{}", ADMIN_PREFIX, "/v3/import-iam").as_str(), + AdminOperation(&ImportIam {}), + )?; + + Ok(()) +} + pub struct AddUser {} #[async_trait::async_trait] impl Operation for AddUser { diff --git a/rustfs/src/admin/mod.rs b/rustfs/src/admin/mod.rs index 2cbaf9ebc..d3e8d58cb 100644 --- a/rustfs/src/admin/mod.rs +++ b/rustfs/src/admin/mod.rs @@ -22,18 +22,7 @@ pub mod utils; #[cfg(test)] mod console_test; -use crate::server::{ADMIN_PREFIX, HEALTH_PREFIX, PROFILE_CPU_PATH, PROFILE_MEMORY_PATH}; -use handlers::{ - GetReplicationMetricsHandler, HealthCheckHandler, IsAdminHandler, ListRemoteTargetHandler, RemoveRemoteTargetHandler, - SetRemoteTargetHandler, bucket_meta, - event::{ListNotificationTargets, ListTargetsArns, NotificationTarget, RemoveNotificationTarget}, - group, kms, kms_dynamic, kms_keys, policies, pools, - profile::{TriggerProfileCPU, TriggerProfileMemory}, - quota, rebalance, - service_account::{AddServiceAccount, DeleteServiceAccount, InfoServiceAccount, ListServiceAccount, UpdateServiceAccount}, - sts, tier, user, -}; -use hyper::Method; +use handlers::{bucket_meta, heal, health, kms, pools, profile_admin, quota, rebalance, replication, sts, system, tier, user}; use router::{AdminOperation, S3Router}; use rpc::register_rpc_route; use s3s::route::S3Route; @@ -48,546 +37,25 @@ use s3s::route::S3Route; pub fn make_admin_route(console_enabled: bool) -> std::io::Result { let mut r: S3Router = S3Router::new(console_enabled); - // Health check endpoint for monitoring and orchestration - r.insert(Method::GET, HEALTH_PREFIX, AdminOperation(&HealthCheckHandler {}))?; - r.insert(Method::HEAD, HEALTH_PREFIX, AdminOperation(&HealthCheckHandler {}))?; - r.insert(Method::GET, PROFILE_CPU_PATH, AdminOperation(&TriggerProfileCPU {}))?; - r.insert(Method::GET, PROFILE_MEMORY_PATH, AdminOperation(&TriggerProfileMemory {}))?; - - // 1 - r.insert(Method::POST, "/", AdminOperation(&sts::AssumeRoleHandle {}))?; - - r.insert( - Method::GET, - format!("{}{}", ADMIN_PREFIX, "/v3/is-admin").as_str(), - AdminOperation(&IsAdminHandler {}), - )?; + health::register_health_route(&mut r)?; + sts::register_admin_auth_route(&mut r)?; register_rpc_route(&mut r)?; - register_user_route(&mut r)?; + user::register_user_route(&mut r)?; + system::register_system_route(&mut r)?; + pools::register_pool_route(&mut r)?; + rebalance::register_rebalance_route(&mut r)?; - r.insert( - Method::POST, - format!("{}{}", ADMIN_PREFIX, "/v3/service").as_str(), - AdminOperation(&handlers::ServiceHandle {}), - )?; - // 1 - r.insert( - Method::GET, - format!("{}{}", ADMIN_PREFIX, "/v3/info").as_str(), - AdminOperation(&handlers::ServerInfoHandler {}), - )?; - r.insert( - Method::GET, - format!("{}{}", ADMIN_PREFIX, "/v3/inspect-data").as_str(), - AdminOperation(&handlers::InspectDataHandler {}), - )?; - r.insert( - Method::POST, - format!("{}{}", ADMIN_PREFIX, "/v3/inspect-data").as_str(), - AdminOperation(&handlers::InspectDataHandler {}), - )?; - // 1 - r.insert( - Method::GET, - format!("{}{}", ADMIN_PREFIX, "/v3/storageinfo").as_str(), - AdminOperation(&handlers::StorageInfoHandler {}), - )?; - // 1 - r.insert( - Method::GET, - format!("{}{}", ADMIN_PREFIX, "/v3/datausageinfo").as_str(), - AdminOperation(&handlers::DataUsageInfoHandler {}), - )?; - r.insert( - Method::GET, - format!("{}{}", ADMIN_PREFIX, "/v3/metrics").as_str(), - AdminOperation(&handlers::MetricsHandler {}), - )?; + heal::register_heal_route(&mut r)?; - // 1 - r.insert( - Method::GET, - format!("{}{}", ADMIN_PREFIX, "/v3/pools/list").as_str(), - AdminOperation(&pools::ListPools {}), - )?; - // 1 - r.insert( - Method::GET, - format!("{}{}", ADMIN_PREFIX, "/v3/pools/status").as_str(), - AdminOperation(&pools::StatusPool {}), - )?; - // todo - r.insert( - Method::POST, - format!("{}{}", ADMIN_PREFIX, "/v3/pools/decommission").as_str(), - AdminOperation(&pools::StartDecommission {}), - )?; - // todo - r.insert( - Method::POST, - format!("{}{}", ADMIN_PREFIX, "/v3/pools/cancel").as_str(), - AdminOperation(&pools::CancelDecommission {}), - )?; + tier::register_tier_route(&mut r)?; - r.insert( - Method::POST, - format!("{}{}", ADMIN_PREFIX, "/v3/rebalance/start").as_str(), - AdminOperation(&rebalance::RebalanceStart {}), - )?; - r.insert( - Method::GET, - format!("{}{}", ADMIN_PREFIX, "/v3/rebalance/status").as_str(), - AdminOperation(&rebalance::RebalanceStatus {}), - )?; - r.insert( - Method::POST, - format!("{}{}", ADMIN_PREFIX, "/v3/rebalance/stop").as_str(), - AdminOperation(&rebalance::RebalanceStop {}), - )?; + quota::register_quota_route(&mut r)?; + bucket_meta::register_bucket_meta_route(&mut r)?; - // Some APIs are only available in EC mode - // if is_dist_erasure().await || is_erasure().await { - r.insert( - Method::POST, - format!("{}{}", ADMIN_PREFIX, "/v3/heal/{bucket}").as_str(), - AdminOperation(&handlers::HealHandler {}), - )?; - r.insert( - Method::POST, - format!("{}{}", ADMIN_PREFIX, "/v3/heal/{bucket}/{prefix}").as_str(), - AdminOperation(&handlers::HealHandler {}), - )?; - r.insert( - Method::POST, - format!("{}{}", ADMIN_PREFIX, "/v3/background-heal/status").as_str(), - AdminOperation(&handlers::BackgroundHealStatusHandler {}), - )?; - - // ? - r.insert( - Method::GET, - format!("{}{}", ADMIN_PREFIX, "/v3/tier").as_str(), - AdminOperation(&tier::ListTiers {}), - )?; - // ? - r.insert( - Method::GET, - format!("{}{}", ADMIN_PREFIX, "/v3/tier-stats").as_str(), - AdminOperation(&tier::GetTierInfo {}), - )?; - // ?force=xxx - r.insert( - Method::DELETE, - format!("{}{}", ADMIN_PREFIX, "/v3/tier/{tiername}").as_str(), - AdminOperation(&tier::RemoveTier {}), - )?; - // ?force=xxx - // body: AddOrUpdateTierReq - r.insert( - Method::PUT, - format!("{}{}", ADMIN_PREFIX, "/v3/tier").as_str(), - AdminOperation(&tier::AddTier {}), - )?; - // ? - // body: AddOrUpdateTierReq - r.insert( - Method::POST, - format!("{}{}", ADMIN_PREFIX, "/v3/tier/{tiername}").as_str(), - AdminOperation(&tier::EditTier {}), - )?; - r.insert( - Method::POST, - format!("{}{}", ADMIN_PREFIX, "/v3/tier/clear").as_str(), - AdminOperation(&tier::ClearTier {}), - )?; - - r.insert( - Method::PUT, - format!("{}{}", ADMIN_PREFIX, "/v3/quota/{bucket}").as_str(), - AdminOperation("a::SetBucketQuotaHandler {}), - )?; - r.insert( - Method::GET, - format!("{}{}", ADMIN_PREFIX, "/v3/quota/{bucket}").as_str(), - AdminOperation("a::GetBucketQuotaHandler {}), - )?; - r.insert( - Method::DELETE, - format!("{}{}", ADMIN_PREFIX, "/v3/quota/{bucket}").as_str(), - AdminOperation("a::ClearBucketQuotaHandler {}), - )?; - r.insert( - Method::GET, - format!("{}{}", ADMIN_PREFIX, "/v3/quota-stats/{bucket}").as_str(), - AdminOperation("a::GetBucketQuotaStatsHandler {}), - )?; - r.insert( - Method::POST, - format!("{}{}", ADMIN_PREFIX, "/v3/quota-check/{bucket}").as_str(), - AdminOperation("a::CheckBucketQuotaHandler {}), - )?; - - r.insert( - Method::GET, - format!("{}{}", ADMIN_PREFIX, "/export-bucket-metadata").as_str(), - AdminOperation(&bucket_meta::ExportBucketMetadata {}), - )?; - - r.insert( - Method::PUT, - format!("{}{}", ADMIN_PREFIX, "/import-bucket-metadata").as_str(), - AdminOperation(&bucket_meta::ImportBucketMetadata {}), - )?; - - register_replication_route(&mut r)?; - register_profiling_route(&mut r)?; - register_kms_route(&mut r)?; + replication::register_replication_route(&mut r)?; + profile_admin::register_profiling_route(&mut r)?; + kms::register_kms_route(&mut r)?; Ok(r) } - -fn register_replication_route(r: &mut S3Router) -> std::io::Result<()> { - r.insert( - Method::GET, - format!("{}{}", ADMIN_PREFIX, "/v3/list-remote-targets").as_str(), - AdminOperation(&ListRemoteTargetHandler {}), - )?; - - r.insert( - Method::GET, - format!("{}{}", ADMIN_PREFIX, "/v3/replicationmetrics").as_str(), - AdminOperation(&GetReplicationMetricsHandler {}), - )?; - - r.insert( - Method::PUT, - format!("{}{}", ADMIN_PREFIX, "/v3/set-remote-target").as_str(), - AdminOperation(&SetRemoteTargetHandler {}), - )?; - - r.insert( - Method::DELETE, - format!("{}{}", ADMIN_PREFIX, "/v3/remove-remote-target").as_str(), - AdminOperation(&RemoveRemoteTargetHandler {}), - )?; - - Ok(()) -} - -fn register_profiling_route(r: &mut S3Router) -> std::io::Result<()> { - // Performance profiling endpoints (available on all platforms, with platform-specific responses) - r.insert( - Method::GET, - format!("{}{}", ADMIN_PREFIX, "/debug/pprof/profile").as_str(), - AdminOperation(&handlers::ProfileHandler {}), - )?; - - r.insert( - Method::GET, - format!("{}{}", ADMIN_PREFIX, "/debug/pprof/status").as_str(), - AdminOperation(&handlers::ProfileStatusHandler {}), - )?; - - Ok(()) -} - -fn register_kms_route(r: &mut S3Router) -> std::io::Result<()> { - // KMS management endpoints - r.insert( - Method::POST, - format!("{}{}", ADMIN_PREFIX, "/v3/kms/create-key").as_str(), - AdminOperation(&kms::CreateKeyHandler {}), - )?; - - r.insert( - Method::GET, - format!("{}{}", ADMIN_PREFIX, "/v3/kms/describe-key").as_str(), - AdminOperation(&kms::DescribeKeyHandler {}), - )?; - - r.insert( - Method::GET, - format!("{}{}", ADMIN_PREFIX, "/v3/kms/list-keys").as_str(), - AdminOperation(&kms::ListKeysHandler {}), - )?; - - r.insert( - Method::POST, - format!("{}{}", ADMIN_PREFIX, "/v3/kms/generate-data-key").as_str(), - AdminOperation(&kms::GenerateDataKeyHandler {}), - )?; - - r.insert( - Method::GET, - format!("{}{}", ADMIN_PREFIX, "/v3/kms/status").as_str(), - AdminOperation(&kms::KmsStatusHandler {}), - )?; - - r.insert( - Method::GET, - format!("{}{}", ADMIN_PREFIX, "/v3/kms/config").as_str(), - AdminOperation(&kms::KmsConfigHandler {}), - )?; - - r.insert( - Method::POST, - format!("{}{}", ADMIN_PREFIX, "/v3/kms/clear-cache").as_str(), - AdminOperation(&kms::KmsClearCacheHandler {}), - )?; - - // KMS Dynamic Configuration APIs - r.insert( - Method::POST, - format!("{}{}", ADMIN_PREFIX, "/v3/kms/configure").as_str(), - AdminOperation(&kms_dynamic::ConfigureKmsHandler {}), - )?; - - r.insert( - Method::POST, - format!("{}{}", ADMIN_PREFIX, "/v3/kms/start").as_str(), - AdminOperation(&kms_dynamic::StartKmsHandler {}), - )?; - - r.insert( - Method::POST, - format!("{}{}", ADMIN_PREFIX, "/v3/kms/stop").as_str(), - AdminOperation(&kms_dynamic::StopKmsHandler {}), - )?; - - r.insert( - Method::GET, - format!("{}{}", ADMIN_PREFIX, "/v3/kms/service-status").as_str(), - AdminOperation(&kms_dynamic::GetKmsStatusHandler {}), - )?; - - r.insert( - Method::POST, - format!("{}{}", ADMIN_PREFIX, "/v3/kms/reconfigure").as_str(), - AdminOperation(&kms_dynamic::ReconfigureKmsHandler {}), - )?; - - // KMS key management endpoints - r.insert( - Method::POST, - format!("{}{}", ADMIN_PREFIX, "/v3/kms/keys").as_str(), - AdminOperation(&kms_keys::CreateKmsKeyHandler {}), - )?; - - r.insert( - Method::DELETE, - format!("{}{}", ADMIN_PREFIX, "/v3/kms/keys/delete").as_str(), - AdminOperation(&kms_keys::DeleteKmsKeyHandler {}), - )?; - - r.insert( - Method::POST, - format!("{}{}", ADMIN_PREFIX, "/v3/kms/keys/cancel-deletion").as_str(), - AdminOperation(&kms_keys::CancelKmsKeyDeletionHandler {}), - )?; - - r.insert( - Method::GET, - format!("{}{}", ADMIN_PREFIX, "/v3/kms/keys").as_str(), - AdminOperation(&kms_keys::ListKmsKeysHandler {}), - )?; - - r.insert( - Method::GET, - format!("{}{}", ADMIN_PREFIX, "/v3/kms/keys/{key_id}").as_str(), - AdminOperation(&kms_keys::DescribeKmsKeyHandler {}), - )?; - - Ok(()) -} - -/// user router -fn register_user_route(r: &mut S3Router) -> std::io::Result<()> { - // 1 - r.insert( - Method::GET, - format!("{}{}", ADMIN_PREFIX, "/v3/accountinfo").as_str(), - AdminOperation(&handlers::AccountInfoHandler {}), - )?; - - // ?[bucket=xxx] - r.insert( - Method::GET, - format!("{}{}", ADMIN_PREFIX, "/v3/list-users").as_str(), - AdminOperation(&user::ListUsers {}), - )?; - - // ?accessKey=xxx - r.insert( - Method::GET, - format!("{}{}", ADMIN_PREFIX, "/v3/user-info").as_str(), - AdminOperation(&user::GetUserInfo {}), - )?; - - // ?accessKey=xxx - r.insert( - Method::DELETE, - format!("{}{}", ADMIN_PREFIX, "/v3/remove-user").as_str(), - AdminOperation(&user::RemoveUser {}), - )?; - - // ?accessKey=xxx - // body: AddOrUpdateUserReq - r.insert( - Method::PUT, - format!("{}{}", ADMIN_PREFIX, "/v3/add-user").as_str(), - AdminOperation(&user::AddUser {}), - )?; - // ?accessKey=xxx&status=enabled - r.insert( - Method::PUT, - format!("{}{}", ADMIN_PREFIX, "/v3/set-user-status").as_str(), - AdminOperation(&user::SetUserStatus {}), - )?; - - r.insert( - Method::GET, - format!("{}{}", ADMIN_PREFIX, "/v3/groups").as_str(), - AdminOperation(&group::ListGroups {}), - )?; - - // ?group=xxx - r.insert( - Method::GET, - format!("{}{}", ADMIN_PREFIX, "/v3/group").as_str(), - AdminOperation(&group::GetGroup {}), - )?; - - // ?group=xxx&status=xxx - r.insert( - Method::PUT, - format!("{}{}", ADMIN_PREFIX, "/v3/set-group-status").as_str(), - AdminOperation(&group::SetGroupStatus {}), - )?; - - // @body GroupAddRemove - r.insert( - Method::PUT, - format!("{}{}", ADMIN_PREFIX, "/v3/update-group-members").as_str(), - AdminOperation(&group::UpdateGroupMembers {}), - )?; - - // Service accounts - // ?accessKey=xxx - // @body: UpdateServiceAccountReq - r.insert( - Method::POST, - format!("{}{}", ADMIN_PREFIX, "/v3/update-service-account").as_str(), - AdminOperation(&UpdateServiceAccount {}), - )?; - // ?accessKey=xxx - r.insert( - Method::GET, - format!("{}{}", ADMIN_PREFIX, "/v3/info-service-account").as_str(), - AdminOperation(&InfoServiceAccount {}), - )?; - - // ?[user=xxx] - r.insert( - Method::GET, - format!("{}{}", ADMIN_PREFIX, "/v3/list-service-accounts").as_str(), - AdminOperation(&ListServiceAccount {}), - )?; - // ?accessKey=xxx - r.insert( - Method::DELETE, - format!("{}{}", ADMIN_PREFIX, "/v3/delete-service-accounts").as_str(), - AdminOperation(&DeleteServiceAccount {}), - )?; - // @body: AddServiceAccountReq - r.insert( - Method::PUT, - format!("{}{}", ADMIN_PREFIX, "/v3/add-service-accounts").as_str(), - AdminOperation(&AddServiceAccount {}), - )?; - - r.insert( - Method::GET, - format!("{}{}", ADMIN_PREFIX, "/v3/export-iam").as_str(), - AdminOperation(&user::ExportIam {}), - )?; - - r.insert( - Method::PUT, - format!("{}{}", ADMIN_PREFIX, "/v3/import-iam").as_str(), - AdminOperation(&user::ImportIam {}), - )?; - - // list-canned-policies?bucket=xxx - r.insert( - Method::GET, - format!("{}{}", ADMIN_PREFIX, "/v3/list-canned-policies").as_str(), - AdminOperation(&policies::ListCannedPolicies {}), - )?; - - // info-canned-policy?name=xxx - r.insert( - Method::GET, - format!("{}{}", ADMIN_PREFIX, "/v3/info-canned-policy").as_str(), - AdminOperation(&policies::InfoCannedPolicy {}), - )?; - - // add-canned-policy?name=xxx - r.insert( - Method::PUT, - format!("{}{}", ADMIN_PREFIX, "/v3/add-canned-policy").as_str(), - AdminOperation(&policies::AddCannedPolicy {}), - )?; - - // remove-canned-policy?name=xxx - r.insert( - Method::DELETE, - format!("{}{}", ADMIN_PREFIX, "/v3/remove-canned-policy").as_str(), - AdminOperation(&policies::RemoveCannedPolicy {}), - )?; - - // set-user-or-group-policy?policyName=xxx&userOrGroup=xxx&isGroup=xxx - r.insert( - Method::PUT, - format!("{}{}", ADMIN_PREFIX, "/v3/set-user-or-group-policy").as_str(), - AdminOperation(&policies::SetPolicyForUserOrGroup {}), - )?; - - register_notification_target_route(r)?; - - Ok(()) -} - -fn register_notification_target_route(r: &mut S3Router) -> std::io::Result<()> { - r.insert( - Method::GET, - format!("{}{}", ADMIN_PREFIX, "/v3/target/list").as_str(), - AdminOperation(&ListNotificationTargets {}), - )?; - - r.insert( - Method::PUT, - format!("{}{}", ADMIN_PREFIX, "/v3/target/{target_type}/{target_name}").as_str(), - AdminOperation(&NotificationTarget {}), - )?; - - // Remove notification target - // This endpoint removes a notification target based on its type and name. - // target-remove?target_type=xxx&target_name=xxx - // * `target_type` - Target type, such as "notify_webhook" or "notify_mqtt". - // * `target_name` - A unique name for a Target, such as "1". - r.insert( - Method::DELETE, - format!("{}{}", ADMIN_PREFIX, "/v3/target/{target_type}/{target_name}/reset").as_str(), - AdminOperation(&RemoveNotificationTarget {}), - )?; - - // arns list - r.insert( - Method::GET, - format!("{}{}", ADMIN_PREFIX, "/v3/target/arns").as_str(), - AdminOperation(&ListTargetsArns {}), - )?; - - Ok(()) -}