admin API refactoring (step 1) #939

Merged
lx merged 19 commits from refactor-admin into next-v2 2025-01-29 20:42:57 +00:00
5 changed files with 86 additions and 222 deletions
Showing only changes of commit 12ea4cda5f - Show all commits

View file

@ -946,14 +946,16 @@ paths:
schema:
$ref: '#/components/schemas/BucketInfo'
/AddGlobalBucketAlias:
/AddBucketAlias:
post:
tags:
- Bucket aliases
operationId: "AddGlobalBucketAlias"
summary: "Add a global alias"
operationId: "AddlBucketAlias"
summary: "Add an alias to a bucket"
description: |
Add a global alias to the target bucket
Add an alias for the target bucket.
This can be a local alias if `accessKeyId` is specified,
or a global alias otherwise.
requestBody:
required: true
content:
@ -961,78 +963,6 @@ paths:
schema:
type: object
required: [bucketId, alias]
properties:
bucketId:
type: string
example: e6a14cd6a27f48684579ec6b381c078ab11697e6bc8513b72b2f5307e25fff9b
alias:
type: string
example: my_documents
responses:
'500':
description: "The server can not handle your request. Check your connectivity with the rest of the cluster."
'400':
description: "Bad request, check your request body"
'404':
description: "Bucket not found"
'200':
description: Returns exhaustive information about the bucket
content:
application/json:
schema:
$ref: '#/components/schemas/BucketInfo'
/RemoveGlobalBucketAlias:
post:
tags:
- Bucket aliases
operationId: "RemoveGlobalBucketAlias"
summary: "Delete a global alias"
description: |
Delete a global alias from the target bucket
requestBody:
required: true
content:
application/json:
schema:
type: object
required: [bucketId, alias]
properties:
bucketId:
type: string
example: e6a14cd6a27f48684579ec6b381c078ab11697e6bc8513b72b2f5307e25fff9b
alias:
type: string
example: my_documents
responses:
'500':
description: "The server can not handle your request. Check your connectivity with the rest of the cluster."
'400':
description: "Bad request, check your request body"
'404':
description: "Bucket not found"
'200':
description: Returns exhaustive information about the bucket
content:
application/json:
schema:
$ref: '#/components/schemas/BucketInfo'
/AddLocalBucketAlias:
post:
tags:
- Bucket aliases
operationId: "AddLocalBucketAlias"
summary: "Add a local alias"
description: |
Add a local alias, bound to specified account, to the target bucket
requestBody:
required: true
content:
application/json:
schema:
type: object
required: [bucketId, accessKeyId, alias]
properties:
bucketId:
type: string
@ -1057,21 +987,23 @@ paths:
schema:
$ref: '#/components/schemas/BucketInfo'
/RemoveGlobalBucketAlias:
/RemoveBucketAlias:
post:
tags:
- Bucket aliases
operationId: "RemoveGlobalBucketAlias"
summary: "Delete a local alias"
operationId: "RemoveBucketAlias"
summary: "Remove an alias from a bucket"
description: |
Delete a local alias, bound to specified account, from the target bucket
Remove an alias for the target bucket.
This can be a local alias if `accessKeyId` is specified,
or a global alias otherwise.
requestBody:
required: true
content:
application/json:
schema:
type: object
required: [bucketId, accessKeyId, alias]
required: [bucketId, alias]
properties:
bucketId:
type: string

View file

@ -750,35 +750,11 @@ Other flags will remain unchanged.
### Operations on bucket aliases
#### AddGlobalBucketAlias `POST /v2/AddGlobalBucketAlias`
#### AddBucketAlias `POST /v2/AddBucketAlias`
Creates a global alias for a bucket.
Request body format:
```json
{
"bucketId": "e6a14cd6a27f48684579ec6b381c078ab11697e6bc8513b72b2f5307e25fff9b",
"alias": "the-bucket"
}
```
#### RemoveGlobalBucketAlias `POST /v2/RemoveGlobalBucketAlias`
Removes a global alias for a bucket.
Request body format:
```json
{
"bucketId": "e6a14cd6a27f48684579ec6b381c078ab11697e6bc8513b72b2f5307e25fff9b",
"alias": "the-bucket"
}
```
#### AddLocalBucketAlias `POST /v2/AddLocalBucketAlias`
Creates a local alias for a bucket in the namespace of a specific access key.
Creates an alias for a bucket in the namespace of a specific access key.
If `accessKeyId` is specified, an alias is created in the local namespace
of the key. Otherwise, a global alias is created.
Request body format:
@ -790,9 +766,11 @@ Request body format:
}
```
#### RemoveLocalBucketAlias `POST /v2/RemoveLocalBucketAlias`
#### RemoveBucketAlias `POST /v2/RemoveBucketAlias`
Removes a local alias for a bucket in the namespace of a specific access key.
Removes an alias for a bucket in the namespace of a specific access key.
If `accessKeyId` is specified, the alias is removed from the local namespace
of the key. Otherwise, the alias is removed from the global namespace.
Request body format:

View file

@ -54,10 +54,8 @@ admin_endpoints![
DenyBucketKey,
// Operations on bucket aliases
AddGlobalBucketAlias,
RemoveGlobalBucketAlias,
AddLocalBucketAlias,
RemoveLocalBucketAlias,
AddBucketAlias,
RemoveBucketAlias,
];
// **********************************************
@ -514,48 +512,26 @@ pub struct DenyBucketKeyResponse(pub GetBucketInfoResponse);
// Operations on bucket aliases
// **********************************************
// ---- AddGlobalBucketAlias ----
// ---- AddBucketAlias ----
#[derive(Serialize, Deserialize)]
pub struct AddGlobalBucketAliasRequest {
pub struct AddBucketAliasRequest {
pub bucket_id: String,
pub access_key_id: Option<String>,
pub alias: String,
}
#[derive(Serialize, Deserialize)]
pub struct AddGlobalBucketAliasResponse(pub GetBucketInfoResponse);
pub struct AddBucketAliasResponse(pub GetBucketInfoResponse);
// ---- RemoveGlobalBucketAlias ----
// ---- RemoveBucketAlias ----
#[derive(Serialize, Deserialize)]
pub struct RemoveGlobalBucketAliasRequest {
pub struct RemoveBucketAliasRequest {
pub bucket_id: String,
pub access_key_id: Option<String>,
pub alias: String,
}
#[derive(Serialize, Deserialize)]
pub struct RemoveGlobalBucketAliasResponse(pub GetBucketInfoResponse);
// ---- AddLocalBucketAlias ----
#[derive(Serialize, Deserialize)]
pub struct AddLocalBucketAliasRequest {
pub bucket_id: String,
pub access_key_id: String,
pub alias: String,
}
#[derive(Serialize, Deserialize)]
pub struct AddLocalBucketAliasResponse(pub GetBucketInfoResponse);
// ---- RemoveLocalBucketAlias ----
#[derive(Serialize, Deserialize)]
pub struct RemoveLocalBucketAliasRequest {
pub bucket_id: String,
pub access_key_id: String,
pub alias: String,
}
#[derive(Serialize, Deserialize)]
pub struct RemoveLocalBucketAliasResponse(pub GetBucketInfoResponse);
pub struct RemoveBucketAliasResponse(pub GetBucketInfoResponse);

View file

@ -18,14 +18,12 @@ use garage_model::s3::object_table::*;
use crate::admin::api::ApiBucketKeyPerm;
use crate::admin::api::{
ApiBucketQuotas, AllowBucketKeyRequest, AllowBucketKeyResponse, DenyBucketKeyRequest,
DenyBucketKeyResponse, BucketKeyPermChangeRequest, BucketLocalAlias, CreateBucketRequest,
CreateBucketResponse, DeleteBucketRequest, DeleteBucketResponse, GetBucketInfoKey,
GetBucketInfoRequest, GetBucketInfoResponse, GetBucketInfoWebsiteResponse,
AddGlobalBucketAliasRequest, AddGlobalBucketAliasResponse, RemoveGlobalBucketAliasRequest,
RemoveGlobalBucketAliasResponse, ListBucketsRequest, ListBucketsResponse, ListBucketsResponseItem,
AddLocalBucketAliasRequest, AddLocalBucketAliasResponse, RemoveLocalBucketAliasRequest,
RemoveLocalBucketAliasResponse, UpdateBucketRequest, UpdateBucketResponse,
AddBucketAliasRequest, AddBucketAliasResponse, AllowBucketKeyRequest, AllowBucketKeyResponse,
ApiBucketQuotas, BucketKeyPermChangeRequest, BucketLocalAlias, CreateBucketRequest,
CreateBucketResponse, DeleteBucketRequest, DeleteBucketResponse, DenyBucketKeyRequest,
DenyBucketKeyResponse, GetBucketInfoKey, GetBucketInfoRequest, GetBucketInfoResponse,
GetBucketInfoWebsiteResponse, ListBucketsRequest, ListBucketsResponse, ListBucketsResponseItem,
RemoveBucketAliasRequest, RemoveBucketAliasResponse, UpdateBucketRequest, UpdateBucketResponse,
};
use crate::admin::error::*;
use crate::admin::EndpointHandler;
@ -453,76 +451,56 @@ pub async fn handle_bucket_change_key_perm(
// ---- BUCKET ALIASES ----
#[async_trait]
impl EndpointHandler for AddGlobalBucketAliasRequest {
type Response = AddGlobalBucketAliasResponse;
impl EndpointHandler for AddBucketAliasRequest {
type Response = AddBucketAliasResponse;
async fn handle(self, garage: &Arc<Garage>) -> Result<AddGlobalBucketAliasResponse, Error> {
async fn handle(self, garage: &Arc<Garage>) -> Result<AddBucketAliasResponse, Error> {
let bucket_id = parse_bucket_id(&self.bucket_id)?;
let helper = garage.locked_helper().await;
match self.access_key_id {
None => {
helper
.set_global_bucket_alias(bucket_id, &self.alias)
.await?;
}
Some(ak) => {
helper
.set_local_bucket_alias(bucket_id, &ak, &self.alias)
.await?;
}
}
Ok(AddGlobalBucketAliasResponse(
Ok(AddBucketAliasResponse(
bucket_info_results(garage, bucket_id).await?,
))
}
}
#[async_trait]
impl EndpointHandler for RemoveGlobalBucketAliasRequest {
type Response = RemoveGlobalBucketAliasResponse;
impl EndpointHandler for RemoveBucketAliasRequest {
type Response = RemoveBucketAliasResponse;
async fn handle(self, garage: &Arc<Garage>) -> Result<RemoveGlobalBucketAliasResponse, Error> {
async fn handle(self, garage: &Arc<Garage>) -> Result<RemoveBucketAliasResponse, Error> {
let bucket_id = parse_bucket_id(&self.bucket_id)?;
let helper = garage.locked_helper().await;
match self.access_key_id {
None => {
helper
.unset_global_bucket_alias(bucket_id, &self.alias)
.await?;
Ok(RemoveGlobalBucketAliasResponse(
bucket_info_results(garage, bucket_id).await?,
))
}
}
#[async_trait]
impl EndpointHandler for AddLocalBucketAliasRequest {
type Response = AddLocalBucketAliasResponse;
async fn handle(self, garage: &Arc<Garage>) -> Result<AddLocalBucketAliasResponse, Error> {
let bucket_id = parse_bucket_id(&self.bucket_id)?;
let helper = garage.locked_helper().await;
Some(ak) => {
helper
.set_local_bucket_alias(bucket_id, &self.access_key_id, &self.alias)
.unset_local_bucket_alias(bucket_id, &ak, &self.alias)
.await?;
Ok(AddLocalBucketAliasResponse(
bucket_info_results(garage, bucket_id).await?,
))
}
}
}
#[async_trait]
impl EndpointHandler for RemoveLocalBucketAliasRequest {
type Response = RemoveLocalBucketAliasResponse;
async fn handle(self, garage: &Arc<Garage>) -> Result<RemoveLocalBucketAliasResponse, Error> {
let bucket_id = parse_bucket_id(&self.bucket_id)?;
let helper = garage.locked_helper().await;
helper
.unset_local_bucket_alias(bucket_id, &self.access_key_id, &self.alias)
.await?;
Ok(RemoveLocalBucketAliasResponse(
Ok(RemoveBucketAliasResponse(
bucket_info_results(garage, bucket_id).await?,
))
}

View file

@ -55,10 +55,8 @@ impl AdminApiRequest {
POST AllowBucketKey (body),
POST DenyBucketKey (body),
// Bucket aliases
POST AddGlobalBucketAlias (body),
POST RemoveGlobalBucketAlias (body),
POST AddLocalBucketAlias (body),
POST RemoveLocalBucketAlias (body),
POST AddBucketAlias (body),
POST RemoveBucketAlias (body),
]);
if let Some(message) = query.nonempty_message() {
@ -174,24 +172,26 @@ impl AdminApiRequest {
Ok(AdminApiRequest::DenyBucketKey(DenyBucketKeyRequest(req)))
}
// Bucket aliasing
Endpoint::GlobalAliasBucket { id, alias } => Ok(AdminApiRequest::AddGlobalBucketAlias(
AddGlobalBucketAliasRequest {
Endpoint::GlobalAliasBucket { id, alias } => {
Ok(AdminApiRequest::AddBucketAlias(AddBucketAliasRequest {
access_key_id: None,
bucket_id: id,
alias,
}))
}
Endpoint::GlobalUnaliasBucket { id, alias } => Ok(AdminApiRequest::RemoveBucketAlias(
RemoveBucketAliasRequest {
access_key_id: None,
bucket_id: id,
alias,
},
)),
Endpoint::GlobalUnaliasBucket { id, alias } => Ok(
AdminApiRequest::RemoveGlobalBucketAlias(RemoveGlobalBucketAliasRequest {
bucket_id: id,
alias,
}),
),
Endpoint::LocalAliasBucket {
id,
access_key_id,
alias,
} => Ok(AdminApiRequest::AddLocalBucketAlias(AddLocalBucketAliasRequest {
access_key_id,
} => Ok(AdminApiRequest::AddBucketAlias(AddBucketAliasRequest {
access_key_id: Some(access_key_id),
bucket_id: id,
alias,
})),
@ -199,9 +199,9 @@ impl AdminApiRequest {
id,
access_key_id,
alias,
} => Ok(AdminApiRequest::RemoveLocalBucketAlias(
RemoveLocalBucketAliasRequest {
access_key_id,
} => Ok(AdminApiRequest::RemoveBucketAlias(
RemoveBucketAliasRequest {
access_key_id: Some(access_key_id),
bucket_id: id,
alias,
},