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("/")] async fn get_vol( conn: Connection<'_, api::Db>, name: &str, ) -> Result, status::Custom> { 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 = "")] async fn create_vol( conn: Connection<'_, api::Db>, input: Json, ) -> Result, status::Custom> { 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("/")] async fn delete_vol( conn: Connection<'_, api::Db>, name: &str, ) -> Result, status::Custom> { 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 = "")] async fn mount_vol( conn: Connection<'_, api::Db>, params: Json, ) -> Result, status::Custom> { let db = conn.into_inner(); let svc = Services::build(db).await.map_err(raise_500)?; let params = params.into_inner(); cluster::volume::mount(&svc, ¶ms).await.map_err(raise_500)?; Ok(Json(serde_json::json!({}))) } #[post("/unmount/")] async fn unmount_vol( conn: Connection<'_, api::Db>, name: &str, ) -> Result, status::Custom> { 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//to/")] async fn transfer_vol( conn: Connection<'_, api::Db>, name: &str, node: &str, ) -> Result, status::Custom> { 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]) }) }