Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 5 additions & 2 deletions src/console/handlers/pools.rs
Original file line number Diff line number Diff line change
Expand Up @@ -511,7 +511,10 @@ pub async fn list_pools(
name: pool.name.clone(),
servers: pool.servers,
volumes_per_server: pool.persistence.volumes_per_server,
total_volumes: pool.servers * pool.persistence.volumes_per_server,
total_volumes: PoolDetails::total_volumes(
pool.servers,
pool.persistence.volumes_per_server,
),
storage_class,
volume_size,
replicas,
Expand Down Expand Up @@ -575,7 +578,7 @@ pub async fn add_pool(
),
});
}
let total_volumes = req.servers.saturating_mul(req.volumes_per_server);
let total_volumes = PoolDetails::total_volumes(req.servers, req.volumes_per_server);

// Build Pool spec
let new_pool = Pool {
Expand Down
27 changes: 26 additions & 1 deletion src/console/models/pool.rs
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ pub struct PoolDetails {
pub name: String,
pub servers: i32,
pub volumes_per_server: i32,
pub total_volumes: i32,
pub total_volumes: i64,
pub storage_class: Option<String>,
pub volume_size: Option<String>,
pub replicas: i32,
Expand All @@ -43,6 +43,17 @@ pub struct PoolDetails {
pub created_at: Option<String>,
}

impl PoolDetails {
/// Return the exact volume count derived from the CRD's `i32` pool dimensions.
///
/// Widening both operands before multiplication is lossless because every `i32 * i32`
/// product fits in an `i64`. This preserves the real count instead of rejecting or clamping a
/// valid CRD value.
pub(crate) fn total_volumes(servers: i32, volumes_per_server: i32) -> i64 {
i64::from(servers) * i64::from(volumes_per_server)
}
}

/// Response listing pools for a tenant
#[derive(Debug, Serialize, ToSchema)]
pub struct PoolListResponse {
Expand Down Expand Up @@ -120,3 +131,17 @@ pub struct PoolDecommissionRequestResponse {
pub request_id: String,
pub action: String,
}

#[cfg(test)]
mod tests {
use super::PoolDetails;

#[test]
fn total_volumes_widens_before_multiplication() {
assert_eq!(PoolDetails::total_volumes(i32::MAX, 2), 4_294_967_294);
assert_eq!(
PoolDetails::total_volumes(i32::MAX, i32::MAX),
4_611_686_014_132_420_609
);
}
}
17 changes: 17 additions & 0 deletions src/console/openapi.rs
Original file line number Diff line number Diff line change
Expand Up @@ -736,6 +736,23 @@ mod tests {
}
}

#[test]
fn pool_total_volumes_documents_widened_integer() {
let spec = serde_json::to_value(ApiDoc::openapi()).expect("OpenAPI spec serializes");
let total_volumes = spec
.pointer("/components/schemas/PoolDetails/properties/total_volumes")
.expect("PoolDetails.total_volumes schema exists");

assert_eq!(
total_volumes.get("type").and_then(Value::as_str),
Some("integer")
);
assert_eq!(
total_volumes.get("format").and_then(Value::as_str),
Some("int64")
);
}

#[test]
fn tenant_api_documents_provisioning_fields() {
let spec = serde_json::to_value(ApiDoc::openapi()).expect("OpenAPI spec serializes");
Expand Down
Loading