diff options
-rw-r--r-- | src/api/admin/api_server.rs | 7 | ||||
-rw-r--r-- | src/api/admin/cluster.rs | 83 | ||||
-rw-r--r-- | src/rpc/system.rs | 1 |
3 files changed, 58 insertions, 33 deletions
diff --git a/src/api/admin/api_server.rs b/src/api/admin/api_server.rs index 57842548..dfaac015 100644 --- a/src/api/admin/api_server.rs +++ b/src/api/admin/api_server.rs @@ -3,7 +3,9 @@ use std::sync::Arc; use async_trait::async_trait; use futures::future::Future; -use http::header::{CONTENT_TYPE, ALLOW, ACCESS_CONTROL_ALLOW_METHODS, ACCESS_CONTROL_ALLOW_ORIGIN}; +use http::header::{ + ACCESS_CONTROL_ALLOW_METHODS, ACCESS_CONTROL_ALLOW_ORIGIN, ALLOW, CONTENT_TYPE, +}; use hyper::{Body, Request, Response}; use opentelemetry::trace::{SpanRef, Tracer}; @@ -16,8 +18,8 @@ use garage_util::error::Error as GarageError; use crate::error::*; use crate::generic_server::*; -use crate::admin::router::{Authorization, Endpoint}; use crate::admin::cluster::*; +use crate::admin::router::{Authorization, Endpoint}; pub struct AdminApiServer { garage: Arc<Garage>, @@ -123,6 +125,7 @@ impl ApiHandler for AdminApiServer { Endpoint::Options => self.handle_options(&req), Endpoint::Metrics => self.handle_metrics(), Endpoint::GetClusterStatus => handle_get_cluster_status(&self.garage).await, + Endpoint::GetClusterLayout => handle_get_cluster_layout(&self.garage).await, _ => Err(Error::NotImplemented(format!( "Admin endpoint {} not implemented yet", endpoint.name() diff --git a/src/api/admin/cluster.rs b/src/api/admin/cluster.rs index 9ed41944..f4835648 100644 --- a/src/api/admin/cluster.rs +++ b/src/api/admin/cluster.rs @@ -1,60 +1,83 @@ -use std::sync::Arc; use std::collections::HashMap; -use std::net::{IpAddr, SocketAddr}; +use std::net::SocketAddr; +use std::sync::Arc; -use serde::{Serialize}; +use serde::Serialize; -use hyper::{Body, Request, Response, StatusCode}; +use hyper::{Body, Response, StatusCode}; -use garage_util::data::*; -use garage_util::error::Error as GarageError; use garage_rpc::layout::*; -use garage_rpc::system::*; +use garage_util::error::Error as GarageError; use garage_model::garage::Garage; - use crate::error::*; - -pub async fn handle_get_cluster_status( - garage: &Arc<Garage>, -) -> Result<Response<Body>, Error> { - let layout = garage.system.get_cluster_layout(); - +pub async fn handle_get_cluster_status(garage: &Arc<Garage>) -> Result<Response<Body>, Error> { let res = GetClusterStatusResponse { - known_nodes: garage.system.get_known_nodes() + known_nodes: garage + .system + .get_known_nodes() .into_iter() - .map(|i| (hex::encode(i.id), KnownNodeResp { - addr: i.addr, - is_up: i.is_up, - last_seen_secs_ago: i.last_seen_secs_ago, - hostname: i.status.hostname, - })) + .map(|i| { + ( + hex::encode(i.id), + KnownNodeResp { + addr: i.addr, + is_up: i.is_up, + last_seen_secs_ago: i.last_seen_secs_ago, + hostname: i.status.hostname, + }, + ) + }) .collect(), - roles: layout.roles.items() + layout: get_cluster_layout(garage), + }; + + let resp_json = serde_json::to_string_pretty(&res).map_err(GarageError::from)?; + Ok(Response::builder() + .status(StatusCode::OK) + .body(Body::from(resp_json))?) +} + +pub async fn handle_get_cluster_layout(garage: &Arc<Garage>) -> Result<Response<Body>, Error> { + let res = get_cluster_layout(garage); + let resp_json = serde_json::to_string_pretty(&res).map_err(GarageError::from)?; + Ok(Response::builder() + .status(StatusCode::OK) + .body(Body::from(resp_json))?) +} + +fn get_cluster_layout(garage: &Arc<Garage>) -> GetClusterLayoutResponse { + let layout = garage.system.get_cluster_layout(); + + GetClusterLayoutResponse { + roles: layout + .roles + .items() .iter() .filter(|(_, _, v)| v.0.is_some()) .map(|(k, _, v)| (hex::encode(k), v.0.clone())) .collect(), - staged_role_changes: layout.staging.items() + staged_role_changes: layout + .staging + .items() .iter() .filter(|(k, _, v)| layout.roles.get(k) != Some(v)) .map(|(k, _, v)| (hex::encode(k), v.0.clone())) .collect(), - }; - - let resp_json = serde_json::to_string_pretty(&res).map_err(GarageError::from)?; - Ok(Response::builder() - .status(StatusCode::OK) - .body(Body::from(resp_json))?) + } } - #[derive(Serialize)] struct GetClusterStatusResponse { #[serde(rename = "knownNodes")] known_nodes: HashMap<String, KnownNodeResp>, + layout: GetClusterLayoutResponse, +} + +#[derive(Serialize)] +struct GetClusterLayoutResponse { roles: HashMap<String, Option<NodeRole>>, #[serde(rename = "stagedRoleChanges")] staged_role_changes: HashMap<String, Option<NodeRole>>, diff --git a/src/rpc/system.rs b/src/rpc/system.rs index a5b8d4f4..73c7b898 100644 --- a/src/rpc/system.rs +++ b/src/rpc/system.rs @@ -462,7 +462,6 @@ impl System { SystemRpc::ReturnKnownNodes(known_nodes) } - async fn handle_advertise_status( self: &Arc<Self>, from: Uuid, |