aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/api/admin/api_server.rs1
-rw-r--r--src/api/admin/cluster.rs33
-rw-r--r--src/api/admin/router.rs2
-rw-r--r--src/rpc/system.rs12
4 files changed, 44 insertions, 4 deletions
diff --git a/src/api/admin/api_server.rs b/src/api/admin/api_server.rs
index 6f568024..61b0d24f 100644
--- a/src/api/admin/api_server.rs
+++ b/src/api/admin/api_server.rs
@@ -124,6 +124,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::ConnectClusterNodes => handle_connect_cluster_nodes(&self.garage, req).await,
// Layout
Endpoint::GetClusterLayout => handle_get_cluster_layout(&self.garage).await,
Endpoint::UpdateClusterLayout => handle_update_cluster_layout(&self.garage, req).await,
diff --git a/src/api/admin/cluster.rs b/src/api/admin/cluster.rs
index 44ad4a37..3401be42 100644
--- a/src/api/admin/cluster.rs
+++ b/src/api/admin/cluster.rs
@@ -45,6 +45,33 @@ pub async fn handle_get_cluster_status(garage: &Arc<Garage>) -> Result<Response<
.body(Body::from(resp_json))?)
}
+pub async fn handle_connect_cluster_nodes(
+ garage: &Arc<Garage>,
+ req: Request<Body>,
+) -> Result<Response<Body>, Error> {
+ let req = parse_json_body::<Vec<String>>(req).await?;
+
+ let res = futures::future::join_all(req.iter().map(|node| garage.system.connect(node)))
+ .await
+ .into_iter()
+ .map(|r| match r {
+ Ok(()) => ConnectClusterNodesResponse {
+ success: true,
+ error: None,
+ },
+ Err(e) => ConnectClusterNodesResponse {
+ success: false,
+ error: Some(format!("{}", e)),
+ },
+ })
+ .collect::<Vec<_>>();
+
+ 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)?;
@@ -85,6 +112,12 @@ struct GetClusterStatusResponse {
}
#[derive(Serialize)]
+struct ConnectClusterNodesResponse {
+ success: bool,
+ error: Option<String>,
+}
+
+#[derive(Serialize)]
#[serde(rename_all = "camelCase")]
struct GetClusterLayoutResponse {
version: u64,
diff --git a/src/api/admin/router.rs b/src/api/admin/router.rs
index 909ef102..41e7ed73 100644
--- a/src/api/admin/router.rs
+++ b/src/api/admin/router.rs
@@ -18,6 +18,7 @@ pub enum Endpoint {
Options,
Metrics,
GetClusterStatus,
+ ConnectClusterNodes,
// Layout
GetClusterLayout,
UpdateClusterLayout,
@@ -91,6 +92,7 @@ impl Endpoint {
OPTIONS _ => Options,
GET "/metrics" => Metrics,
GET "/v0/status" => GetClusterStatus,
+ POST "/v0/connect" => ConnectClusterNodes,
// Layout endpoints
GET "/v0/layout" => GetClusterLayout,
POST "/v0/layout" => UpdateClusterLayout,
diff --git a/src/rpc/system.rs b/src/rpc/system.rs
index eb2f2e42..78d538ec 100644
--- a/src/rpc/system.rs
+++ b/src/rpc/system.rs
@@ -383,10 +383,14 @@ impl System {
}
}
}
- return Err(Error::Message(format!(
- "Could not connect to specified peers. Errors: {:?}",
- errors
- )));
+ if errors.len() == 1 {
+ return Err(Error::Message(errors[0].1.to_string()));
+ } else {
+ return Err(Error::Message(format!(
+ "Could not connect to specified peers. Errors: {:?}",
+ errors
+ )));
+ }
}
// ---- INTERNALS ----