diff --git a/doc/api/garage-admin-v2.json b/doc/api/garage-admin-v2.json index c63feec4..df6620a0 100644 --- a/doc/api/garage-admin-v2.json +++ b/doc/api/garage-admin-v2.json @@ -2445,7 +2445,10 @@ "type": "string" }, "routingRules": { - "type": "array", + "type": [ + "array", + "null" + ], "items": { "$ref": "#/components/schemas/website.RoutingRule" } @@ -2608,13 +2611,19 @@ ], "properties": { "bucketCount": { - "type": "integer", + "type": [ + "integer", + "null" + ], "format": "int64", "description": "number of buckets in the cluster", "minimum": 0 }, "dataAvail": { - "type": "integer", + "type": [ + "integer", + "null" + ], "format": "int64", "description": "available storage space for object data in the entire cluster, in bytes", "minimum": 0 @@ -2624,23 +2633,35 @@ "description": "cluster statistics as a free-form string, kept for compatibility with nodes\nrunning older v2.x versions of garage" }, "incompleteAvailInfo": { - "type": "boolean", + "type": [ + "boolean", + "null" + ], "description": "true if the available storage space statistics are imprecise due to missing\ninformation of disconnected nodes. When this is the case, the actual\nspace available in the cluster might be lower than the reported values." }, "metadataAvail": { - "type": "integer", + "type": [ + "integer", + "null" + ], "format": "int64", "description": "available storage space for object metadata in the entire cluster, in bytes", "minimum": 0 }, "totalObjectBytes": { - "type": "integer", + "type": [ + "integer", + "null" + ], "format": "int64", "description": "total size of objects stored in all buckets, before compression, deduplication and\nreplication (this is NOT equivalent to actual disk usage in the cluster)", "minimum": 0 }, "totalObjectCount": { - "type": "integer", + "type": [ + "integer", + "null" + ], "format": "int64", "description": "total number of objects stored in all buckets", "minimum": 0 @@ -3134,7 +3155,10 @@ "description": "garage version running on this node" }, "hostname": { - "type": "string", + "type": [ + "string", + "null" + ], "description": "hostname of this node" }, "nodeId": { @@ -3153,15 +3177,25 @@ ], "properties": { "blockManagerStats": { - "$ref": "#/components/schemas/NodeBlockManagerStats", - "description": "block manager statistics" + "oneOf": [ + { + "type": "null" + }, + { + "$ref": "#/components/schemas/NodeBlockManagerStats", + "description": "block manager statistics" + } + ] }, "freeform": { "type": "string", "description": "node statistics as a free-form string, kept for compatibility with nodes\nrunning older v2.x versions of garage" }, "tableStats": { - "type": "array", + "type": [ + "array", + "null" + ], "items": { "$ref": "#/components/schemas/NodeTableStats" }, @@ -3484,7 +3518,10 @@ "description": "garage version running on this node" }, "hostname": { - "type": "string", + "type": [ + "string", + "null" + ], "description": "hostname of this node" }, "nodeId": { @@ -3529,15 +3566,25 @@ ], "properties": { "blockManagerStats": { - "$ref": "#/components/schemas/NodeBlockManagerStats", - "description": "block manager statistics" + "oneOf": [ + { + "type": "null" + }, + { + "$ref": "#/components/schemas/NodeBlockManagerStats", + "description": "block manager statistics" + } + ] }, "freeform": { "type": "string", "description": "node statistics as a free-form string, kept for compatibility with nodes\nrunning older v2.x versions of garage" }, "tableStats": { - "type": "array", + "type": [ + "array", + "null" + ], "items": { "$ref": "#/components/schemas/NodeTableStats" }, diff --git a/src/api/admin/api.rs b/src/api/admin/api.rs index 53bb2f0b..ed145ea7 100644 --- a/src/api/admin/api.rs +++ b/src/api/admin/api.rs @@ -288,28 +288,28 @@ pub struct GetClusterStatisticsResponse { /// cluster statistics as a free-form string, kept for compatibility with nodes /// running older v2.x versions of garage pub freeform: String, - // FIXME for v3: remove serde(default) for all three fields below + // FIXME for v3: remove Option<> and serde(default) for all fields below /// available storage space for object data in the entire cluster, in bytes - #[serde(default)] - pub data_avail: u64, + #[serde(default, skip_serializing_if = "Option::is_none")] + pub data_avail: Option, /// available storage space for object metadata in the entire cluster, in bytes - #[serde(default)] - pub metadata_avail: u64, + #[serde(default, skip_serializing_if = "Option::is_none")] + pub metadata_avail: Option, /// true if the available storage space statistics are imprecise due to missing /// information of disconnected nodes. When this is the case, the actual /// space available in the cluster might be lower than the reported values. - #[serde(default)] - pub incomplete_avail_info: bool, + #[serde(default, skip_serializing_if = "Option::is_none")] + pub incomplete_avail_info: Option, /// number of buckets in the cluster - #[serde(default)] - pub bucket_count: u64, + #[serde(default, skip_serializing_if = "Option::is_none")] + pub bucket_count: Option, /// total number of objects stored in all buckets - #[serde(default)] - pub total_object_count: u64, + #[serde(default, skip_serializing_if = "Option::is_none")] + pub total_object_count: Option, /// total size of objects stored in all buckets, before compression, deduplication and /// replication (this is NOT equivalent to actual disk usage in the cluster) - #[serde(default)] - pub total_object_bytes: u64, + #[serde(default, skip_serializing_if = "Option::is_none")] + pub total_object_bytes: Option, } // ---- ConnectClusterNodes ---- @@ -870,13 +870,14 @@ pub struct GetBucketInfoResponse { /// Whether website access is enabled for this bucket pub website_access: bool, /// Website configuration for this bucket + #[serde(default, skip_serializing_if = "Option::is_none")] pub website_config: Option, // FIXME for v3: remove serde(default) for the two fields below /// CORS rules for this bucket - #[serde(default)] + #[serde(default, skip_serializing_if = "Option::is_none")] pub cors_rules: Option>, /// Object lifecycle rules for this bucket - #[serde(default)] + #[serde(default, skip_serializing_if = "Option::is_none")] pub lifecycle_rules: Option>, /// List of access keys that have permissions granted on this bucket pub keys: Vec, @@ -902,8 +903,8 @@ pub struct GetBucketInfoWebsiteResponse { pub index_document: String, pub error_document: Option, // FIXME for v3: remove serde(default) for field below - #[serde(default)] - pub routing_rules: Vec, + #[serde(default, skip_serializing_if = "Option::is_none")] + pub routing_rules: Option>, } #[derive(Debug, Clone, Serialize, Deserialize, ToSchema)] @@ -1152,10 +1153,10 @@ pub struct LocalGetNodeInfoRequest; #[serde(rename_all = "camelCase")] pub struct LocalGetNodeInfoResponse { pub node_id: String, - // FIXME for v3: remove serde(default) for field below + // FIXME for v3: remove Option<> and serde(default) for field below /// hostname of this node - #[serde(default)] - pub hostname: String, + #[serde(default, skip_serializing_if = "Option::is_none")] + pub hostname: Option, /// garage version running on this node pub garage_version: String, /// build-time features enabled for this garage release @@ -1180,11 +1181,11 @@ pub struct LocalGetNodeStatisticsResponse { pub freeform: String, // FIXME for v3: remove serde(default) for fields below /// metadata table statistics - #[serde(default)] - pub table_stats: Vec, + #[serde(default, skip_serializing_if = "Option::is_none")] + pub table_stats: Option>, /// block manager statistics - #[serde(default)] - pub block_manager_stats: NodeBlockManagerStats, + #[serde(default, skip_serializing_if = "Option::is_none")] + pub block_manager_stats: Option, } #[derive(Debug, Clone, Serialize, Deserialize, ToSchema)] diff --git a/src/api/admin/bucket.rs b/src/api/admin/bucket.rs index e0b7b3ad..e723d3b4 100644 --- a/src/api/admin/bucket.rs +++ b/src/api/admin/bucket.rs @@ -744,11 +744,12 @@ async fn bucket_info_results( GetBucketInfoWebsiteResponse { index_document: wsc.index_document, error_document: wsc.error_document, - routing_rules: wsc - .routing_rules - .into_iter() - .map(xml::website::RoutingRule::from_garage_routing_rule) - .collect::>(), + routing_rules: Some( + wsc.routing_rules + .into_iter() + .map(xml::website::RoutingRule::from_garage_routing_rule) + .collect::>(), + ), } }), cors_rules: state.cors_config.get().as_ref().map(|rules| { diff --git a/src/api/admin/cluster.rs b/src/api/admin/cluster.rs index eee657e3..7284be5f 100644 --- a/src/api/admin/cluster.rs +++ b/src/api/admin/cluster.rs @@ -311,12 +311,12 @@ impl RequestHandler for GetClusterStatisticsRequest { Ok(GetClusterStatisticsResponse { freeform: ret, - metadata_avail, - data_avail, - incomplete_avail_info: incomplete_info, - bucket_count, - total_object_count, - total_object_bytes, + metadata_avail: Some(metadata_avail), + data_avail: Some(data_avail), + incomplete_avail_info: Some(incomplete_info), + bucket_count: Some(bucket_count), + total_object_count: Some(total_object_count), + total_object_bytes: Some(total_object_bytes), }) } } diff --git a/src/api/admin/node.rs b/src/api/admin/node.rs index 6e46a46d..12163f18 100644 --- a/src/api/admin/node.rs +++ b/src/api/admin/node.rs @@ -27,7 +27,7 @@ impl RequestHandler for LocalGetNodeInfoRequest { Ok(LocalGetNodeInfoResponse { node_id: hex::encode(garage.system.id), - hostname, + hostname: Some(hostname), garage_version: garage_util::version::garage_version().to_string(), garage_features: garage_util::version::garage_features() .map(|features| features.iter().map(ToString::to_string).collect()), @@ -146,8 +146,8 @@ impl RequestHandler for LocalGetNodeStatisticsRequest { Ok(LocalGetNodeStatisticsResponse { freeform: ret, - table_stats, - block_manager_stats, + table_stats: Some(table_stats), + block_manager_stats: Some(block_manager_stats), }) } }