aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlex Auvolat <alex@adnab.me>2022-05-17 17:16:29 +0200
committerAlex Auvolat <alex@adnab.me>2022-05-17 17:16:29 +0200
commit2ce3513c108a53bdcc5a838704867a4499295d85 (patch)
tree77681eee926bd532a2568dafab899d13691b0e8c
parente92c52eb6522a140cdced40bc047149dc638bfa4 (diff)
downloadgarage-2ce3513c108a53bdcc5a838704867a4499295d85.tar.gz
garage-2ce3513c108a53bdcc5a838704867a4499295d85.zip
Specify and implement {Global,Local}{Alias,Unalias}Bucket
-rw-r--r--doc/drafts/admin-api.md19
-rw-r--r--src/api/admin/api_server.rs17
-rw-r--r--src/api/admin/bucket.rs78
-rw-r--r--src/api/admin/router.rs28
4 files changed, 133 insertions, 9 deletions
diff --git a/doc/drafts/admin-api.md b/doc/drafts/admin-api.md
index 5dc3f127..14c4ec39 100644
--- a/doc/drafts/admin-api.md
+++ b/doc/drafts/admin-api.md
@@ -501,3 +501,22 @@ Request body format:
Flags in `permissions` which have the value `true` will be deactivated.
Other flags will remain unchanged.
+
+## Operations on bucket aliases
+
+### GlobalAliasBucket `PUT /bucket/alias/global?id=<bucket id>&alias=<global alias>`
+
+Empty body. Creates a global alias for a bucket.
+
+### GlobalUnaliasBucket `DELETE /bucket/alias/global?id=<bucket id>&alias=<global alias>`
+
+Removes a global alias for a bucket.
+
+### LocalAliasBucket `PUT /bucket/alias/local?id=<bucket id>&accessKeyId=<access key ID>&alias=<local alias>`
+
+Empty body. Creates a local alias for a bucket in the namespace of a specific access key.
+
+### LocalUnaliasBucket `DELETE /bucket/alias/local?id=<bucket id>&accessKeyId<access key ID>&alias=<local alias>`
+
+Removes a local alias for a bucket in the namespace of a specific access key.
+
diff --git a/src/api/admin/api_server.rs b/src/api/admin/api_server.rs
index 098a54aa..a51d66e5 100644
--- a/src/api/admin/api_server.rs
+++ b/src/api/admin/api_server.rs
@@ -151,6 +151,23 @@ impl ApiHandler for AdminApiServer {
Endpoint::BucketDenyKey => {
handle_bucket_change_key_perm(&self.garage, req, false).await
}
+ // Bucket aliasing
+ Endpoint::GlobalAliasBucket { id, alias } => {
+ handle_global_alias_bucket(&self.garage, id, alias).await
+ }
+ Endpoint::GlobalUnaliasBucket { id, alias } => {
+ handle_global_unalias_bucket(&self.garage, id, alias).await
+ }
+ Endpoint::LocalAliasBucket {
+ id,
+ access_key_id,
+ alias,
+ } => handle_local_alias_bucket(&self.garage, id, access_key_id, alias).await,
+ Endpoint::LocalUnaliasBucket {
+ id,
+ access_key_id,
+ alias,
+ } => handle_local_unalias_bucket(&self.garage, id, access_key_id, alias).await,
}
}
}
diff --git a/src/api/admin/bucket.rs b/src/api/admin/bucket.rs
index 2124f2c2..cc37089a 100644
--- a/src/api/admin/bucket.rs
+++ b/src/api/admin/bucket.rs
@@ -87,10 +87,7 @@ pub async fn handle_get_bucket_info(
global_alias: Option<String>,
) -> Result<Response<Body>, Error> {
let bucket_id = match (id, global_alias) {
- (Some(id), None) => {
- let id_hex = hex::decode(&id).ok_or_bad_request("Invalid bucket id")?;
- Uuid::try_from(&id_hex).ok_or_bad_request("Invalid bucket id")?
- }
+ (Some(id), None) => parse_bucket_id(&id)?,
(None, Some(ga)) => garage
.bucket_helper()
.resolve_global_bucket_name(&ga)
@@ -324,8 +321,7 @@ pub async fn handle_delete_bucket(
) -> Result<Response<Body>, Error> {
let helper = garage.bucket_helper();
- let id_hex = hex::decode(&id).ok_or_bad_request("Invalid bucket id")?;
- let bucket_id = Uuid::try_from(&id_hex).ok_or_bad_request("Invalid bucket id")?;
+ let bucket_id = parse_bucket_id(&id)?;
let mut bucket = helper.get_existing_bucket(bucket_id).await?;
let state = bucket.state.as_option().unwrap();
@@ -385,8 +381,7 @@ pub async fn handle_bucket_change_key_perm(
) -> Result<Response<Body>, Error> {
let req = parse_json_body::<BucketKeyPermChangeRequest>(req).await?;
- let id_hex = hex::decode(&req.bucket_id).ok_or_bad_request("Invalid bucket id")?;
- let bucket_id = Uuid::try_from(&id_hex).ok_or_bad_request("Invalid bucket id")?;
+ let bucket_id = parse_bucket_id(&req.bucket_id)?;
let bucket = garage
.bucket_helper()
@@ -430,3 +425,70 @@ struct BucketKeyPermChangeRequest {
access_key_id: String,
permissions: ApiBucketKeyPerm,
}
+
+pub async fn handle_global_alias_bucket(
+ garage: &Arc<Garage>,
+ bucket_id: String,
+ alias: String,
+) -> Result<Response<Body>, Error> {
+ let bucket_id = parse_bucket_id(&bucket_id)?;
+
+ garage
+ .bucket_helper()
+ .set_global_bucket_alias(bucket_id, &alias)
+ .await?;
+
+ bucket_info_results(garage, bucket_id).await
+}
+
+pub async fn handle_global_unalias_bucket(
+ garage: &Arc<Garage>,
+ bucket_id: String,
+ alias: String,
+) -> Result<Response<Body>, Error> {
+ let bucket_id = parse_bucket_id(&bucket_id)?;
+
+ garage
+ .bucket_helper()
+ .unset_global_bucket_alias(bucket_id, &alias)
+ .await?;
+
+ bucket_info_results(garage, bucket_id).await
+}
+
+pub async fn handle_local_alias_bucket(
+ garage: &Arc<Garage>,
+ bucket_id: String,
+ access_key_id: String,
+ alias: String,
+) -> Result<Response<Body>, Error> {
+ let bucket_id = parse_bucket_id(&bucket_id)?;
+
+ garage
+ .bucket_helper()
+ .set_local_bucket_alias(bucket_id, &access_key_id, &alias)
+ .await?;
+
+ bucket_info_results(garage, bucket_id).await
+}
+
+pub async fn handle_local_unalias_bucket(
+ garage: &Arc<Garage>,
+ bucket_id: String,
+ access_key_id: String,
+ alias: String,
+) -> Result<Response<Body>, Error> {
+ let bucket_id = parse_bucket_id(&bucket_id)?;
+
+ garage
+ .bucket_helper()
+ .unset_local_bucket_alias(bucket_id, &access_key_id, &alias)
+ .await?;
+
+ bucket_info_results(garage, bucket_id).await
+}
+
+fn parse_bucket_id(id: &str) -> Result<Uuid, Error> {
+ let id_hex = hex::decode(&id).ok_or_bad_request("Invalid bucket id")?;
+ Ok(Uuid::try_from(&id_hex).ok_or_bad_request("Invalid bucket id")?)
+}
diff --git a/src/api/admin/router.rs b/src/api/admin/router.rs
index 2a5098bf..6961becb 100644
--- a/src/api/admin/router.rs
+++ b/src/api/admin/router.rs
@@ -49,6 +49,25 @@ pub enum Endpoint {
// Bucket-Key Permissions
BucketAllowKey,
BucketDenyKey,
+ // Bucket aliases
+ GlobalAliasBucket {
+ id: String,
+ alias: String,
+ },
+ GlobalUnaliasBucket {
+ id: String,
+ alias: String,
+ },
+ LocalAliasBucket {
+ id: String,
+ access_key_id: String,
+ alias: String,
+ },
+ LocalUnaliasBucket {
+ id: String,
+ access_key_id: String,
+ alias: String,
+ },
}}
impl Endpoint {
@@ -87,6 +106,11 @@ impl Endpoint {
// Bucket-key permissions
POST "/bucket/allow" => BucketAllowKey,
POST "/bucket/deny" => BucketDenyKey,
+ // Bucket aliases
+ PUT "/bucket/alias/global" => GlobalAliasBucket (query::id, query::alias),
+ DELETE "/bucket/alias/global" => GlobalUnaliasBucket (query::id, query::alias),
+ PUT "/bucket/alias/local" => LocalAliasBucket (query::id, query::access_key_id, query::alias),
+ DELETE "/bucket/alias/local" => LocalUnaliasBucket (query::id, query::access_key_id, query::alias),
]);
if let Some(message) = query.nonempty_message() {
@@ -107,5 +131,7 @@ impl Endpoint {
generateQueryParameters! {
"id" => id,
"search" => search,
- "globalAlias" => global_alias
+ "globalAlias" => global_alias,
+ "alias" => alias,
+ "accessKeyId" => access_key_id
}