diff --git a/router/src/handler.rs b/router/src/handler.rs
deleted file mode 100644
index 64256d61a..000000000
--- a/router/src/handler.rs
+++ /dev/null
@@ -1 +0,0 @@
-pub trait Handler: Send + Sync + 'static {}
diff --git a/router/src/handlers.rs b/router/src/handlers.rs
new file mode 100644
index 000000000..5e4a0213d
--- /dev/null
+++ b/router/src/handlers.rs
@@ -0,0 +1,181 @@
+use hyper::StatusCode;
+use matchit::Params;
+use s3s::{s3_error, Body, S3Request, S3Response, S3Result};
+use tracing::warn;
+
+use crate::router::Operation;
+
+pub struct AssumeRoleHandle {}
+#[async_trait::async_trait]
+impl Operation for AssumeRoleHandle {
+ async fn call(&self, _req: S3Request
, _params: Params<'_, '_>) -> S3Result> {
+ warn!("handle AssumeRoleHandle");
+
+ return Err(s3_error!(NotImplemented));
+ }
+}
+
+pub struct ServiceHandle {}
+#[async_trait::async_trait]
+impl Operation for ServiceHandle {
+ async fn call(&self, _req: S3Request, _params: Params<'_, '_>) -> S3Result> {
+ warn!("handle ServiceHandle");
+
+ return Err(s3_error!(NotImplemented));
+ }
+}
+
+pub struct ServerInfoHandler {}
+
+#[async_trait::async_trait]
+impl Operation for ServerInfoHandler {
+ async fn call(&self, _req: S3Request, _params: Params<'_, '_>) -> S3Result> {
+ warn!("handle ServerInfoHandler");
+
+ return Err(s3_error!(NotImplemented));
+ }
+}
+
+pub struct InspectDataHandler {}
+
+#[async_trait::async_trait]
+impl Operation for InspectDataHandler {
+ async fn call(&self, _req: S3Request, _params: Params<'_, '_>) -> S3Result> {
+ warn!("handle InspectDataHandler");
+
+ return Err(s3_error!(NotImplemented));
+ }
+}
+
+pub struct StorageInfoHandler {}
+
+#[async_trait::async_trait]
+impl Operation for StorageInfoHandler {
+ async fn call(&self, _req: S3Request, _params: Params<'_, '_>) -> S3Result> {
+ warn!("handle StorageInfoHandler");
+
+ return Err(s3_error!(NotImplemented));
+ }
+}
+
+pub struct DataUsageInfoHandler {}
+
+#[async_trait::async_trait]
+impl Operation for DataUsageInfoHandler {
+ async fn call(&self, _req: S3Request, _params: Params<'_, '_>) -> S3Result> {
+ warn!("handle DataUsageInfoHandler");
+
+ return Err(s3_error!(NotImplemented));
+ }
+}
+
+pub struct MetricsHandler {}
+
+#[async_trait::async_trait]
+impl Operation for MetricsHandler {
+ async fn call(&self, _req: S3Request, _params: Params<'_, '_>) -> S3Result> {
+ warn!("handle MetricsHandler");
+
+ return Err(s3_error!(NotImplemented));
+ }
+}
+
+pub struct HealHandler {}
+
+#[async_trait::async_trait]
+impl Operation for HealHandler {
+ async fn call(&self, _req: S3Request, _params: Params<'_, '_>) -> S3Result> {
+ warn!("handle HealHandler");
+
+ return Err(s3_error!(NotImplemented));
+ }
+}
+
+pub struct BackgroundHealStatusHandler {}
+
+#[async_trait::async_trait]
+impl Operation for BackgroundHealStatusHandler {
+ async fn call(&self, _req: S3Request, _params: Params<'_, '_>) -> S3Result> {
+ warn!("handle BackgroundHealStatusHandler");
+
+ return Err(s3_error!(NotImplemented));
+ }
+}
+
+pub struct ListPools {}
+
+#[async_trait::async_trait]
+impl Operation for ListPools {
+ async fn call(&self, _req: S3Request, _params: Params<'_, '_>) -> S3Result> {
+ warn!("handle ListPools");
+
+ return Err(s3_error!(NotImplemented));
+ }
+}
+
+pub struct StatusPool {}
+
+#[async_trait::async_trait]
+impl Operation for StatusPool {
+ async fn call(&self, _req: S3Request, _params: Params<'_, '_>) -> S3Result> {
+ warn!("handle StatusPool");
+
+ return Err(s3_error!(NotImplemented));
+ }
+}
+
+pub struct StartDecommission {}
+
+#[async_trait::async_trait]
+impl Operation for StartDecommission {
+ async fn call(&self, _req: S3Request, _params: Params<'_, '_>) -> S3Result> {
+ warn!("handle StartDecommission");
+
+ return Err(s3_error!(NotImplemented));
+ }
+}
+
+pub struct CancelDecommission {}
+
+#[async_trait::async_trait]
+impl Operation for CancelDecommission {
+ async fn call(&self, _req: S3Request, _params: Params<'_, '_>) -> S3Result> {
+ warn!("handle CancelDecommission");
+
+ return Err(s3_error!(NotImplemented));
+ }
+}
+
+pub struct RebalanceStart {}
+
+#[async_trait::async_trait]
+impl Operation for RebalanceStart {
+ async fn call(&self, _req: S3Request, _params: Params<'_, '_>) -> S3Result> {
+ warn!("handle RebalanceStart");
+
+ return Err(s3_error!(NotImplemented));
+ }
+}
+
+// RebalanceStatus
+pub struct RebalanceStatus {}
+
+#[async_trait::async_trait]
+impl Operation for RebalanceStatus {
+ async fn call(&self, _req: S3Request, _params: Params<'_, '_>) -> S3Result> {
+ warn!("handle RebalanceStatus");
+
+ return Err(s3_error!(NotImplemented));
+ }
+}
+// RebalanceStop
+pub struct RebalanceStop {}
+
+#[async_trait::async_trait]
+impl Operation for RebalanceStop {
+ async fn call(&self, _req: S3Request, _params: Params<'_, '_>) -> S3Result> {
+ warn!("handle RebalanceStop");
+
+ return Err(s3_error!(NotImplemented));
+ }
+}
diff --git a/router/src/lib.rs b/router/src/lib.rs
index 40f3f4be8..d111ad750 100644
--- a/router/src/lib.rs
+++ b/router/src/lib.rs
@@ -1,3 +1,101 @@
-pub mod handler;
-pub mod operation;
+pub mod handlers;
pub mod router;
+
+use common::error::Result;
+use hyper::Method;
+use router::{AdminOperation, S3Router};
+use s3s::route::S3Route;
+
+const ADMIN_PREFIX: &str = "/rustfs/admin";
+
+pub fn make_admin_route() -> Result {
+ let mut r = S3Router::new();
+
+ r.insert(Method::POST, "/", AdminOperation(&handlers::AssumeRoleHandle {}))?;
+
+ r.insert(
+ Method::POST,
+ format!("{}{}", ADMIN_PREFIX, "/v3/service").as_str(),
+ AdminOperation(&handlers::ServiceHandle {}),
+ )?;
+ 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 {}),
+ )?;
+ r.insert(
+ Method::GET,
+ format!("{}{}", ADMIN_PREFIX, "/v3/storageinfo").as_str(),
+ AdminOperation(&handlers::StorageInfoHandler {}),
+ )?;
+ 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 {}),
+ )?;
+
+ 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/pools/list").as_str(),
+ AdminOperation(&handlers::ListPools {}),
+ )?;
+ r.insert(
+ Method::GET,
+ format!("{}{}", ADMIN_PREFIX, "/v3/pools/status").as_str(),
+ AdminOperation(&handlers::StatusPool {}),
+ )?;
+ r.insert(
+ Method::POST,
+ format!("{}{}", ADMIN_PREFIX, "/v3/pools/decommission").as_str(),
+ AdminOperation(&handlers::StartDecommission {}),
+ )?;
+ r.insert(
+ Method::POST,
+ format!("{}{}", ADMIN_PREFIX, "/v3/pools/cancel").as_str(),
+ AdminOperation(&handlers::CancelDecommission {}),
+ )?;
+
+ r.insert(
+ Method::POST,
+ format!("{}{}", ADMIN_PREFIX, "/v3/rebalance/start").as_str(),
+ AdminOperation(&handlers::RebalanceStart {}),
+ )?;
+ r.insert(
+ Method::GET,
+ format!("{}{}", ADMIN_PREFIX, "/v3/rebalance/status").as_str(),
+ AdminOperation(&handlers::RebalanceStatus {}),
+ )?;
+ r.insert(
+ Method::POST,
+ format!("{}{}", ADMIN_PREFIX, "/v3/rebalance/stop").as_str(),
+ AdminOperation(&handlers::RebalanceStop {}),
+ )?;
+
+ Ok(r)
+}
diff --git a/router/src/operation.rs b/router/src/operation.rs
deleted file mode 100644
index 6b3398520..000000000
--- a/router/src/operation.rs
+++ /dev/null
@@ -1,10 +0,0 @@
-use hyper::{Method, StatusCode};
-use matchit::Params;
-use s3s::{Body, S3Request, S3Response, S3Result};
-
-#[async_trait::async_trait]
-pub trait Operation: Send + Sync + 'static {
- fn method(&self) -> Method;
- fn uri(&self) -> &'static str;
- async fn call(&self, req: S3Request, params: Params<'_, '_>) -> S3Result>;
-}
diff --git a/router/src/router.rs b/router/src/router.rs
index 2f137279b..11dbf19f1 100644
--- a/router/src/router.rs
+++ b/router/src/router.rs
@@ -1,26 +1,18 @@
-use std::collections::HashMap;
-use std::str::FromStr;
-
+use common::error::Result;
use hyper::http::Extensions;
use hyper::HeaderMap;
use hyper::Method;
use hyper::StatusCode;
use hyper::Uri;
-
+use matchit::Params;
+use matchit::Router;
+use s3s::header;
use s3s::route::S3Route;
use s3s::s3_error;
use s3s::Body;
use s3s::S3Request;
use s3s::S3Response;
use s3s::S3Result;
-use tracing::warn;
-
-use crate::operation::Operation;
-use common::error::Result;
-use matchit::Router;
-
-const ADMIN_PREFIX: &str = "/rustfs/admin";
-// const ADMIN_VERSION: &str = "v3";
pub struct S3Router {
router: Router,
@@ -33,10 +25,10 @@ impl S3Router {
Self { router }
}
- pub fn insert(&mut self, operation: T) -> Result<()> {
- let path = Self::make_route_str(operation.method(), &operation.uri());
+ pub fn insert(&mut self, method: Method, path: &str, operation: T) -> Result<()> {
+ let path = Self::make_route_str(method, path);
- warn!("set uri {}", &path);
+ // warn!("set uri {}", &path);
self.router.insert(path, operation)?;
@@ -44,7 +36,13 @@ impl S3Router {
}
fn make_route_str(method: Method, path: &str) -> String {
- format!("{}|{}{}", method.as_str(), ADMIN_PREFIX, path)
+ format!("{}|{}", method.as_str(), path)
+ }
+}
+
+impl Default for S3Router {
+ fn default() -> Self {
+ Self::new()
}
}
@@ -53,7 +51,16 @@ impl S3Route for S3Router
where
T: Operation,
{
- fn is_match(&self, _method: &Method, uri: &Uri, _headers: &HeaderMap, _: &mut Extensions) -> bool {
+ fn is_match(&self, method: &Method, uri: &Uri, headers: &HeaderMap, _: &mut Extensions) -> bool {
+ // AssumeRole
+ if method == Method::POST && uri.path() == "/" {
+ if let Some(val) = headers.get(header::CONTENT_TYPE) {
+ if val.as_bytes() == b"application/x-www-form-urlencoded" {
+ return true;
+ }
+ }
+ }
+
uri.path().starts_with("/rustfs/admin")
}
@@ -70,3 +77,19 @@ where
return Err(s3_error!(NotImplemented));
}
}
+
+#[async_trait::async_trait]
+pub trait Operation: Send + Sync + 'static {
+ // fn method() -> Method;
+ // fn uri() -> &'static str;
+ async fn call(&self, req: S3Request, params: Params<'_, '_>) -> S3Result>;
+}
+
+pub struct AdminOperation(pub &'static dyn Operation);
+
+#[async_trait::async_trait]
+impl Operation for AdminOperation {
+ async fn call(&self, req: S3Request, params: Params<'_, '_>) -> S3Result> {
+ self.0.call(req, params).await
+ }
+}
diff --git a/rustfs/src/main.rs b/rustfs/src/main.rs
index de4e7631c..46daded39 100644
--- a/rustfs/src/main.rs
+++ b/rustfs/src/main.rs
@@ -1,6 +1,5 @@
mod config;
mod grpc;
-mod route;
mod service;
mod storage;
@@ -114,7 +113,7 @@ async fn run(opt: config::Opt) -> Result<()> {
b.set_access(store.clone());
- b.set_route(route::make_admin_route()?);
+ b.set_route(router::make_admin_route()?);
// // Enable parsing virtual-hosted-style requests
// if let Some(dm) = opt.domain_name {
diff --git a/rustfs/src/route.rs b/rustfs/src/route.rs
deleted file mode 100644
index cba7a5efb..000000000
--- a/rustfs/src/route.rs
+++ /dev/null
@@ -1,68 +0,0 @@
-use common::error::{Error, Result};
-
-use matchit::Params;
-use router::{operation::Operation, router::S3Router};
-use s3s::route::S3Route;
-use s3s::{Body, S3Request, S3Response, S3Result};
-use tracing::warn;
-
-use hyper::Method;
-use hyper::StatusCode;
-
-pub fn make_admin_route() -> Result {
- let mut r = S3Router::new();
-
- r.insert(AdminOperation(&InfoHandler {}))?;
- r.insert(AdminOperation(&ListPoolHandler {}))?;
-
- Ok(r)
-}
-
-struct AdminOperation(&'static dyn Operation);
-
-#[async_trait::async_trait]
-impl Operation for AdminOperation {
- fn method(&self) -> Method {
- self.0.method()
- }
- fn uri(&self) -> &'static str {
- self.0.uri()
- }
- async fn call(&self, req: S3Request, params: Params<'_, '_>) -> S3Result> {
- self.0.call(req, params).await
- }
-}
-
-struct InfoHandler {}
-
-#[async_trait::async_trait]
-impl Operation for InfoHandler {
- fn method(&self) -> Method {
- Method::GET
- }
- fn uri(&self) -> &'static str {
- "/v3/info"
- }
- async fn call(&self, _req: S3Request, _params: Params<'_, '_>) -> S3Result> {
- warn!("handle info");
-
- unimplemented!()
- }
-}
-
-struct ListPoolHandler {}
-
-#[async_trait::async_trait]
-impl Operation for ListPoolHandler {
- fn method(&self) -> Method {
- Method::GET
- }
- fn uri(&self) -> &'static str {
- "/v3/pool/list"
- }
- async fn call(&self, _req: S3Request, _params: Params<'_, '_>) -> S3Result> {
- warn!("handle info");
-
- unimplemented!()
- }
-}