move bucket search logic from helper to admin api
This commit is contained in:
parent
22c0420607
commit
eb40475f1e
2 changed files with 47 additions and 56 deletions
|
@ -82,15 +82,56 @@ impl RequestHandler for GetBucketInfoRequest {
|
||||||
let bucket_id = match (self.id, self.global_alias, self.search) {
|
let bucket_id = match (self.id, self.global_alias, self.search) {
|
||||||
(Some(id), None, None) => parse_bucket_id(&id)?,
|
(Some(id), None, None) => parse_bucket_id(&id)?,
|
||||||
(None, Some(ga), None) => garage
|
(None, Some(ga), None) => garage
|
||||||
.bucket_helper()
|
.bucket_alias_table
|
||||||
.resolve_global_bucket_name(&ga)
|
.get(&EmptyKey, &ga)
|
||||||
.await?
|
.await?
|
||||||
|
.and_then(|x| *x.state.get())
|
||||||
.ok_or_else(|| HelperError::NoSuchBucket(ga.to_string()))?,
|
.ok_or_else(|| HelperError::NoSuchBucket(ga.to_string()))?,
|
||||||
(None, None, Some(search)) => {
|
(None, None, Some(search)) => {
|
||||||
garage
|
let helper = garage.bucket_helper();
|
||||||
.bucket_helper()
|
if let Some(uuid) = helper.resolve_global_bucket_name(&search).await? {
|
||||||
.admin_get_existing_matching_bucket(&search)
|
uuid
|
||||||
.await?
|
} else {
|
||||||
|
let hexdec = if search.len() >= 2 {
|
||||||
|
search
|
||||||
|
.get(..search.len() & !1)
|
||||||
|
.and_then(|x| hex::decode(x).ok())
|
||||||
|
} else {
|
||||||
|
None
|
||||||
|
};
|
||||||
|
let hex = hexdec
|
||||||
|
.ok_or_else(|| Error::Common(CommonError::NoSuchBucket(search.clone())))?;
|
||||||
|
|
||||||
|
let mut start = [0u8; 32];
|
||||||
|
start
|
||||||
|
.as_mut_slice()
|
||||||
|
.get_mut(..hex.len())
|
||||||
|
.ok_or_bad_request("invalid length")?
|
||||||
|
.copy_from_slice(&hex);
|
||||||
|
let mut candidates = garage
|
||||||
|
.bucket_table
|
||||||
|
.get_range(
|
||||||
|
&EmptyKey,
|
||||||
|
Some(start.into()),
|
||||||
|
Some(DeletedFilter::NotDeleted),
|
||||||
|
10,
|
||||||
|
EnumerationOrder::Forward,
|
||||||
|
)
|
||||||
|
.await?
|
||||||
|
.into_iter()
|
||||||
|
.collect::<Vec<_>>();
|
||||||
|
candidates.retain(|x| hex::encode(x.id).starts_with(&search));
|
||||||
|
if candidates.is_empty() {
|
||||||
|
return Err(Error::Common(CommonError::NoSuchBucket(search.clone())));
|
||||||
|
} else if candidates.len() == 1 {
|
||||||
|
candidates.into_iter().next().unwrap().id
|
||||||
|
} else {
|
||||||
|
return Err(Error::bad_request(format!(
|
||||||
|
"Several matching buckets: {}",
|
||||||
|
search
|
||||||
|
)));
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
_ => {
|
_ => {
|
||||||
return Err(Error::bad_request(
|
return Err(Error::bad_request(
|
||||||
|
|
|
@ -67,56 +67,6 @@ impl<'a> BucketHelper<'a> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Find a bucket by its global alias or a prefix of its uuid
|
|
||||||
pub async fn admin_get_existing_matching_bucket(
|
|
||||||
&self,
|
|
||||||
pattern: &String,
|
|
||||||
) -> Result<Uuid, Error> {
|
|
||||||
if let Some(uuid) = self.resolve_global_bucket_name(pattern).await? {
|
|
||||||
Ok(uuid)
|
|
||||||
} else {
|
|
||||||
let hexdec = if pattern.len() >= 2 {
|
|
||||||
pattern
|
|
||||||
.get(..pattern.len() & !1)
|
|
||||||
.and_then(|x| hex::decode(x).ok())
|
|
||||||
} else {
|
|
||||||
None
|
|
||||||
};
|
|
||||||
let hex = hexdec.ok_or_else(|| Error::NoSuchBucket(pattern.clone()))?;
|
|
||||||
|
|
||||||
let mut start = [0u8; 32];
|
|
||||||
start
|
|
||||||
.as_mut_slice()
|
|
||||||
.get_mut(..hex.len())
|
|
||||||
.ok_or_bad_request("invalid length")?
|
|
||||||
.copy_from_slice(&hex);
|
|
||||||
let mut candidates = self
|
|
||||||
.0
|
|
||||||
.bucket_table
|
|
||||||
.get_range(
|
|
||||||
&EmptyKey,
|
|
||||||
Some(start.into()),
|
|
||||||
Some(DeletedFilter::NotDeleted),
|
|
||||||
10,
|
|
||||||
EnumerationOrder::Forward,
|
|
||||||
)
|
|
||||||
.await?
|
|
||||||
.into_iter()
|
|
||||||
.collect::<Vec<_>>();
|
|
||||||
candidates.retain(|x| hex::encode(x.id).starts_with(pattern));
|
|
||||||
if candidates.is_empty() {
|
|
||||||
Err(Error::NoSuchBucket(pattern.clone()))
|
|
||||||
} else if candidates.len() == 1 {
|
|
||||||
Ok(candidates.into_iter().next().unwrap().id)
|
|
||||||
} else {
|
|
||||||
Err(Error::BadRequest(format!(
|
|
||||||
"Several matching buckets: {}",
|
|
||||||
pattern
|
|
||||||
)))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Returns a Bucket if it is present in bucket table,
|
/// Returns a Bucket if it is present in bucket table,
|
||||||
/// even if it is in deleted state. Querying a non-existing
|
/// even if it is in deleted state. Querying a non-existing
|
||||||
/// bucket ID returns an internal error.
|
/// bucket ID returns an internal error.
|
||||||
|
|
Loading…
Add table
Reference in a new issue