init admin_route done

This commit is contained in:
weisd
2024-11-06 11:28:39 +08:00
parent c410784cc9
commit b416c45bbb
7 changed files with 322 additions and 100 deletions
-1
View File
@@ -1 +0,0 @@
pub trait Handler: Send + Sync + 'static {}
+181
View File
@@ -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<Body>, _params: Params<'_, '_>) -> S3Result<S3Response<(StatusCode, Body)>> {
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<Body>, _params: Params<'_, '_>) -> S3Result<S3Response<(StatusCode, Body)>> {
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<Body>, _params: Params<'_, '_>) -> S3Result<S3Response<(StatusCode, Body)>> {
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<Body>, _params: Params<'_, '_>) -> S3Result<S3Response<(StatusCode, Body)>> {
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<Body>, _params: Params<'_, '_>) -> S3Result<S3Response<(StatusCode, Body)>> {
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<Body>, _params: Params<'_, '_>) -> S3Result<S3Response<(StatusCode, Body)>> {
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<Body>, _params: Params<'_, '_>) -> S3Result<S3Response<(StatusCode, Body)>> {
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<Body>, _params: Params<'_, '_>) -> S3Result<S3Response<(StatusCode, Body)>> {
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<Body>, _params: Params<'_, '_>) -> S3Result<S3Response<(StatusCode, Body)>> {
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<Body>, _params: Params<'_, '_>) -> S3Result<S3Response<(StatusCode, Body)>> {
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<Body>, _params: Params<'_, '_>) -> S3Result<S3Response<(StatusCode, Body)>> {
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<Body>, _params: Params<'_, '_>) -> S3Result<S3Response<(StatusCode, Body)>> {
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<Body>, _params: Params<'_, '_>) -> S3Result<S3Response<(StatusCode, Body)>> {
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<Body>, _params: Params<'_, '_>) -> S3Result<S3Response<(StatusCode, Body)>> {
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<Body>, _params: Params<'_, '_>) -> S3Result<S3Response<(StatusCode, Body)>> {
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<Body>, _params: Params<'_, '_>) -> S3Result<S3Response<(StatusCode, Body)>> {
warn!("handle RebalanceStop");
return Err(s3_error!(NotImplemented));
}
}
+100 -2
View File
@@ -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<impl S3Route> {
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)
}
-10
View File
@@ -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<Body>, params: Params<'_, '_>) -> S3Result<S3Response<(StatusCode, Body)>>;
}
+40 -17
View File
@@ -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<T> {
router: Router<T>,
@@ -33,10 +25,10 @@ impl<T: Operation> S3Router<T> {
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<T: Operation> S3Router<T> {
}
fn make_route_str(method: Method, path: &str) -> String {
format!("{}|{}{}", method.as_str(), ADMIN_PREFIX, path)
format!("{}|{}", method.as_str(), path)
}
}
impl<T: Operation> Default for S3Router<T> {
fn default() -> Self {
Self::new()
}
}
@@ -53,7 +51,16 @@ impl<T> S3Route for S3Router<T>
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<Body>, params: Params<'_, '_>) -> S3Result<S3Response<(StatusCode, Body)>>;
}
pub struct AdminOperation(pub &'static dyn Operation);
#[async_trait::async_trait]
impl Operation for AdminOperation {
async fn call(&self, req: S3Request<Body>, params: Params<'_, '_>) -> S3Result<S3Response<(StatusCode, Body)>> {
self.0.call(req, params).await
}
}
+1 -2
View File
@@ -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 {
-68
View File
@@ -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<impl S3Route> {
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<Body>, params: Params<'_, '_>) -> S3Result<S3Response<(StatusCode, Body)>> {
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<Body>, _params: Params<'_, '_>) -> S3Result<S3Response<(StatusCode, Body)>> {
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<Body>, _params: Params<'_, '_>) -> S3Result<S3Response<(StatusCode, Body)>> {
warn!("handle info");
unimplemented!()
}
}