diff options
author | Alex Auvolat <alex@adnab.me> | 2022-05-17 19:02:13 +0200 |
---|---|---|
committer | Alex Auvolat <alex@adnab.me> | 2022-05-17 19:02:13 +0200 |
commit | dcfa408887b588e9f9eee608c1358a5a81330e9e (patch) | |
tree | 168f66fe25786df731aa2bbf32d1d8f3b683bcdb | |
parent | 70383b4363c9d9d1ddebcb29c60f833022e97d24 (diff) | |
download | garage-dcfa408887b588e9f9eee608c1358a5a81330e9e.tar.gz garage-dcfa408887b588e9f9eee608c1358a5a81330e9e.zip |
Implement ImportKey
-rw-r--r-- | doc/drafts/admin-api.md | 14 | ||||
-rw-r--r-- | src/api/admin/api_server.rs | 1 | ||||
-rw-r--r-- | src/api/admin/error.rs | 9 | ||||
-rw-r--r-- | src/api/admin/key.rs | 25 | ||||
-rw-r--r-- | src/api/admin/router.rs | 2 | ||||
-rw-r--r-- | src/rpc/system.rs | 7 |
6 files changed, 53 insertions, 5 deletions
diff --git a/doc/drafts/admin-api.md b/doc/drafts/admin-api.md index 2e1ffa82..d6b8ed5d 100644 --- a/doc/drafts/admin-api.md +++ b/doc/drafts/admin-api.md @@ -273,6 +273,20 @@ Request body format: } ``` +### ImportKey `POST /v0/key/import` + +Imports an existing API key. + +Request body format: + +```json +{ + "accessKeyId": "GK31c2f218a2e44f485b94239e", + "secretAccessKey": "b892c0665f0ada8a4755dae98baa3b133590e11dae3bcc1f9d769d67f16c3835", + "name": "NameOfMyKey" +} +``` + ### GetKeyInfo `GET /v0/key?id=<acces key id>` ### GetKeyInfo `GET /v0/key?search=<pattern>` diff --git a/src/api/admin/api_server.rs b/src/api/admin/api_server.rs index 61b0d24f..a0af9bd9 100644 --- a/src/api/admin/api_server.rs +++ b/src/api/admin/api_server.rs @@ -136,6 +136,7 @@ impl ApiHandler for AdminApiServer { handle_get_key_info(&self.garage, id, search).await } Endpoint::CreateKey => handle_create_key(&self.garage, req).await, + Endpoint::ImportKey => handle_import_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, // Buckets diff --git a/src/api/admin/error.rs b/src/api/admin/error.rs index 592440a5..b4475268 100644 --- a/src/api/admin/error.rs +++ b/src/api/admin/error.rs @@ -20,6 +20,13 @@ pub enum Error { /// The API access key does not exist #[error(display = "Access key not found: {}", _0)] NoSuchAccessKey(String), + + /// In Import key, the key already exists + #[error( + display = "Key {} already exists in data store. Even if it is deleted, we can't let you create a new key with the same ID. Sorry.", + _0 + )] + KeyAlreadyExists(String), } impl<T> From<T> for Error @@ -52,6 +59,7 @@ impl Error { match self { Error::CommonError(c) => c.aws_code(), Error::NoSuchAccessKey(_) => "NoSuchAccessKey", + Error::KeyAlreadyExists(_) => "KeyAlreadyExists", } } } @@ -62,6 +70,7 @@ impl ApiError for Error { match self { Error::CommonError(c) => c.http_status_code(), Error::NoSuchAccessKey(_) => StatusCode::NOT_FOUND, + Error::KeyAlreadyExists(_) => StatusCode::CONFLICT, } } diff --git a/src/api/admin/key.rs b/src/api/admin/key.rs index be37088b..f30b5dbb 100644 --- a/src/api/admin/key.rs +++ b/src/api/admin/key.rs @@ -80,6 +80,31 @@ struct CreateKeyRequest { name: String, } +pub async fn handle_import_key( + garage: &Arc<Garage>, + req: Request<Body>, +) -> Result<Response<Body>, Error> { + let req = parse_json_body::<ImportKeyRequest>(req).await?; + + let prev_key = garage.key_table.get(&EmptyKey, &req.access_key_id).await?; + if prev_key.is_some() { + return Err(Error::KeyAlreadyExists(req.access_key_id.to_string())); + } + + let imported_key = Key::import(&req.access_key_id, &req.secret_access_key, &req.name); + garage.key_table.insert(&imported_key).await?; + + key_info_results(garage, imported_key).await +} + +#[derive(Deserialize)] +#[serde(rename_all = "camelCase")] +struct ImportKeyRequest { + access_key_id: String, + secret_access_key: String, + name: String, +} + pub async fn handle_update_key( garage: &Arc<Garage>, id: String, diff --git a/src/api/admin/router.rs b/src/api/admin/router.rs index 41e7ed73..93639873 100644 --- a/src/api/admin/router.rs +++ b/src/api/admin/router.rs @@ -27,6 +27,7 @@ pub enum Endpoint { // Keys ListKeys, CreateKey, + ImportKey, GetKeyInfo { id: Option<String>, search: Option<String>, @@ -103,6 +104,7 @@ impl Endpoint { GET "/v0/key" if search => GetKeyInfo (query_opt::id, query_opt::search), POST "/v0/key" if id => UpdateKey (query::id), POST "/v0/key" => CreateKey, + POST "/v0/key/import" => ImportKey, DELETE "/v0/key" if id => DeleteKey (query::id), GET "/v0/key" => ListKeys, // Bucket endpoints diff --git a/src/rpc/system.rs b/src/rpc/system.rs index 78d538ec..1d7c3ea4 100644 --- a/src/rpc/system.rs +++ b/src/rpc/system.rs @@ -384,12 +384,9 @@ impl System { } } if errors.len() == 1 { - return Err(Error::Message(errors[0].1.to_string())); + Err(Error::Message(errors[0].1.to_string())) } else { - return Err(Error::Message(format!( - "Could not connect to specified peers. Errors: {:?}", - errors - ))); + Err(Error::Message(format!("{:?}", errors))) } } |