admin api: small fixes

This commit is contained in:
Alex 2025-01-29 12:06:58 +01:00
parent 420bbc162d
commit 4f0b923c4f
6 changed files with 41 additions and 10 deletions

View file

@ -91,7 +91,7 @@ paths:
example: "ec79480e0ce52ae26fd00c9da684e4fa56658d9c64cdcecb094e936de0bfe71f"
garageVersion:
type: string
example: "v0.9.0"
example: "v2.0.0"
garageFeatures:
type: array
items:

View file

@ -53,7 +53,7 @@ Returns an HTTP status 200 if the node is ready to answer user's requests,
and an HTTP status 503 (Service Unavailable) if there are some partitions
for which a quorum of nodes is not available.
A simple textual message is also returned in a body with content-type `text/plain`.
See `/v2/health` for an API that also returns JSON output.
See `/v2/GetClusterHealth` for an API that also returns JSON output.
### Other special endpoints

View file

@ -13,9 +13,21 @@ use crate::admin::EndpointHandler;
use crate::helpers::is_default;
// This generates the following:
//
// - An enum AdminApiRequest that contains a variant for all endpoints
// - An enum AdminApiResponse that contains a variant for all non-special endpoints
//
// - An enum AdminApiResponse that contains a variant for all non-special endpoints.
// This enum is serialized in api_server.rs, without the enum tag,
// which gives directly the JSON response corresponding to the API call.
// This enum does not implement Deserialize as its meaning can be ambiguous.
//
// - An enum TaggedAdminApiResponse that contains the same variants, but
// serializes as a tagged enum. This allows it to be transmitted through
// Garage RPC and deserialized correctly upon receival.
// Conversion from untagged to tagged can be done using the `.tagged()` method.
//
// - AdminApiRequest::name() that returns the name of the endpoint
//
// - impl EndpointHandler for AdminApiHandler, that uses the impl EndpointHandler
// of each request type below for non-special endpoints
admin_endpoints![
@ -60,6 +72,9 @@ admin_endpoints![
// **********************************************
// Special endpoints
//
// These endpoints don't have associated *Response structs
// because they directly produce an http::Response
// **********************************************
#[derive(Serialize, Deserialize)]
@ -153,11 +168,11 @@ pub struct GetClusterHealthResponse {
pub struct ConnectClusterNodesRequest(pub Vec<String>);
#[derive(Serialize, Deserialize)]
pub struct ConnectClusterNodesResponse(pub Vec<ConnectClusterNodeResponse>);
pub struct ConnectClusterNodesResponse(pub Vec<ConnectNodeResponse>);
#[derive(Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct ConnectClusterNodeResponse {
pub struct ConnectNodeResponse {
pub success: bool,
pub error: Option<String>,
}
@ -331,7 +346,6 @@ pub struct UpdateKeyResponse(pub GetKeyInfoResponse);
#[derive(Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct UpdateKeyRequestBody {
// TODO: id (get parameter) goes here
pub name: Option<String>,
pub allow: Option<KeyPerm>,
pub deny: Option<KeyPerm>,

View file

@ -176,7 +176,7 @@ impl ApiHandler for AdminApiServer {
impl ApiEndpoint for Endpoint {
fn name(&self) -> Cow<'static, str> {
match self {
Self::Old(endpoint_v1) => Cow::Owned(format!("v1:{}", endpoint_v1.name())),
Self::Old(endpoint_v1) => Cow::Borrowed(endpoint_v1.name()),
Self::New(path) => Cow::Owned(path.clone()),
}
}

View file

@ -151,11 +151,11 @@ impl EndpointHandler for ConnectClusterNodesRequest {
.await
.into_iter()
.map(|r| match r {
Ok(()) => ConnectClusterNodeResponse {
Ok(()) => ConnectNodeResponse {
success: true,
error: None,
},
Err(e) => ConnectClusterNodeResponse {
Err(e) => ConnectNodeResponse {
success: false,
error: Some(format!("{}", e)),
},

View file

@ -14,7 +14,7 @@ macro_rules! admin_endpoints {
)*
}
#[derive(Serialize, Deserialize)]
#[derive(Serialize)]
#[serde(untagged)]
pub enum AdminApiResponse {
$(
@ -22,6 +22,13 @@ macro_rules! admin_endpoints {
)*
}
#[derive(Serialize, Deserialize)]
pub enum TaggedAdminApiResponse {
$(
$endpoint( [<$endpoint Response>] ),
)*
}
impl AdminApiRequest {
pub fn name(&self) -> &'static str {
match self {
@ -35,6 +42,16 @@ macro_rules! admin_endpoints {
}
}
impl AdminApiResponse {
fn tagged(self) -> TaggedAdminApiResponse {
match self {
$(
Self::$endpoint(res) => TaggedAdminApiResponse::$endpoint(res),
)*
}
}
}
#[async_trait]
impl EndpointHandler for AdminApiRequest {
type Response = AdminApiResponse;