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::convert::TryFrom;
|
||||||
use std::net::SocketAddr;
|
use std::net::SocketAddr;
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
|
@ -70,8 +71,13 @@ admin_endpoints![
|
||||||
// Operations on bucket aliases
|
// Operations on bucket aliases
|
||||||
AddBucketAlias,
|
AddBucketAlias,
|
||||||
RemoveBucketAlias,
|
RemoveBucketAlias,
|
||||||
|
|
||||||
|
// Worker operations
|
||||||
|
GetWorkerParam,
|
||||||
];
|
];
|
||||||
|
|
||||||
|
local_admin_endpoints![GetWorkerParam,];
|
||||||
|
|
||||||
// **********************************************
|
// **********************************************
|
||||||
// Special endpoints
|
// Special endpoints
|
||||||
//
|
//
|
||||||
|
@ -579,3 +585,15 @@ pub struct RemoveBucketAliasRequest {
|
||||||
|
|
||||||
#[derive(Debug, Clone, Serialize, Deserialize)]
|
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||||
pub struct RemoveBucketAliasResponse(pub GetBucketInfoResponse);
|
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 admin_endpoints;
|
||||||
|
pub(crate) use local_admin_endpoints;
|
||||||
|
|
|
@ -7,11 +7,15 @@ mod router_v0;
|
||||||
mod router_v1;
|
mod router_v1;
|
||||||
mod router_v2;
|
mod router_v2;
|
||||||
|
|
||||||
|
pub mod rpc;
|
||||||
|
|
||||||
mod bucket;
|
mod bucket;
|
||||||
mod cluster;
|
mod cluster;
|
||||||
mod key;
|
mod key;
|
||||||
mod special;
|
mod special;
|
||||||
|
|
||||||
|
mod worker;
|
||||||
|
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
|
|
||||||
use async_trait::async_trait;
|
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