admin api: base infrastructure for local endpoints
This commit is contained in:
parent
3018dfd663
commit
8e61d149f2
5 changed files with 197 additions and 0 deletions
|
@ -1,3 +1,4 @@
|
|||
use std::collections::HashMap;
|
||||
use std::convert::TryFrom;
|
||||
use std::net::SocketAddr;
|
||||
use std::sync::Arc;
|
||||
|
@ -70,8 +71,13 @@ admin_endpoints![
|
|||
// Operations on bucket aliases
|
||||
AddBucketAlias,
|
||||
RemoveBucketAlias,
|
||||
|
||||
// Worker operations
|
||||
GetWorkerParam,
|
||||
];
|
||||
|
||||
local_admin_endpoints![GetWorkerParam,];
|
||||
|
||||
// **********************************************
|
||||
// Special endpoints
|
||||
//
|
||||
|
@ -579,3 +585,15 @@ pub struct RemoveBucketAliasRequest {
|
|||
|
||||
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||
pub struct RemoveBucketAliasResponse(pub GetBucketInfoResponse);
|
||||
|
||||
// **********************************************
|
||||
// Worker operations
|
||||
// **********************************************
|
||||
|
||||
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||
pub struct LocalGetWorkerParamRequest {
|
||||
param: Option<String>,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||
pub struct LocalGetWorkerParamResponse(HashMap<String, String>);
|
||||
|
|
|
@ -91,4 +91,86 @@ macro_rules! admin_endpoints {
|
|||
};
|
||||
}
|
||||
|
||||
macro_rules! local_admin_endpoints {
|
||||
[
|
||||
$($endpoint:ident,)*
|
||||
] => {
|
||||
paste! {
|
||||
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||
pub enum LocalAdminApiRequest {
|
||||
$(
|
||||
$endpoint( [<Local $endpoint Request>] ),
|
||||
)*
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||
pub enum LocalAdminApiResponse {
|
||||
$(
|
||||
$endpoint( [<Local $endpoint Response>] ),
|
||||
)*
|
||||
}
|
||||
|
||||
$(
|
||||
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||
pub struct [< $endpoint Request >] {
|
||||
node: String,
|
||||
body: [< Local $endpoint Request >],
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||
pub struct [< $endpoint Response >](HashMap<String, [< Local $endpoint Response >] >);
|
||||
|
||||
impl From< [< Local $endpoint Request >] > for LocalAdminApiRequest {
|
||||
fn from(req: [< Local $endpoint Request >]) -> LocalAdminApiRequest {
|
||||
LocalAdminApiRequest::$endpoint(req)
|
||||
}
|
||||
}
|
||||
|
||||
impl TryFrom<LocalAdminApiResponse> for [< Local $endpoint Response >] {
|
||||
type Error = LocalAdminApiResponse;
|
||||
fn try_from(resp: LocalAdminApiResponse) -> Result< [< Local $endpoint Response >], LocalAdminApiResponse> {
|
||||
match resp {
|
||||
LocalAdminApiResponse::$endpoint(v) => Ok(v),
|
||||
x => Err(x),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[async_trait]
|
||||
impl EndpointHandler for [< $endpoint Request >] {
|
||||
type Response = [< $endpoint Response >];
|
||||
|
||||
async fn handle(self, garage: &Arc<Garage>) -> Result<Self::Response, Error> {
|
||||
todo!()
|
||||
}
|
||||
}
|
||||
)*
|
||||
|
||||
impl LocalAdminApiRequest {
|
||||
pub fn name(&self) -> &'static str {
|
||||
match self {
|
||||
$(
|
||||
Self::$endpoint(_) => stringify!($endpoint),
|
||||
)*
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[async_trait]
|
||||
impl EndpointHandler for LocalAdminApiRequest {
|
||||
type Response = LocalAdminApiResponse;
|
||||
|
||||
async fn handle(self, garage: &Arc<Garage>) -> Result<LocalAdminApiResponse, Error> {
|
||||
Ok(match self {
|
||||
$(
|
||||
LocalAdminApiRequest::$endpoint(req) => LocalAdminApiResponse::$endpoint(req.handle(garage).await?),
|
||||
)*
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
pub(crate) use admin_endpoints;
|
||||
pub(crate) use local_admin_endpoints;
|
||||
|
|
|
@ -7,11 +7,15 @@ mod router_v0;
|
|||
mod router_v1;
|
||||
mod router_v2;
|
||||
|
||||
pub mod rpc;
|
||||
|
||||
mod bucket;
|
||||
mod cluster;
|
||||
mod key;
|
||||
mod special;
|
||||
|
||||
mod worker;
|
||||
|
||||
use std::sync::Arc;
|
||||
|
||||
use async_trait::async_trait;
|
||||
|
|
75
src/api/admin/rpc.rs
Normal file
75
src/api/admin/rpc.rs
Normal file
|
@ -0,0 +1,75 @@
|
|||
use std::fmt::Write;
|
||||
use std::sync::Arc;
|
||||
|
||||
use async_trait::async_trait;
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
use garage_util::background::BackgroundRunner;
|
||||
use garage_util::error::Error;
|
||||
|
||||
use garage_rpc::*;
|
||||
|
||||
use garage_model::garage::Garage;
|
||||
|
||||
use crate::admin::api::{LocalAdminApiRequest, LocalAdminApiResponse};
|
||||
use crate::admin::EndpointHandler as AdminApiEndpoint;
|
||||
use crate::generic_server::ApiError;
|
||||
|
||||
pub const ADMIN_RPC_PATH: &str = "garage_api/admin/rpc.rs/Rpc";
|
||||
|
||||
#[derive(Debug, Serialize, Deserialize)]
|
||||
pub struct AdminRpc(LocalAdminApiRequest);
|
||||
|
||||
#[derive(Debug, Serialize, Deserialize)]
|
||||
pub enum AdminRpcResponse {
|
||||
ApiOkResponse(LocalAdminApiResponse),
|
||||
ApiErrorResponse {
|
||||
http_code: u16,
|
||||
error_code: String,
|
||||
message: String,
|
||||
},
|
||||
}
|
||||
|
||||
impl Rpc for AdminRpc {
|
||||
type Response = Result<AdminRpcResponse, Error>;
|
||||
}
|
||||
|
||||
pub struct AdminRpcHandler {
|
||||
garage: Arc<Garage>,
|
||||
background: Arc<BackgroundRunner>,
|
||||
endpoint: Arc<Endpoint<AdminRpc, Self>>,
|
||||
}
|
||||
|
||||
impl AdminRpcHandler {
|
||||
pub fn new(garage: Arc<Garage>, background: Arc<BackgroundRunner>) -> Arc<Self> {
|
||||
let endpoint = garage.system.netapp.endpoint(ADMIN_RPC_PATH.into());
|
||||
let admin = Arc::new(Self {
|
||||
garage,
|
||||
background,
|
||||
endpoint,
|
||||
});
|
||||
admin.endpoint.set_handler(admin.clone());
|
||||
admin
|
||||
}
|
||||
}
|
||||
|
||||
#[async_trait]
|
||||
impl EndpointHandler<AdminRpc> for AdminRpcHandler {
|
||||
async fn handle(
|
||||
self: &Arc<Self>,
|
||||
message: &AdminRpc,
|
||||
_from: NodeID,
|
||||
) -> Result<AdminRpcResponse, Error> {
|
||||
let req = message.0.clone();
|
||||
info!("Proxied admin API request: {}", req.name());
|
||||
let res = req.handle(&self.garage).await;
|
||||
match res {
|
||||
Ok(res) => Ok(AdminRpcResponse::ApiOkResponse(res)),
|
||||
Err(e) => Ok(AdminRpcResponse::ApiErrorResponse {
|
||||
http_code: e.http_status_code().as_u16(),
|
||||
error_code: e.code().to_string(),
|
||||
message: e.to_string(),
|
||||
}),
|
||||
}
|
||||
}
|
||||
}
|
18
src/api/admin/worker.rs
Normal file
18
src/api/admin/worker.rs
Normal file
|
@ -0,0 +1,18 @@
|
|||
use std::sync::Arc;
|
||||
|
||||
use async_trait::async_trait;
|
||||
|
||||
use garage_model::garage::Garage;
|
||||
|
||||
use crate::admin::api::*;
|
||||
use crate::admin::error::Error;
|
||||
use crate::admin::EndpointHandler;
|
||||
|
||||
#[async_trait]
|
||||
impl EndpointHandler for LocalGetWorkerParamRequest {
|
||||
type Response = LocalGetWorkerParamResponse;
|
||||
|
||||
async fn handle(self, garage: &Arc<Garage>) -> Result<LocalGetWorkerParamResponse, Error> {
|
||||
todo!()
|
||||
}
|
||||
}
|
Loading…
Add table
Reference in a new issue