mirror of
https://github.com/deuxfleurs-org/garage.git
synced 2026-09-01 09:48:23 +00:00
admin api: implement PreviewClusterLayoutChanges
This commit is contained in:
@@ -950,6 +950,30 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"/v2/PreviewClusterLayoutChanges": {
|
||||||
|
"post": {
|
||||||
|
"tags": [
|
||||||
|
"Cluster layout"
|
||||||
|
],
|
||||||
|
"description": "\nComputes a new layout taking into account the staged parameters, and returns it with detailed statistics. The new layout is not applied in the cluster.\n\n*Note: do not try to parse the `message` field of the response, it is given as an array of string specifically because its format is not stable.*\n ",
|
||||||
|
"operationId": "PreviewClusterLayoutChanges",
|
||||||
|
"responses": {
|
||||||
|
"200": {
|
||||||
|
"description": "Information about the new layout",
|
||||||
|
"content": {
|
||||||
|
"application/json": {
|
||||||
|
"schema": {
|
||||||
|
"$ref": "#/components/schemas/PreviewClusterLayoutChangesResponse"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"500": {
|
||||||
|
"description": "Internal server error"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
"/v2/PurgeBlocks": {
|
"/v2/PurgeBlocks": {
|
||||||
"post": {
|
"post": {
|
||||||
"tags": [
|
"tags": [
|
||||||
@@ -2992,6 +3016,39 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"PreviewClusterLayoutChangesResponse": {
|
||||||
|
"oneOf": [
|
||||||
|
{
|
||||||
|
"type": "object",
|
||||||
|
"required": [
|
||||||
|
"error"
|
||||||
|
],
|
||||||
|
"properties": {
|
||||||
|
"error": {
|
||||||
|
"type": "string"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "object",
|
||||||
|
"required": [
|
||||||
|
"message",
|
||||||
|
"newLayout"
|
||||||
|
],
|
||||||
|
"properties": {
|
||||||
|
"message": {
|
||||||
|
"type": "array",
|
||||||
|
"items": {
|
||||||
|
"type": "string"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"newLayout": {
|
||||||
|
"$ref": "#/components/schemas/GetClusterLayoutResponse"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
"RemoveBucketAliasRequest": {
|
"RemoveBucketAliasRequest": {
|
||||||
"allOf": [
|
"allOf": [
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -52,6 +52,7 @@ admin_endpoints![
|
|||||||
// Layout operations
|
// Layout operations
|
||||||
GetClusterLayout,
|
GetClusterLayout,
|
||||||
UpdateClusterLayout,
|
UpdateClusterLayout,
|
||||||
|
PreviewClusterLayoutChanges,
|
||||||
ApplyClusterLayout,
|
ApplyClusterLayout,
|
||||||
RevertClusterLayout,
|
RevertClusterLayout,
|
||||||
|
|
||||||
@@ -318,6 +319,23 @@ pub enum ZoneRedundancy {
|
|||||||
Maximum,
|
Maximum,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ---- PreviewClusterLayoutChanges ----
|
||||||
|
|
||||||
|
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||||
|
pub struct PreviewClusterLayoutChangesRequest;
|
||||||
|
|
||||||
|
#[derive(Debug, Clone, Serialize, Deserialize, ToSchema)]
|
||||||
|
#[serde(untagged)]
|
||||||
|
pub enum PreviewClusterLayoutChangesResponse {
|
||||||
|
#[serde(rename_all = "camelCase")]
|
||||||
|
Error { error: String },
|
||||||
|
#[serde(rename_all = "camelCase")]
|
||||||
|
Success {
|
||||||
|
message: Vec<String>,
|
||||||
|
new_layout: GetClusterLayoutResponse,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
// ---- UpdateClusterLayout ----
|
// ---- UpdateClusterLayout ----
|
||||||
|
|
||||||
#[derive(Debug, Clone, Serialize, Deserialize, ToSchema)]
|
#[derive(Debug, Clone, Serialize, Deserialize, ToSchema)]
|
||||||
|
|||||||
@@ -3,6 +3,7 @@ use std::sync::Arc;
|
|||||||
|
|
||||||
use garage_util::crdt::*;
|
use garage_util::crdt::*;
|
||||||
use garage_util::data::*;
|
use garage_util::data::*;
|
||||||
|
use garage_util::error::Error as GarageError;
|
||||||
|
|
||||||
use garage_rpc::layout;
|
use garage_rpc::layout;
|
||||||
|
|
||||||
@@ -308,6 +309,29 @@ impl RequestHandler for UpdateClusterLayoutRequest {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl RequestHandler for PreviewClusterLayoutChangesRequest {
|
||||||
|
type Response = PreviewClusterLayoutChangesResponse;
|
||||||
|
|
||||||
|
async fn handle(
|
||||||
|
self,
|
||||||
|
garage: &Arc<Garage>,
|
||||||
|
_admin: &Admin,
|
||||||
|
) -> Result<PreviewClusterLayoutChangesResponse, Error> {
|
||||||
|
let layout = garage.system.cluster_layout().inner().clone();
|
||||||
|
let new_ver = layout.current().version + 1;
|
||||||
|
match layout.apply_staged_changes(Some(new_ver)) {
|
||||||
|
Err(GarageError::Message(error)) => {
|
||||||
|
Ok(PreviewClusterLayoutChangesResponse::Error { error })
|
||||||
|
}
|
||||||
|
Err(e) => Err(e.into()),
|
||||||
|
Ok((new_layout, msg)) => Ok(PreviewClusterLayoutChangesResponse::Success {
|
||||||
|
message: msg,
|
||||||
|
new_layout: format_cluster_layout(&new_layout),
|
||||||
|
}),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl RequestHandler for ApplyClusterLayoutRequest {
|
impl RequestHandler for ApplyClusterLayoutRequest {
|
||||||
type Response = ApplyClusterLayoutResponse;
|
type Response = ApplyClusterLayoutResponse;
|
||||||
|
|
||||||
|
|||||||
@@ -117,6 +117,21 @@ Contrary to the CLI that may update only a subset of the fields capacity, zone a
|
|||||||
)]
|
)]
|
||||||
fn UpdateClusterLayout() -> () {}
|
fn UpdateClusterLayout() -> () {}
|
||||||
|
|
||||||
|
#[utoipa::path(post,
|
||||||
|
path = "/v2/PreviewClusterLayoutChanges",
|
||||||
|
tag = "Cluster layout",
|
||||||
|
description = "
|
||||||
|
Computes a new layout taking into account the staged parameters, and returns it with detailed statistics. The new layout is not applied in the cluster.
|
||||||
|
|
||||||
|
*Note: do not try to parse the `message` field of the response, it is given as an array of string specifically because its format is not stable.*
|
||||||
|
",
|
||||||
|
responses(
|
||||||
|
(status = 200, description = "Information about the new layout", body = PreviewClusterLayoutChangesResponse),
|
||||||
|
(status = 500, description = "Internal server error")
|
||||||
|
),
|
||||||
|
)]
|
||||||
|
fn PreviewClusterLayoutChanges() -> () {}
|
||||||
|
|
||||||
#[utoipa::path(post,
|
#[utoipa::path(post,
|
||||||
path = "/v2/ApplyClusterLayout",
|
path = "/v2/ApplyClusterLayout",
|
||||||
tag = "Cluster layout",
|
tag = "Cluster layout",
|
||||||
@@ -686,6 +701,7 @@ impl Modify for SecurityAddon {
|
|||||||
// Layout operations
|
// Layout operations
|
||||||
GetClusterLayout,
|
GetClusterLayout,
|
||||||
UpdateClusterLayout,
|
UpdateClusterLayout,
|
||||||
|
PreviewClusterLayoutChanges,
|
||||||
ApplyClusterLayout,
|
ApplyClusterLayout,
|
||||||
RevertClusterLayout,
|
RevertClusterLayout,
|
||||||
// Key operations
|
// Key operations
|
||||||
|
|||||||
@@ -37,6 +37,7 @@ impl AdminApiRequest {
|
|||||||
// Layout endpoints
|
// Layout endpoints
|
||||||
GET GetClusterLayout (),
|
GET GetClusterLayout (),
|
||||||
POST UpdateClusterLayout (body),
|
POST UpdateClusterLayout (body),
|
||||||
|
POST PreviewClusterLayoutChanges (),
|
||||||
POST ApplyClusterLayout (body),
|
POST ApplyClusterLayout (body),
|
||||||
POST RevertClusterLayout (),
|
POST RevertClusterLayout (),
|
||||||
// API key endpoints
|
// API key endpoints
|
||||||
|
|||||||
Reference in New Issue
Block a user