admin API refactoring (step 1) #939
5 changed files with 86 additions and 222 deletions
|
@ -946,14 +946,16 @@ paths:
|
||||||
schema:
|
schema:
|
||||||
$ref: '#/components/schemas/BucketInfo'
|
$ref: '#/components/schemas/BucketInfo'
|
||||||
|
|
||||||
/AddGlobalBucketAlias:
|
/AddBucketAlias:
|
||||||
post:
|
post:
|
||||||
tags:
|
tags:
|
||||||
- Bucket aliases
|
- Bucket aliases
|
||||||
operationId: "AddGlobalBucketAlias"
|
operationId: "AddlBucketAlias"
|
||||||
summary: "Add a global alias"
|
summary: "Add an alias to a bucket"
|
||||||
description: |
|
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:
|
requestBody:
|
||||||
required: true
|
required: true
|
||||||
content:
|
content:
|
||||||
|
@ -961,78 +963,6 @@ paths:
|
||||||
schema:
|
schema:
|
||||||
type: object
|
type: object
|
||||||
required: [bucketId, alias]
|
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:
|
properties:
|
||||||
bucketId:
|
bucketId:
|
||||||
type: string
|
type: string
|
||||||
|
@ -1057,21 +987,23 @@ paths:
|
||||||
schema:
|
schema:
|
||||||
$ref: '#/components/schemas/BucketInfo'
|
$ref: '#/components/schemas/BucketInfo'
|
||||||
|
|
||||||
/RemoveGlobalBucketAlias:
|
/RemoveBucketAlias:
|
||||||
post:
|
post:
|
||||||
tags:
|
tags:
|
||||||
- Bucket aliases
|
- Bucket aliases
|
||||||
operationId: "RemoveGlobalBucketAlias"
|
operationId: "RemoveBucketAlias"
|
||||||
summary: "Delete a local alias"
|
summary: "Remove an alias from a bucket"
|
||||||
description: |
|
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:
|
requestBody:
|
||||||
required: true
|
required: true
|
||||||
content:
|
content:
|
||||||
application/json:
|
application/json:
|
||||||
schema:
|
schema:
|
||||||
type: object
|
type: object
|
||||||
required: [bucketId, accessKeyId, alias]
|
required: [bucketId, alias]
|
||||||
properties:
|
properties:
|
||||||
bucketId:
|
bucketId:
|
||||||
type: string
|
type: string
|
||||||
|
|
|
@ -750,35 +750,11 @@ Other flags will remain unchanged.
|
||||||
|
|
||||||
### Operations on bucket aliases
|
### Operations on bucket aliases
|
||||||
|
|
||||||
#### AddGlobalBucketAlias `POST /v2/AddGlobalBucketAlias`
|
#### AddBucketAlias `POST /v2/AddBucketAlias`
|
||||||
|
|
||||||
Creates a global alias for a bucket.
|
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
|
||||||
Request body format:
|
of the key. Otherwise, a global alias is created.
|
||||||
|
|
||||||
```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.
|
|
||||||
|
|
||||||
Request body format:
|
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:
|
Request body format:
|
||||||
|
|
||||||
|
|
|
@ -54,10 +54,8 @@ admin_endpoints![
|
||||||
DenyBucketKey,
|
DenyBucketKey,
|
||||||
|
|
||||||
// Operations on bucket aliases
|
// Operations on bucket aliases
|
||||||
AddGlobalBucketAlias,
|
AddBucketAlias,
|
||||||
RemoveGlobalBucketAlias,
|
RemoveBucketAlias,
|
||||||
AddLocalBucketAlias,
|
|
||||||
RemoveLocalBucketAlias,
|
|
||||||
];
|
];
|
||||||
|
|
||||||
// **********************************************
|
// **********************************************
|
||||||
|
@ -514,48 +512,26 @@ pub struct DenyBucketKeyResponse(pub GetBucketInfoResponse);
|
||||||
// Operations on bucket aliases
|
// Operations on bucket aliases
|
||||||
// **********************************************
|
// **********************************************
|
||||||
|
|
||||||
// ---- AddGlobalBucketAlias ----
|
// ---- AddBucketAlias ----
|
||||||
|
|
||||||
#[derive(Serialize, Deserialize)]
|
#[derive(Serialize, Deserialize)]
|
||||||
pub struct AddGlobalBucketAliasRequest {
|
pub struct AddBucketAliasRequest {
|
||||||
pub bucket_id: String,
|
pub bucket_id: String,
|
||||||
|
pub access_key_id: Option<String>,
|
||||||
pub alias: String,
|
pub alias: String,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Serialize, Deserialize)]
|
#[derive(Serialize, Deserialize)]
|
||||||
pub struct AddGlobalBucketAliasResponse(pub GetBucketInfoResponse);
|
pub struct AddBucketAliasResponse(pub GetBucketInfoResponse);
|
||||||
|
|
||||||
// ---- RemoveGlobalBucketAlias ----
|
// ---- RemoveBucketAlias ----
|
||||||
|
|
||||||
#[derive(Serialize, Deserialize)]
|
#[derive(Serialize, Deserialize)]
|
||||||
pub struct RemoveGlobalBucketAliasRequest {
|
pub struct RemoveBucketAliasRequest {
|
||||||
pub bucket_id: String,
|
pub bucket_id: String,
|
||||||
|
pub access_key_id: Option<String>,
|
||||||
pub alias: String,
|
pub alias: String,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Serialize, Deserialize)]
|
#[derive(Serialize, Deserialize)]
|
||||||
pub struct RemoveGlobalBucketAliasResponse(pub GetBucketInfoResponse);
|
pub struct RemoveBucketAliasResponse(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);
|
|
||||||
|
|
|
@ -18,14 +18,12 @@ use garage_model::s3::object_table::*;
|
||||||
|
|
||||||
use crate::admin::api::ApiBucketKeyPerm;
|
use crate::admin::api::ApiBucketKeyPerm;
|
||||||
use crate::admin::api::{
|
use crate::admin::api::{
|
||||||
ApiBucketQuotas, AllowBucketKeyRequest, AllowBucketKeyResponse, DenyBucketKeyRequest,
|
AddBucketAliasRequest, AddBucketAliasResponse, AllowBucketKeyRequest, AllowBucketKeyResponse,
|
||||||
DenyBucketKeyResponse, BucketKeyPermChangeRequest, BucketLocalAlias, CreateBucketRequest,
|
ApiBucketQuotas, BucketKeyPermChangeRequest, BucketLocalAlias, CreateBucketRequest,
|
||||||
CreateBucketResponse, DeleteBucketRequest, DeleteBucketResponse, GetBucketInfoKey,
|
CreateBucketResponse, DeleteBucketRequest, DeleteBucketResponse, DenyBucketKeyRequest,
|
||||||
GetBucketInfoRequest, GetBucketInfoResponse, GetBucketInfoWebsiteResponse,
|
DenyBucketKeyResponse, GetBucketInfoKey, GetBucketInfoRequest, GetBucketInfoResponse,
|
||||||
AddGlobalBucketAliasRequest, AddGlobalBucketAliasResponse, RemoveGlobalBucketAliasRequest,
|
GetBucketInfoWebsiteResponse, ListBucketsRequest, ListBucketsResponse, ListBucketsResponseItem,
|
||||||
RemoveGlobalBucketAliasResponse, ListBucketsRequest, ListBucketsResponse, ListBucketsResponseItem,
|
RemoveBucketAliasRequest, RemoveBucketAliasResponse, UpdateBucketRequest, UpdateBucketResponse,
|
||||||
AddLocalBucketAliasRequest, AddLocalBucketAliasResponse, RemoveLocalBucketAliasRequest,
|
|
||||||
RemoveLocalBucketAliasResponse, UpdateBucketRequest, UpdateBucketResponse,
|
|
||||||
};
|
};
|
||||||
use crate::admin::error::*;
|
use crate::admin::error::*;
|
||||||
use crate::admin::EndpointHandler;
|
use crate::admin::EndpointHandler;
|
||||||
|
@ -453,76 +451,56 @@ pub async fn handle_bucket_change_key_perm(
|
||||||
// ---- BUCKET ALIASES ----
|
// ---- BUCKET ALIASES ----
|
||||||
|
|
||||||
#[async_trait]
|
#[async_trait]
|
||||||
impl EndpointHandler for AddGlobalBucketAliasRequest {
|
impl EndpointHandler for AddBucketAliasRequest {
|
||||||
type Response = AddGlobalBucketAliasResponse;
|
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 bucket_id = parse_bucket_id(&self.bucket_id)?;
|
||||||
|
|
||||||
let helper = garage.locked_helper().await;
|
let helper = garage.locked_helper().await;
|
||||||
|
|
||||||
helper
|
match self.access_key_id {
|
||||||
.set_global_bucket_alias(bucket_id, &self.alias)
|
None => {
|
||||||
.await?;
|
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?,
|
bucket_info_results(garage, bucket_id).await?,
|
||||||
))
|
))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[async_trait]
|
#[async_trait]
|
||||||
impl EndpointHandler for RemoveGlobalBucketAliasRequest {
|
impl EndpointHandler for RemoveBucketAliasRequest {
|
||||||
type Response = RemoveGlobalBucketAliasResponse;
|
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 bucket_id = parse_bucket_id(&self.bucket_id)?;
|
||||||
|
|
||||||
let helper = garage.locked_helper().await;
|
let helper = garage.locked_helper().await;
|
||||||
|
|
||||||
helper
|
match self.access_key_id {
|
||||||
.unset_global_bucket_alias(bucket_id, &self.alias)
|
None => {
|
||||||
.await?;
|
helper
|
||||||
|
.unset_global_bucket_alias(bucket_id, &self.alias)
|
||||||
|
.await?;
|
||||||
|
}
|
||||||
|
Some(ak) => {
|
||||||
|
helper
|
||||||
|
.unset_local_bucket_alias(bucket_id, &ak, &self.alias)
|
||||||
|
.await?;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
Ok(RemoveGlobalBucketAliasResponse(
|
Ok(RemoveBucketAliasResponse(
|
||||||
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;
|
|
||||||
|
|
||||||
helper
|
|
||||||
.set_local_bucket_alias(bucket_id, &self.access_key_id, &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(
|
|
||||||
bucket_info_results(garage, bucket_id).await?,
|
bucket_info_results(garage, bucket_id).await?,
|
||||||
))
|
))
|
||||||
}
|
}
|
||||||
|
|
|
@ -55,10 +55,8 @@ impl AdminApiRequest {
|
||||||
POST AllowBucketKey (body),
|
POST AllowBucketKey (body),
|
||||||
POST DenyBucketKey (body),
|
POST DenyBucketKey (body),
|
||||||
// Bucket aliases
|
// Bucket aliases
|
||||||
POST AddGlobalBucketAlias (body),
|
POST AddBucketAlias (body),
|
||||||
POST RemoveGlobalBucketAlias (body),
|
POST RemoveBucketAlias (body),
|
||||||
POST AddLocalBucketAlias (body),
|
|
||||||
POST RemoveLocalBucketAlias (body),
|
|
||||||
]);
|
]);
|
||||||
|
|
||||||
if let Some(message) = query.nonempty_message() {
|
if let Some(message) = query.nonempty_message() {
|
||||||
|
@ -174,24 +172,26 @@ impl AdminApiRequest {
|
||||||
Ok(AdminApiRequest::DenyBucketKey(DenyBucketKeyRequest(req)))
|
Ok(AdminApiRequest::DenyBucketKey(DenyBucketKeyRequest(req)))
|
||||||
}
|
}
|
||||||
// Bucket aliasing
|
// Bucket aliasing
|
||||||
Endpoint::GlobalAliasBucket { id, alias } => Ok(AdminApiRequest::AddGlobalBucketAlias(
|
Endpoint::GlobalAliasBucket { id, alias } => {
|
||||||
AddGlobalBucketAliasRequest {
|
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,
|
bucket_id: id,
|
||||||
alias,
|
alias,
|
||||||
},
|
},
|
||||||
)),
|
)),
|
||||||
Endpoint::GlobalUnaliasBucket { id, alias } => Ok(
|
|
||||||
AdminApiRequest::RemoveGlobalBucketAlias(RemoveGlobalBucketAliasRequest {
|
|
||||||
bucket_id: id,
|
|
||||||
alias,
|
|
||||||
}),
|
|
||||||
),
|
|
||||||
Endpoint::LocalAliasBucket {
|
Endpoint::LocalAliasBucket {
|
||||||
id,
|
id,
|
||||||
access_key_id,
|
access_key_id,
|
||||||
alias,
|
alias,
|
||||||
} => Ok(AdminApiRequest::AddLocalBucketAlias(AddLocalBucketAliasRequest {
|
} => Ok(AdminApiRequest::AddBucketAlias(AddBucketAliasRequest {
|
||||||
access_key_id,
|
access_key_id: Some(access_key_id),
|
||||||
bucket_id: id,
|
bucket_id: id,
|
||||||
alias,
|
alias,
|
||||||
})),
|
})),
|
||||||
|
@ -199,9 +199,9 @@ impl AdminApiRequest {
|
||||||
id,
|
id,
|
||||||
access_key_id,
|
access_key_id,
|
||||||
alias,
|
alias,
|
||||||
} => Ok(AdminApiRequest::RemoveLocalBucketAlias(
|
} => Ok(AdminApiRequest::RemoveBucketAlias(
|
||||||
RemoveLocalBucketAliasRequest {
|
RemoveBucketAliasRequest {
|
||||||
access_key_id,
|
access_key_id: Some(access_key_id),
|
||||||
bucket_id: id,
|
bucket_id: id,
|
||||||
alias,
|
alias,
|
||||||
},
|
},
|
||||||
|
|
Loading…
Add table
Reference in a new issue