more complete admin API #298
6 changed files with 35 additions and 43 deletions
|
@ -248,11 +248,10 @@ pub async fn handle_create_bucket(
|
||||||
}
|
}
|
||||||
|
|
||||||
let key = garage
|
let key = garage
|
||||||
.key_table
|
.key_helper()
|
||||||
.get(&EmptyKey, &la.access_key_id)
|
.get_existing_key(&la.access_key_id)
|
||||||
.await?
|
.await?;
|
||||||
.ok_or(Error::NoSuchAccessKey)?;
|
let state = key.state.as_option().unwrap();
|
||||||
let state = key.state.as_option().ok_or(Error::NoSuchAccessKey)?;
|
|
||||||
if matches!(state.local_aliases.get(&la.alias), Some(_)) {
|
if matches!(state.local_aliases.get(&la.alias), Some(_)) {
|
||||||
return Err(Error::bad_request("Local alias already exists"));
|
return Err(Error::bad_request("Local alias already exists"));
|
||||||
}
|
}
|
||||||
|
|
|
@ -18,8 +18,8 @@ pub enum Error {
|
||||||
|
|
||||||
// Category: cannot process
|
// Category: cannot process
|
||||||
/// The API access key does not exist
|
/// The API access key does not exist
|
||||||
#[error(display = "Access key not found")]
|
#[error(display = "Access key not found: {}", _0)]
|
||||||
NoSuchAccessKey,
|
NoSuchAccessKey(String),
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T> From<T> for Error
|
impl<T> From<T> for Error
|
||||||
|
@ -38,9 +38,11 @@ impl From<HelperError> for Error {
|
||||||
match err {
|
match err {
|
||||||
HelperError::Internal(i) => Self::CommonError(CommonError::InternalError(i)),
|
HelperError::Internal(i) => Self::CommonError(CommonError::InternalError(i)),
|
||||||
HelperError::BadRequest(b) => Self::CommonError(CommonError::BadRequest(b)),
|
HelperError::BadRequest(b) => Self::CommonError(CommonError::BadRequest(b)),
|
||||||
HelperError::InvalidBucketName(_) => Self::CommonError(CommonError::InvalidBucketName),
|
HelperError::InvalidBucketName(n) => {
|
||||||
HelperError::NoSuchBucket(_) => Self::CommonError(CommonError::NoSuchBucket),
|
Self::CommonError(CommonError::InvalidBucketName(n))
|
||||||
HelperError::NoSuchAccessKey(_) => Self::NoSuchAccessKey,
|
}
|
||||||
|
HelperError::NoSuchBucket(n) => Self::CommonError(CommonError::NoSuchBucket(n)),
|
||||||
|
HelperError::NoSuchAccessKey(n) => Self::NoSuchAccessKey(n),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -49,7 +51,7 @@ impl Error {
|
||||||
fn code(&self) -> &'static str {
|
fn code(&self) -> &'static str {
|
||||||
match self {
|
match self {
|
||||||
Error::CommonError(c) => c.aws_code(),
|
Error::CommonError(c) => c.aws_code(),
|
||||||
Error::NoSuchAccessKey => "NoSuchAccessKey",
|
Error::NoSuchAccessKey(_) => "NoSuchAccessKey",
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -59,7 +61,7 @@ impl ApiError for Error {
|
||||||
fn http_status_code(&self) -> StatusCode {
|
fn http_status_code(&self) -> StatusCode {
|
||||||
match self {
|
match self {
|
||||||
Error::CommonError(c) => c.http_status_code(),
|
Error::CommonError(c) => c.http_status_code(),
|
||||||
Error::NoSuchAccessKey => StatusCode::NOT_FOUND,
|
Error::NoSuchAccessKey(_) => StatusCode::NOT_FOUND,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -50,17 +50,12 @@ pub async fn handle_get_key_info(
|
||||||
search: Option<String>,
|
search: Option<String>,
|
||||||
) -> Result<Response<Body>, Error> {
|
) -> Result<Response<Body>, Error> {
|
||||||
let key = if let Some(id) = id {
|
let key = if let Some(id) = id {
|
||||||
garage
|
garage.key_helper().get_existing_key(&id).await?
|
||||||
.key_table
|
|
||||||
.get(&EmptyKey, &id)
|
|
||||||
.await?
|
|
||||||
.ok_or(Error::NoSuchAccessKey)?
|
|
||||||
} else if let Some(search) = search {
|
} else if let Some(search) = search {
|
||||||
garage
|
garage
|
||||||
.key_helper()
|
.key_helper()
|
||||||
.get_existing_matching_key(&search)
|
.get_existing_matching_key(&search)
|
||||||
.await
|
.await?
|
||||||
.map_err(|_| Error::NoSuchAccessKey)?
|
|
||||||
} else {
|
} else {
|
||||||
unreachable!();
|
unreachable!();
|
||||||
};
|
};
|
||||||
|
@ -92,13 +87,9 @@ pub async fn handle_update_key(
|
||||||
) -> Result<Response<Body>, Error> {
|
) -> Result<Response<Body>, Error> {
|
||||||
let req = parse_json_body::<UpdateKeyRequest>(req).await?;
|
let req = parse_json_body::<UpdateKeyRequest>(req).await?;
|
||||||
|
|
||||||
let mut key = garage
|
let mut key = garage.key_helper().get_existing_key(&id).await?;
|
||||||
.key_table
|
|
||||||
.get(&EmptyKey, &id)
|
|
||||||
.await?
|
|
||||||
.ok_or(Error::NoSuchAccessKey)?;
|
|
||||||
|
|
||||||
let key_state = key.state.as_option_mut().ok_or(Error::NoSuchAccessKey)?;
|
let key_state = key.state.as_option_mut().unwrap();
|
||||||
|
|
||||||
if let Some(new_name) = req.name {
|
if let Some(new_name) = req.name {
|
||||||
key_state.name.update(new_name);
|
key_state.name.update(new_name);
|
||||||
|
@ -127,13 +118,9 @@ struct UpdateKeyRequest {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn handle_delete_key(garage: &Arc<Garage>, id: String) -> Result<Response<Body>, Error> {
|
pub async fn handle_delete_key(garage: &Arc<Garage>, id: String) -> Result<Response<Body>, Error> {
|
||||||
let mut key = garage
|
let mut key = garage.key_helper().get_existing_key(&id).await?;
|
||||||
.key_table
|
|
||||||
.get(&EmptyKey, &id)
|
|
||||||
.await?
|
|
||||||
.ok_or(Error::NoSuchAccessKey)?;
|
|
||||||
|
|
||||||
key.state.as_option().ok_or(Error::NoSuchAccessKey)?;
|
key.state.as_option().unwrap();
|
||||||
|
|
||||||
garage.key_helper().delete_key(&mut key).await?;
|
garage.key_helper().delete_key(&mut key).await?;
|
||||||
|
|
||||||
|
|
|
@ -32,8 +32,8 @@ pub enum CommonError {
|
||||||
// These have to be error codes referenced in the S3 spec here:
|
// These have to be error codes referenced in the S3 spec here:
|
||||||
// https://docs.aws.amazon.com/AmazonS3/latest/API/ErrorResponses.html#ErrorCodeList
|
// https://docs.aws.amazon.com/AmazonS3/latest/API/ErrorResponses.html#ErrorCodeList
|
||||||
/// The bucket requested don't exists
|
/// The bucket requested don't exists
|
||||||
#[error(display = "Bucket not found")]
|
#[error(display = "Bucket not found: {}", _0)]
|
||||||
NoSuchBucket,
|
NoSuchBucket(String),
|
||||||
|
|
||||||
/// Tried to create a bucket that already exist
|
/// Tried to create a bucket that already exist
|
||||||
#[error(display = "Bucket already exists")]
|
#[error(display = "Bucket already exists")]
|
||||||
|
@ -45,8 +45,8 @@ pub enum CommonError {
|
||||||
|
|
||||||
// Category: bad request
|
// Category: bad request
|
||||||
/// Bucket name is not valid according to AWS S3 specs
|
/// Bucket name is not valid according to AWS S3 specs
|
||||||
#[error(display = "Invalid bucket name")]
|
#[error(display = "Invalid bucket name: {}", _0)]
|
||||||
InvalidBucketName,
|
InvalidBucketName(String),
|
||||||
}
|
}
|
||||||
|
|
||||||
impl CommonError {
|
impl CommonError {
|
||||||
|
@ -62,9 +62,9 @@ impl CommonError {
|
||||||
}
|
}
|
||||||
CommonError::BadRequest(_) => StatusCode::BAD_REQUEST,
|
CommonError::BadRequest(_) => StatusCode::BAD_REQUEST,
|
||||||
CommonError::Forbidden(_) => StatusCode::FORBIDDEN,
|
CommonError::Forbidden(_) => StatusCode::FORBIDDEN,
|
||||||
CommonError::NoSuchBucket => StatusCode::NOT_FOUND,
|
CommonError::NoSuchBucket(_) => StatusCode::NOT_FOUND,
|
||||||
CommonError::BucketNotEmpty | CommonError::BucketAlreadyExists => StatusCode::CONFLICT,
|
CommonError::BucketNotEmpty | CommonError::BucketAlreadyExists => StatusCode::CONFLICT,
|
||||||
CommonError::InvalidBucketName => StatusCode::BAD_REQUEST,
|
CommonError::InvalidBucketName(_) => StatusCode::BAD_REQUEST,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -80,10 +80,10 @@ impl CommonError {
|
||||||
"InternalError"
|
"InternalError"
|
||||||
}
|
}
|
||||||
CommonError::BadRequest(_) => "InvalidRequest",
|
CommonError::BadRequest(_) => "InvalidRequest",
|
||||||
CommonError::NoSuchBucket => "NoSuchBucket",
|
CommonError::NoSuchBucket(_) => "NoSuchBucket",
|
||||||
CommonError::BucketAlreadyExists => "BucketAlreadyExists",
|
CommonError::BucketAlreadyExists => "BucketAlreadyExists",
|
||||||
CommonError::BucketNotEmpty => "BucketNotEmpty",
|
CommonError::BucketNotEmpty => "BucketNotEmpty",
|
||||||
CommonError::InvalidBucketName => "InvalidBucketName",
|
CommonError::InvalidBucketName(_) => "InvalidBucketName",
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -59,8 +59,10 @@ impl From<HelperError> for Error {
|
||||||
match err {
|
match err {
|
||||||
HelperError::Internal(i) => Self::CommonError(CommonError::InternalError(i)),
|
HelperError::Internal(i) => Self::CommonError(CommonError::InternalError(i)),
|
||||||
HelperError::BadRequest(b) => Self::CommonError(CommonError::BadRequest(b)),
|
HelperError::BadRequest(b) => Self::CommonError(CommonError::BadRequest(b)),
|
||||||
HelperError::InvalidBucketName(_) => Self::CommonError(CommonError::InvalidBucketName),
|
HelperError::InvalidBucketName(n) => {
|
||||||
HelperError::NoSuchBucket(_) => Self::CommonError(CommonError::NoSuchBucket),
|
Self::CommonError(CommonError::InvalidBucketName(n))
|
||||||
|
}
|
||||||
|
HelperError::NoSuchBucket(n) => Self::CommonError(CommonError::NoSuchBucket(n)),
|
||||||
e => Self::CommonError(CommonError::BadRequest(format!("{}", e))),
|
e => Self::CommonError(CommonError::BadRequest(format!("{}", e))),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -91,8 +91,10 @@ impl From<HelperError> for Error {
|
||||||
match err {
|
match err {
|
||||||
HelperError::Internal(i) => Self::CommonError(CommonError::InternalError(i)),
|
HelperError::Internal(i) => Self::CommonError(CommonError::InternalError(i)),
|
||||||
HelperError::BadRequest(b) => Self::CommonError(CommonError::BadRequest(b)),
|
HelperError::BadRequest(b) => Self::CommonError(CommonError::BadRequest(b)),
|
||||||
HelperError::InvalidBucketName(_) => Self::CommonError(CommonError::InvalidBucketName),
|
HelperError::InvalidBucketName(n) => {
|
||||||
HelperError::NoSuchBucket(_) => Self::CommonError(CommonError::NoSuchBucket),
|
Self::CommonError(CommonError::InvalidBucketName(n))
|
||||||
|
}
|
||||||
|
HelperError::NoSuchBucket(n) => Self::CommonError(CommonError::NoSuchBucket(n)),
|
||||||
e => Self::bad_request(format!("{}", e)),
|
e => Self::bad_request(format!("{}", e)),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue