aboutsummaryrefslogtreecommitdiff
path: root/src/api/admin/cluster.rs
diff options
context:
space:
mode:
Diffstat (limited to 'src/api/admin/cluster.rs')
-rw-r--r--src/api/admin/cluster.rs182
1 files changed, 88 insertions, 94 deletions
diff --git a/src/api/admin/cluster.rs b/src/api/admin/cluster.rs
index 11753509..c7eb7e7d 100644
--- a/src/api/admin/cluster.rs
+++ b/src/api/admin/cluster.rs
@@ -2,7 +2,6 @@ use std::collections::HashMap;
use std::sync::Arc;
use async_trait::async_trait;
-use hyper::{body::Incoming as IncomingBody, Request, Response};
use garage_util::crdt::*;
use garage_util::data::*;
@@ -14,14 +13,13 @@ use garage_model::garage::Garage;
use crate::admin::api::{
ApplyClusterLayoutRequest, ApplyClusterLayoutResponse, ConnectClusterNodeResponse,
ConnectClusterNodesRequest, ConnectClusterNodesResponse, FreeSpaceResp,
- GetClusterHealthRequest, GetClusterHealthResponse, GetClusterLayoutResponse,
- GetClusterStatusRequest, GetClusterStatusResponse, NodeResp, NodeRoleChange,
- NodeRoleChangeEnum, NodeRoleResp, UpdateClusterLayoutRequest,
+ GetClusterHealthRequest, GetClusterHealthResponse, GetClusterLayoutRequest,
+ GetClusterLayoutResponse, GetClusterStatusRequest, GetClusterStatusResponse, NodeResp,
+ NodeRoleChange, NodeRoleChangeEnum, NodeRoleResp, RevertClusterLayoutRequest,
+ RevertClusterLayoutResponse, UpdateClusterLayoutRequest, UpdateClusterLayoutResponse,
};
-use crate::admin::api_server::ResBody;
use crate::admin::error::*;
use crate::admin::EndpointHandler;
-use crate::helpers::{json_ok_response, parse_json_body};
#[async_trait]
impl EndpointHandler for GetClusterStatusRequest {
@@ -149,17 +147,6 @@ impl EndpointHandler for GetClusterHealthRequest {
}
}
-pub async fn handle_connect_cluster_nodes(
- garage: &Arc<Garage>,
- req: Request<IncomingBody>,
-) -> Result<Response<ResBody>, Error> {
- let req = parse_json_body::<ConnectClusterNodesRequest, _, Error>(req).await?;
-
- let res = req.handle(garage).await?;
-
- Ok(json_ok_response(&res)?)
-}
-
#[async_trait]
impl EndpointHandler for ConnectClusterNodesRequest {
type Response = ConnectClusterNodesResponse;
@@ -183,10 +170,15 @@ impl EndpointHandler for ConnectClusterNodesRequest {
}
}
-pub async fn handle_get_cluster_layout(garage: &Arc<Garage>) -> Result<Response<ResBody>, Error> {
- let res = format_cluster_layout(garage.system.cluster_layout().inner());
+#[async_trait]
+impl EndpointHandler for GetClusterLayoutRequest {
+ type Response = GetClusterLayoutResponse;
- Ok(json_ok_response(&res)?)
+ async fn handle(self, garage: &Arc<Garage>) -> Result<GetClusterLayoutResponse, Error> {
+ Ok(format_cluster_layout(
+ garage.system.cluster_layout().inner(),
+ ))
+ }
}
fn format_cluster_layout(layout: &layout::LayoutHistory) -> GetClusterLayoutResponse {
@@ -238,85 +230,87 @@ fn format_cluster_layout(layout: &layout::LayoutHistory) -> GetClusterLayoutResp
// ---- update functions ----
-pub async fn handle_update_cluster_layout(
- garage: &Arc<Garage>,
- req: Request<IncomingBody>,
-) -> Result<Response<ResBody>, Error> {
- let updates = parse_json_body::<UpdateClusterLayoutRequest, _, Error>(req).await?;
-
- let mut layout = garage.system.cluster_layout().inner().clone();
-
- let mut roles = layout.current().roles.clone();
- roles.merge(&layout.staging.get().roles);
-
- for change in updates.0 {
- let node = hex::decode(&change.id).ok_or_bad_request("Invalid node identifier")?;
- let node = Uuid::try_from(&node).ok_or_bad_request("Invalid node identifier")?;
-
- let new_role = match change.action {
- NodeRoleChangeEnum::Remove { remove: true } => None,
- NodeRoleChangeEnum::Update {
- zone,
- capacity,
- tags,
- } => Some(layout::NodeRole {
- zone,
- capacity,
- tags,
- }),
- _ => return Err(Error::bad_request("Invalid layout change")),
- };
+#[async_trait]
+impl EndpointHandler for UpdateClusterLayoutRequest {
+ type Response = UpdateClusterLayoutResponse;
+
+ async fn handle(self, garage: &Arc<Garage>) -> Result<UpdateClusterLayoutResponse, Error> {
+ let mut layout = garage.system.cluster_layout().inner().clone();
+
+ let mut roles = layout.current().roles.clone();
+ roles.merge(&layout.staging.get().roles);
+
+ for change in self.0 {
+ let node = hex::decode(&change.id).ok_or_bad_request("Invalid node identifier")?;
+ let node = Uuid::try_from(&node).ok_or_bad_request("Invalid node identifier")?;
+
+ let new_role = match change.action {
+ NodeRoleChangeEnum::Remove { remove: true } => None,
+ NodeRoleChangeEnum::Update {
+ zone,
+ capacity,
+ tags,
+ } => Some(layout::NodeRole {
+ zone,
+ capacity,
+ tags,
+ }),
+ _ => return Err(Error::bad_request("Invalid layout change")),
+ };
+
+ layout
+ .staging
+ .get_mut()
+ .roles
+ .merge(&roles.update_mutator(node, layout::NodeRoleV(new_role)));
+ }
- layout
- .staging
- .get_mut()
- .roles
- .merge(&roles.update_mutator(node, layout::NodeRoleV(new_role)));
+ garage
+ .system
+ .layout_manager
+ .update_cluster_layout(&layout)
+ .await?;
+
+ let res = format_cluster_layout(&layout);
+ Ok(UpdateClusterLayoutResponse(res))
}
+}
- garage
- .system
- .layout_manager
- .update_cluster_layout(&layout)
- .await?;
+#[async_trait]
+impl EndpointHandler for ApplyClusterLayoutRequest {
+ type Response = ApplyClusterLayoutResponse;
- let res = format_cluster_layout(&layout);
- Ok(json_ok_response(&res)?)
-}
+ async fn handle(self, garage: &Arc<Garage>) -> Result<ApplyClusterLayoutResponse, Error> {
+ let layout = garage.system.cluster_layout().inner().clone();
+ let (layout, msg) = layout.apply_staged_changes(Some(self.version))?;
+
+ garage
+ .system
+ .layout_manager
+ .update_cluster_layout(&layout)
+ .await?;
-pub async fn handle_apply_cluster_layout(
- garage: &Arc<Garage>,
- req: Request<IncomingBody>,
-) -> Result<Response<ResBody>, Error> {
- let param = parse_json_body::<ApplyClusterLayoutRequest, _, Error>(req).await?;
-
- let layout = garage.system.cluster_layout().inner().clone();
- let (layout, msg) = layout.apply_staged_changes(Some(param.version))?;
-
- garage
- .system
- .layout_manager
- .update_cluster_layout(&layout)
- .await?;
-
- let res = ApplyClusterLayoutResponse {
- message: msg,
- layout: format_cluster_layout(&layout),
- };
- Ok(json_ok_response(&res)?)
+ Ok(ApplyClusterLayoutResponse {
+ message: msg,
+ layout: format_cluster_layout(&layout),
+ })
+ }
}
-pub async fn handle_revert_cluster_layout(
- garage: &Arc<Garage>,
-) -> Result<Response<ResBody>, Error> {
- let layout = garage.system.cluster_layout().inner().clone();
- let layout = layout.revert_staged_changes()?;
- garage
- .system
- .layout_manager
- .update_cluster_layout(&layout)
- .await?;
-
- let res = format_cluster_layout(&layout);
- Ok(json_ok_response(&res)?)
+#[async_trait]
+impl EndpointHandler for RevertClusterLayoutRequest {
+ type Response = RevertClusterLayoutResponse;
+
+ async fn handle(self, garage: &Arc<Garage>) -> Result<RevertClusterLayoutResponse, Error> {
+ let layout = garage.system.cluster_layout().inner().clone();
+ let layout = layout.revert_staged_changes()?;
+ garage
+ .system
+ .layout_manager
+ .update_cluster_layout(&layout)
+ .await?;
+
+ let res = format_cluster_layout(&layout);
+ Ok(RevertClusterLayoutResponse(res))
+ }
}