mirror of
https://github.com/rustfs/rustfs.git
synced 2026-08-28 07:57:01 +00:00
fix(storage): expose truthful storage class capabilities (#5172)
This commit is contained in:
@@ -46,6 +46,34 @@ pub const OUTPOSTS: &str = "OUTPOSTS";
|
||||
pub const SNOW: &str = "SNOW";
|
||||
pub const STANDARD_IA: &str = "STANDARD_IA";
|
||||
|
||||
/// Version of the client-discoverable storage-class write contract.
|
||||
pub const CAPABILITY_CONTRACT_VERSION: u32 = 1;
|
||||
/// Storage classes whose write semantics RustFS implements.
|
||||
pub const SUPPORTED_WRITE_CLASSES: [&str; 2] = [STANDARD, RRS];
|
||||
/// Stable S3 error code returned for unsupported write classes.
|
||||
pub const UNSUPPORTED_WRITE_ERROR: &str = "InvalidStorageClass";
|
||||
/// Compatibility behavior applied to historical label-only object metadata.
|
||||
pub const LEGACY_LABEL_BEHAVIOR: &str = "normalized_to_effective_class";
|
||||
|
||||
/// Returns whether a client may select this storage class for a write.
|
||||
pub fn is_supported_write_class(storage_class: &str) -> bool {
|
||||
SUPPORTED_WRITE_CLASSES.contains(&storage_class)
|
||||
}
|
||||
|
||||
/// Resolves the storage class that truthfully describes the stored object.
|
||||
///
|
||||
/// A completed lifecycle transition is a real storage tier and therefore keeps
|
||||
/// its tier name. For local objects, only RRS has distinct layout semantics;
|
||||
/// historical AWS class labels otherwise describe the effective STANDARD
|
||||
/// layout.
|
||||
pub fn effective_class<'a>(stored_class: Option<&'a str>, transitioned_tier: Option<&'a str>) -> &'a str {
|
||||
if let Some(tier) = transitioned_tier.filter(|tier| !tier.is_empty()) {
|
||||
return tier;
|
||||
}
|
||||
|
||||
if stored_class == Some(RRS) { RRS } else { STANDARD }
|
||||
}
|
||||
|
||||
// Standard constants for config info storage class
|
||||
pub const CLASS_STANDARD: &str = "standard";
|
||||
pub const CLASS_RRS: &str = "rrs";
|
||||
@@ -556,6 +584,47 @@ mod tests {
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn write_capability_contract_only_accepts_implemented_layouts() {
|
||||
assert_eq!(SUPPORTED_WRITE_CLASSES, [STANDARD, RRS]);
|
||||
assert!(is_supported_write_class(STANDARD));
|
||||
assert!(is_supported_write_class(RRS));
|
||||
|
||||
for label_only_class in [
|
||||
DEEP_ARCHIVE,
|
||||
EXPRESS_ONEZONE,
|
||||
GLACIER,
|
||||
GLACIER_IR,
|
||||
INTELLIGENT_TIERING,
|
||||
ONEZONE_IA,
|
||||
OUTPOSTS,
|
||||
SNOW,
|
||||
STANDARD_IA,
|
||||
] {
|
||||
assert!(
|
||||
!is_supported_write_class(label_only_class),
|
||||
"{label_only_class} must not be advertised as a supported write class"
|
||||
);
|
||||
}
|
||||
assert!(!is_supported_write_class(""));
|
||||
assert!(!is_supported_write_class("standard"));
|
||||
assert!(!is_supported_write_class("UNKNOWN"));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn effective_class_normalizes_legacy_labels_and_preserves_real_tiers() {
|
||||
assert_eq!(effective_class(None, None), STANDARD);
|
||||
assert_eq!(effective_class(Some(STANDARD), None), STANDARD);
|
||||
assert_eq!(effective_class(Some(RRS), None), RRS);
|
||||
assert_eq!(effective_class(Some(STANDARD_IA), None), STANDARD);
|
||||
assert_eq!(effective_class(Some(GLACIER), None), STANDARD);
|
||||
assert_eq!(effective_class(Some("UNKNOWN"), None), STANDARD);
|
||||
|
||||
assert_eq!(effective_class(Some(STANDARD_IA), Some("WARM-TIER")), "WARM-TIER");
|
||||
assert_eq!(effective_class(Some(STANDARD), Some(STANDARD_IA)), STANDARD_IA);
|
||||
assert_eq!(effective_class(Some(RRS), Some("CUSTOM-RRS-TIER")), "CUSTOM-RRS-TIER");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn automatic_parity_is_resolved_per_pool() {
|
||||
let cfg = lookup_config_for_pools_with_env(&KVS::new(), &[4, 2], no_env_overrides())
|
||||
|
||||
Reference in New Issue
Block a user