api-server/src/api/route/volume.rs

138 lines
4.0 KiB
Rust

use rocket::fairing::AdHoc;
use rocket::response::status;
use rocket::serde::json::Json;
use sea_orm_rocket::Connection;
use sea_orm::*;
use crate::api;
use crate::api::cluster;
use crate::api::cluster::volume::VolumeParams;
use crate::api::entity::nodes;
use crate::api::entity::nodes::P5xError;
use crate::api::services::Services;
use crate::api::util::raise_500;
#[get("/<name>")]
async fn get_vol(
conn: Connection<'_, api::Db>,
name: &str,
) -> Result<Json<VolumeParams>, status::Custom<String>> {
let db = conn.into_inner();
let svc = Services::build(db).await.map_err(raise_500)?;
let vol = VolumeParams::resolve(&svc, name)
.await.map_err(raise_500)?
.ok_or(P5xError::BadPrecondition("Could not find a volume with that name"))
.map_err(raise_500)?;
Ok(Json(vol))
}
#[post("/", data = "<input>")]
async fn create_vol(
conn: Connection<'_, api::Db>,
input: Json<VolumeParams>,
) -> Result<Json<VolumeParams>, status::Custom<String>> {
let input = input.into_inner();
let db = conn.into_inner();
let svc = Services::build(db).await.map_err(raise_500)?;
let vol: VolumeParams = cluster::volume::create(&svc, &input.name, input.size_in_bytes)
.await
.map_err(raise_500)?
.into();
cluster::volume::unmount(&svc, &vol).await.map_err(raise_500)?;
Ok(Json(vol.into()))
}
#[delete("/<name>")]
async fn delete_vol(
conn: Connection<'_, api::Db>,
name: &str,
) -> Result<Json<serde_json::Value>, status::Custom<String>> {
let db = conn.into_inner();
let svc = Services::build(db).await.map_err(raise_500)?;
let vol = VolumeParams::resolve(&svc, name)
.await.map_err(raise_500)?
.ok_or(P5xError::BadPrecondition("Could not find a volume with that name"))
.map_err(raise_500)?;
cluster::volume::unmount(&svc, &vol).await.map_err(raise_500)?;
cluster::volume::delete(&svc, &vol).await.map_err(raise_500)?;
Ok(Json(serde_json::json!({})))
}
#[post("/mount", data = "<params>")]
async fn mount_vol(
conn: Connection<'_, api::Db>,
params: Json<VolumeParams>,
) -> Result<Json<serde_json::Value>, status::Custom<String>> {
let db = conn.into_inner();
let svc = Services::build(db).await.map_err(raise_500)?;
let params = params.into_inner();
cluster::volume::mount(&svc, &params).await.map_err(raise_500)?;
Ok(Json(serde_json::json!({})))
}
#[post("/unmount/<name>")]
async fn unmount_vol(
conn: Connection<'_, api::Db>,
name: &str,
) -> Result<Json<serde_json::Value>, status::Custom<String>> {
let db = conn.into_inner();
let svc = Services::build(db).await.map_err(raise_500)?;
let vol = VolumeParams::resolve(&svc, name)
.await.map_err(raise_500)?
.ok_or(P5xError::BadPrecondition("Could not find a volume with that name"))
.map_err(raise_500)?;
cluster::volume::unmount(&svc, &vol).await.map_err(raise_500)?;
Ok(Json(serde_json::json!({})))
}
#[post("/transfer/<name>/to/<node>")]
async fn transfer_vol(
conn: Connection<'_, api::Db>,
name: &str,
node: &str,
) -> Result<Json<VolumeParams>, status::Custom<String>> {
let db = conn.into_inner();
let svc = Services::build(db).await.map_err(raise_500)?;
let vol = VolumeParams::resolve(&svc, name)
.await.map_err(raise_500)?
.ok_or(P5xError::BadPrecondition("Could not find a volume with that name"))
.map_err(raise_500)?;
let node = nodes::Entity::find()
.filter(nodes::Column::Hostname.eq(node))
.one(db)
.await.map_err(raise_500)?
.ok_or(P5xError::BadPrecondition("Could not find a node with that name"))
.map_err(raise_500)?;
let vol = cluster::volume::transfer(&svc, &vol, &node).await.map_err(raise_500)?;
Ok(Json(vol.into()))
}
pub(super) fn init() -> AdHoc {
AdHoc::on_ignite("Routes: /volume", |rocket| async {
rocket.mount("/volume", routes![create_vol, delete_vol, get_vol, mount_vol, unmount_vol, transfer_vol])
})
}