mirror of
https://github.com/deuxfleurs-org/garage.git
synced 2026-08-28 07:57:02 +00:00
New model for buckets
This commit is contained in:
+55
-7
@@ -1,9 +1,12 @@
|
||||
use std::collections::HashMap;
|
||||
use std::sync::Arc;
|
||||
|
||||
use hyper::{Body, Response};
|
||||
|
||||
use garage_model::garage::Garage;
|
||||
use garage_model::key_table::Key;
|
||||
use garage_table::util::EmptyKey;
|
||||
use garage_util::crdt::*;
|
||||
use garage_util::time::*;
|
||||
|
||||
use crate::error::*;
|
||||
@@ -34,20 +37,65 @@ pub fn handle_get_bucket_versioning() -> Result<Response<Body>, Error> {
|
||||
.body(Body::from(xml.into_bytes()))?)
|
||||
}
|
||||
|
||||
pub fn handle_list_buckets(api_key: &Key) -> Result<Response<Body>, Error> {
|
||||
pub async fn handle_list_buckets(garage: &Garage, api_key: &Key) -> Result<Response<Body>, Error> {
|
||||
let key_state = api_key.state.as_option().ok_or_internal_error(
|
||||
"Key should not be in deleted state at this point (internal error)",
|
||||
)?;
|
||||
|
||||
// Collect buckets user has access to
|
||||
let ids = api_key
|
||||
.state
|
||||
.as_option()
|
||||
.unwrap()
|
||||
.authorized_buckets
|
||||
.items()
|
||||
.iter()
|
||||
.filter(|(_, perms)| perms.allow_read || perms.allow_write)
|
||||
.map(|(id, _)| *id)
|
||||
.collect::<Vec<_>>();
|
||||
|
||||
let mut buckets_by_id = HashMap::new();
|
||||
let mut aliases = HashMap::new();
|
||||
|
||||
for bucket_id in ids.iter() {
|
||||
let bucket = garage.bucket_table.get(bucket_id, &EmptyKey).await?;
|
||||
if let Some(bucket) = bucket {
|
||||
if let Deletable::Present(param) = bucket.state {
|
||||
for (alias, _, active) in param.aliases.items() {
|
||||
if *active {
|
||||
let alias_ent = garage.bucket_alias_table.get(&EmptyKey, alias).await?;
|
||||
if let Some(alias_ent) = alias_ent {
|
||||
if let Some(alias_p) = alias_ent.state.get().as_option() {
|
||||
if alias_p.bucket_id == *bucket_id {
|
||||
aliases.insert(alias_ent.name.clone(), *bucket_id);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
buckets_by_id.insert(bucket_id, param);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (alias, _, id) in key_state.local_aliases.items() {
|
||||
if let Some(id) = id.as_option() {
|
||||
aliases.insert(alias.clone(), *id);
|
||||
}
|
||||
}
|
||||
|
||||
// Generate response
|
||||
let list_buckets = s3_xml::ListAllMyBucketsResult {
|
||||
owner: s3_xml::Owner {
|
||||
display_name: s3_xml::Value(api_key.name.get().to_string()),
|
||||
id: s3_xml::Value(api_key.key_id.to_string()),
|
||||
},
|
||||
buckets: s3_xml::BucketList {
|
||||
entries: api_key
|
||||
.authorized_buckets
|
||||
.items()
|
||||
entries: aliases
|
||||
.iter()
|
||||
.filter(|(_, _, perms)| perms.allow_read || perms.allow_write)
|
||||
.map(|(name, ts, _)| s3_xml::Bucket {
|
||||
creation_date: s3_xml::Value(msec_to_rfc3339(*ts)),
|
||||
.filter_map(|(name, id)| buckets_by_id.get(id).map(|p| (name, id, p)))
|
||||
.map(|(name, _id, param)| s3_xml::Bucket {
|
||||
creation_date: s3_xml::Value(msec_to_rfc3339(param.creation_date)),
|
||||
name: s3_xml::Value(name.to_string()),
|
||||
})
|
||||
.collect(),
|
||||
|
||||
Reference in New Issue
Block a user