diff options
author | Alex Auvolat <alex@adnab.me> | 2022-05-11 11:40:26 +0200 |
---|---|---|
committer | Alex Auvolat <alex@adnab.me> | 2022-05-11 11:40:26 +0200 |
commit | 393b76ecba66ff11b80bf404691704568f2d1794 (patch) | |
tree | 66aa5010cb6391f52360396481b759e4187400e1 /src/api | |
parent | 5c00c9fb46305b021b5fc45d7ae7b1e13b72030c (diff) | |
download | garage-393b76ecba66ff11b80bf404691704568f2d1794.tar.gz garage-393b76ecba66ff11b80bf404691704568f2d1794.zip |
Implement CreateKey, DeleteKey and rudimentary UpdateKey
Diffstat (limited to 'src/api')
-rw-r--r-- | src/api/admin/api_server.rs | 5 | ||||
-rw-r--r-- | src/api/admin/key.rs | 95 |
2 files changed, 89 insertions, 11 deletions
diff --git a/src/api/admin/api_server.rs b/src/api/admin/api_server.rs index e44443ff..952f6a73 100644 --- a/src/api/admin/api_server.rs +++ b/src/api/admin/api_server.rs @@ -136,10 +136,15 @@ impl ApiHandler for AdminApiServer { Endpoint::GetKeyInfo { id, search } => { handle_get_key_info(&self.garage, id, search).await } + Endpoint::CreateKey => handle_create_key(&self.garage, req).await, + Endpoint::UpdateKey { id } => handle_update_key(&self.garage, id, req).await, + Endpoint::DeleteKey { id } => handle_delete_key(&self.garage, id).await, + /* _ => Err(Error::NotImplemented(format!( "Admin endpoint {} not implemented yet", endpoint.name() ))), + */ } } } diff --git a/src/api/admin/key.rs b/src/api/admin/key.rs index 224be6c1..7cfe3fce 100644 --- a/src/api/admin/key.rs +++ b/src/api/admin/key.rs @@ -1,16 +1,11 @@ use std::collections::HashMap; -use std::net::SocketAddr; use std::sync::Arc; use hyper::{Body, Request, Response, StatusCode}; use serde::{Deserialize, Serialize}; -use garage_util::crdt::*; -use garage_util::data::*; use garage_util::error::Error as GarageError; -use garage_rpc::layout::*; - use garage_table::*; use garage_model::garage::Garage; @@ -62,7 +57,7 @@ pub async fn handle_get_key_info( .ok_or(Error::NoSuchKey)? } else if let Some(search) = search { garage - .bucket_helper() + .key_helper() .get_existing_matching_key(&search) .await .map_err(|_| Error::NoSuchKey)? @@ -70,6 +65,84 @@ pub async fn handle_get_key_info( unreachable!(); }; + key_info_results(garage, key).await +} + +pub async fn handle_create_key( + garage: &Arc<Garage>, + req: Request<Body>, +) -> Result<Response<Body>, Error> { + let req = parse_json_body::<CreateKeyRequest>(req).await?; + + let key = Key::new(&req.name); + garage.key_table.insert(&key).await?; + + key_info_results(garage, key).await +} + +#[derive(Deserialize)] +struct CreateKeyRequest { + name: String, +} + +pub async fn handle_update_key( + garage: &Arc<Garage>, + id: String, + req: Request<Body>, +) -> Result<Response<Body>, Error> { + let req = parse_json_body::<UpdateKeyRequest>(req).await?; + + let mut key = garage + .key_table + .get(&EmptyKey, &id) + .await? + .ok_or(Error::NoSuchKey)?; + + let key_state = key.state.as_option_mut().ok_or(Error::NoSuchKey)?; + + if let Some(new_name) = req.name { + key_state.name.update(new_name); + } + if let Some(allow) = req.allow { + if allow.create_bucket { + key_state.allow_create_bucket.update(true); + } + } + if let Some(deny) = req.deny { + if deny.create_bucket { + key_state.allow_create_bucket.update(false); + } + } + + garage.key_table.insert(&key).await?; + + key_info_results(garage, key).await +} + +#[derive(Deserialize)] +struct UpdateKeyRequest { + name: Option<String>, + allow: Option<KeyPerm>, + deny: Option<KeyPerm>, +} + +pub async fn handle_delete_key(garage: &Arc<Garage>, id: String) -> Result<Response<Body>, Error> { + let mut key = garage + .key_table + .get(&EmptyKey, &id) + .await? + .ok_or(Error::NoSuchKey)?; + + key.state.as_option().ok_or(Error::NoSuchKey)?; + + garage.key_helper().delete_key(&mut key).await?; + + Ok(Response::builder() + .status(StatusCode::NO_CONTENT) + .body(Body::empty())?) +} + +async fn key_info_results(garage: &Arc<Garage>, key: Key) -> Result<Response<Body>, Error> { let mut relevant_buckets = HashMap::new(); let key_state = key.state.as_option().unwrap(); @@ -99,7 +172,7 @@ pub async fn handle_get_key_info( name: key_state.name.get().clone(), access_key_id: key.key_id.clone(), secret_access_key: key_state.secret_key.clone(), - permissions: KeyPermResult { + permissions: KeyPerm { create_bucket: *key_state.allow_create_bucket.get(), }, buckets: relevant_buckets @@ -153,13 +226,13 @@ struct GetKeyInfoResult { access_key_id: String, #[serde(rename = "secretAccessKey")] secret_access_key: String, - permissions: KeyPermResult, + permissions: KeyPerm, buckets: Vec<KeyInfoBucketResult>, } -#[derive(Serialize)] -struct KeyPermResult { - #[serde(rename = "createBucket")] +#[derive(Serialize, Deserialize)] +struct KeyPerm { + #[serde(rename = "createBucket", default)] create_bucket: bool, } |