more complete admin API #298
4 changed files with 133 additions and 9 deletions
|
@ -501,3 +501,22 @@ Request body format:
|
||||||
|
|
||||||
Flags in `permissions` which have the value `true` will be deactivated.
|
Flags in `permissions` which have the value `true` will be deactivated.
|
||||||
Other flags will remain unchanged.
|
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.
|
||||||
|
|
||||||
|
|
|
@ -151,6 +151,23 @@ impl ApiHandler for AdminApiServer {
|
||||||
Endpoint::BucketDenyKey => {
|
Endpoint::BucketDenyKey => {
|
||||||
handle_bucket_change_key_perm(&self.garage, req, false).await
|
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,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -87,10 +87,7 @@ pub async fn handle_get_bucket_info(
|
||||||
global_alias: Option<String>,
|
global_alias: Option<String>,
|
||||||
) -> Result<Response<Body>, Error> {
|
) -> Result<Response<Body>, Error> {
|
||||||
let bucket_id = match (id, global_alias) {
|
let bucket_id = match (id, global_alias) {
|
||||||
(Some(id), None) => {
|
(Some(id), None) => parse_bucket_id(&id)?,
|
||||||
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")?
|
|
||||||
}
|
|
||||||
(None, Some(ga)) => garage
|
(None, Some(ga)) => garage
|
||||||
.bucket_helper()
|
.bucket_helper()
|
||||||
.resolve_global_bucket_name(&ga)
|
.resolve_global_bucket_name(&ga)
|
||||||
|
@ -324,8 +321,7 @@ pub async fn handle_delete_bucket(
|
||||||
) -> Result<Response<Body>, Error> {
|
) -> Result<Response<Body>, Error> {
|
||||||
let helper = garage.bucket_helper();
|
let helper = garage.bucket_helper();
|
||||||
|
|
||||||
let id_hex = hex::decode(&id).ok_or_bad_request("Invalid bucket id")?;
|
let bucket_id = parse_bucket_id(&id)?;
|
||||||
let bucket_id = Uuid::try_from(&id_hex).ok_or_bad_request("Invalid bucket id")?;
|
|
||||||
|
|
||||||
let mut bucket = helper.get_existing_bucket(bucket_id).await?;
|
let mut bucket = helper.get_existing_bucket(bucket_id).await?;
|
||||||
let state = bucket.state.as_option().unwrap();
|
let state = bucket.state.as_option().unwrap();
|
||||||
|
@ -385,8 +381,7 @@ pub async fn handle_bucket_change_key_perm(
|
||||||
) -> Result<Response<Body>, Error> {
|
) -> Result<Response<Body>, Error> {
|
||||||
let req = parse_json_body::<BucketKeyPermChangeRequest>(req).await?;
|
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 = parse_bucket_id(&req.bucket_id)?;
|
||||||
let bucket_id = Uuid::try_from(&id_hex).ok_or_bad_request("Invalid bucket id")?;
|
|
||||||
|
|
||||||
let bucket = garage
|
let bucket = garage
|
||||||
.bucket_helper()
|
.bucket_helper()
|
||||||
|
@ -430,3 +425,70 @@ struct BucketKeyPermChangeRequest {
|
||||||
access_key_id: String,
|
access_key_id: String,
|
||||||
permissions: ApiBucketKeyPerm,
|
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")?)
|
||||||
|
}
|
||||||
|
|
|
@ -49,6 +49,25 @@ pub enum Endpoint {
|
||||||
// Bucket-Key Permissions
|
// Bucket-Key Permissions
|
||||||
BucketAllowKey,
|
BucketAllowKey,
|
||||||
BucketDenyKey,
|
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 {
|
impl Endpoint {
|
||||||
|
@ -87,6 +106,11 @@ impl Endpoint {
|
||||||
// Bucket-key permissions
|
// Bucket-key permissions
|
||||||
POST "/bucket/allow" => BucketAllowKey,
|
POST "/bucket/allow" => BucketAllowKey,
|
||||||
POST "/bucket/deny" => BucketDenyKey,
|
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() {
|
if let Some(message) = query.nonempty_message() {
|
||||||
|
@ -107,5 +131,7 @@ impl Endpoint {
|
||||||
generateQueryParameters! {
|
generateQueryParameters! {
|
||||||
"id" => id,
|
"id" => id,
|
||||||
"search" => search,
|
"search" => search,
|
||||||
"globalAlias" => global_alias
|
"globalAlias" => global_alias,
|
||||||
|
"alias" => alias,
|
||||||
|
"accessKeyId" => access_key_id
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue