aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlex Auvolat <alex@adnab.me>2022-05-17 19:02:13 +0200
committerAlex Auvolat <alex@adnab.me>2022-05-17 19:02:13 +0200
commitdcfa408887b588e9f9eee608c1358a5a81330e9e (patch)
tree168f66fe25786df731aa2bbf32d1d8f3b683bcdb
parent70383b4363c9d9d1ddebcb29c60f833022e97d24 (diff)
downloadgarage-dcfa408887b588e9f9eee608c1358a5a81330e9e.tar.gz
garage-dcfa408887b588e9f9eee608c1358a5a81330e9e.zip
Implement ImportKey
-rw-r--r--doc/drafts/admin-api.md14
-rw-r--r--src/api/admin/api_server.rs1
-rw-r--r--src/api/admin/error.rs9
-rw-r--r--src/api/admin/key.rs25
-rw-r--r--src/api/admin/router.rs2
-rw-r--r--src/rpc/system.rs7
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)))
}
}