mirror of
https://github.com/rustfs/rustfs.git
synced 2026-08-21 20:06:37 +00:00
155 lines
4.8 KiB
Rust
155 lines
4.8 KiB
Rust
// Copyright 2024 RustFS Team
|
|
//
|
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
|
// you may not use this file except in compliance with the License.
|
|
// You may obtain a copy of the License at
|
|
//
|
|
// http://www.apache.org/licenses/LICENSE-2.0
|
|
//
|
|
// Unless required by applicable law or agreed to in writing, software
|
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
// See the License for the specific language governing permissions and
|
|
// limitations under the License.
|
|
|
|
use rustfs_utils::string::match_simple;
|
|
use s3s::dto::{BucketVersioningStatus, VersioningConfiguration};
|
|
|
|
pub trait VersioningApi {
|
|
fn enabled(&self) -> bool;
|
|
fn prefix_enabled(&self, prefix: &str) -> bool;
|
|
fn prefix_suspended(&self, prefix: &str) -> bool;
|
|
fn delete_state(&self, prefix: &str) -> (bool, bool) {
|
|
(self.prefix_enabled(prefix), self.suspended())
|
|
}
|
|
fn versioned(&self, prefix: &str) -> bool;
|
|
fn suspended(&self) -> bool;
|
|
}
|
|
|
|
impl VersioningApi for VersioningConfiguration {
|
|
fn enabled(&self) -> bool {
|
|
self.status == Some(BucketVersioningStatus::from_static(BucketVersioningStatus::ENABLED))
|
|
}
|
|
fn prefix_enabled(&self, prefix: &str) -> bool {
|
|
if self.status != Some(BucketVersioningStatus::from_static(BucketVersioningStatus::ENABLED)) {
|
|
return false;
|
|
}
|
|
|
|
if prefix.is_empty() {
|
|
return true;
|
|
}
|
|
|
|
if self.exclude_folders.unwrap_or(false) && prefix.ends_with('/') {
|
|
return false;
|
|
}
|
|
|
|
if let Some(ref excluded_prefixes) = self.excluded_prefixes {
|
|
for p in excluded_prefixes.iter() {
|
|
if let Some(ref sprefix) = p.prefix {
|
|
let pattern = format!("{sprefix}*");
|
|
if match_simple(&pattern, prefix) {
|
|
return false;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
true
|
|
}
|
|
|
|
fn prefix_suspended(&self, prefix: &str) -> bool {
|
|
if self.status == Some(BucketVersioningStatus::from_static(BucketVersioningStatus::SUSPENDED)) {
|
|
return true;
|
|
}
|
|
|
|
if self.status == Some(BucketVersioningStatus::from_static(BucketVersioningStatus::ENABLED)) {
|
|
if prefix.is_empty() {
|
|
return false;
|
|
}
|
|
|
|
if let Some(exclude_folders) = self.exclude_folders
|
|
&& exclude_folders
|
|
&& prefix.ends_with('/')
|
|
{
|
|
return true;
|
|
}
|
|
|
|
if let Some(ref excluded_prefixes) = self.excluded_prefixes {
|
|
for p in excluded_prefixes.iter() {
|
|
if let Some(ref sprefix) = p.prefix {
|
|
let pattern = format!("{sprefix}*");
|
|
if match_simple(&pattern, prefix) {
|
|
return true;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
false
|
|
}
|
|
fn versioned(&self, prefix: &str) -> bool {
|
|
self.prefix_enabled(prefix) || self.prefix_suspended(prefix)
|
|
}
|
|
fn suspended(&self) -> bool {
|
|
self.status == Some(BucketVersioningStatus::from_static(BucketVersioningStatus::SUSPENDED))
|
|
}
|
|
}
|
|
|
|
#[cfg(test)]
|
|
mod tests {
|
|
use s3s::dto::{BucketVersioningStatus, ExcludedPrefix};
|
|
|
|
use super::*;
|
|
|
|
struct LegacyVersioning;
|
|
|
|
impl VersioningApi for LegacyVersioning {
|
|
fn enabled(&self) -> bool {
|
|
false
|
|
}
|
|
|
|
fn prefix_enabled(&self, _prefix: &str) -> bool {
|
|
false
|
|
}
|
|
|
|
fn prefix_suspended(&self, _prefix: &str) -> bool {
|
|
false
|
|
}
|
|
|
|
fn versioned(&self, _prefix: &str) -> bool {
|
|
false
|
|
}
|
|
|
|
fn suspended(&self) -> bool {
|
|
false
|
|
}
|
|
}
|
|
|
|
#[test]
|
|
fn delete_state_has_a_backward_compatible_default() {
|
|
assert_eq!(LegacyVersioning.delete_state("object"), (false, false));
|
|
}
|
|
|
|
#[test]
|
|
fn delete_state_treats_excluded_prefixes_as_unversioned() {
|
|
let config = VersioningConfiguration {
|
|
status: Some(BucketVersioningStatus::from_static(BucketVersioningStatus::ENABLED)),
|
|
excluded_prefixes: Some(vec![ExcludedPrefix {
|
|
prefix: Some("archive/".to_string()),
|
|
}]),
|
|
..Default::default()
|
|
};
|
|
|
|
assert_eq!(config.delete_state("archive/object"), (false, false));
|
|
assert!(config.prefix_suspended("archive/object"));
|
|
assert_eq!(config.delete_state("live/object"), (true, false));
|
|
|
|
let suspended = VersioningConfiguration {
|
|
status: Some(BucketVersioningStatus::from_static(BucketVersioningStatus::SUSPENDED)),
|
|
..Default::default()
|
|
};
|
|
assert_eq!(suspended.delete_state("archive/object"), (false, true));
|
|
}
|
|
}
|