diff options
-rw-r--r-- | Cargo.lock | 4 | ||||
-rw-r--r-- | src/errors.rs | 10 | ||||
-rw-r--r-- | src/handlers/planets.rs | 52 | ||||
-rw-r--r-- | src/main.rs | 13 |
4 files changed, 73 insertions, 6 deletions
@@ -862,8 +862,8 @@ dependencies = [ [[package]] name = "solarlib" -version = "1.3.0" -source = "git+https://git.carathe.dev/muirrum/solarlib?branch=master#d674951ce8cb5b41afe68bbeefcd9ee585125ab9" +version = "1.4.0" +source = "git+https://git.carathe.dev/muirrum/solarlib?branch=master#137ec4c34aa962b11148cfad443a4c88035e3d87" dependencies = [ "mac_address", "rand", diff --git a/src/errors.rs b/src/errors.rs index d76db92..b22932f 100644 --- a/src/errors.rs +++ b/src/errors.rs @@ -12,6 +12,9 @@ pub enum ServiceError { #[error("Axum error: {0}")] Axum(#[from] axum::Error), + + #[error("Not Found")] + NotFound, } pub type StringResult<T = &'static str> = std::result::Result<T, ServiceError>; @@ -23,8 +26,13 @@ impl IntoResponse for ServiceError { fn into_response(self) -> Response { let body = body::boxed(body::Full::from(self.to_string())); + + let status = match self { + ServiceError::NotFound => StatusCode::NOT_FOUND, + _ => StatusCode::INTERNAL_SERVER_ERROR, + }; Response::builder() - .status(StatusCode::INTERNAL_SERVER_ERROR) + .status(status) .body(body) .unwrap() } diff --git a/src/handlers/planets.rs b/src/handlers/planets.rs index e80e7fe..a57f605 100644 --- a/src/handlers/planets.rs +++ b/src/handlers/planets.rs @@ -1,11 +1,11 @@ -use axum::{response::IntoResponse, Json}; +use axum::{response::IntoResponse, Json, extract::Path}; use tracing::{error, instrument}; use solarlib::star::Star; use solarlib::planet::Planet; -use crate::errors::*; +use crate::{errors::*, get_star}; pub async fn list() -> JsonResult<Json<Vec<Planet>>> { let con_url = std::env::var("QEMU_URL").unwrap_or("qemu:///system".to_string()); @@ -16,3 +16,51 @@ pub async fn list() -> JsonResult<Json<Vec<Planet>>> { Ok(Json(inhabitants)) } +pub async fn get(Path(uuid): Path<String>) -> JsonResult<Json<Planet>> { + + let con_url = std::env::var("QEMU_URL").unwrap_or("qemu:///system".to_string()); + let mut star = Star::new(con_url)?; + + if let Ok(p) = star.find_planet(uuid) { + return Ok(Json(p)); + } else { + return Err(ServiceError::NotFound); + } +} + +pub async fn shutdown(Path(uuid): Path<String>) -> NoneResult { + let con_url = std::env::var("QEMU_URL").unwrap_or("qemu:///system".to_string()); + let mut star = Star::new(con_url)?; + + if let Ok(p) = star.find_planet(uuid) { + p.shutdown()?; + } else { + return Err(ServiceError::NotFound); + } + + Ok(()) +} + +pub async fn start(Path(uuid): Path<String>) -> NoneResult { + let mut s = get_star()?; + + if let Ok(p) = s.find_planet(uuid) { + p.start()?; + } else { + return Err(ServiceError::NotFound); + } + + Ok(()) +} + +pub async fn pause(Path(uuid): Path<String>) -> NoneResult { + let mut s = get_star()?; + + if let Ok(p) = s.find_planet(uuid) { + p.pause()?; + } else { + return Err(ServiceError::NotFound); + } + + Ok(()) +} diff --git a/src/main.rs b/src/main.rs index 8fbd0ff..742113e 100644 --- a/src/main.rs +++ b/src/main.rs @@ -2,11 +2,12 @@ use axum::{ error_handling::HandleErrorLayer, http::StatusCode, response::IntoResponse, - routing::get, + routing::{get, post}, Json, Router }; use serde::{Deserialize, Serialize}; +use solarlib::star::Star; use std::{net::SocketAddr, time::Duration, str::FromStr}; use tower::{BoxError, ServiceBuilder}; @@ -33,6 +34,10 @@ async fn main() { let app = Router::new() .route("/health", get(health_check)) .route("/planets/list", get(handlers::planets::list)) + .route("/planets/:uuid", get(handlers::planets::get)) + .route("/planets/:uuid/shutdown", post(handlers::planets::shutdown)) + .route("/planets/:uuid/start", post(handlers::planets::start)) + .route("/planets/:uuid/pause", post(handlers::planets::pause)) .layer( ServiceBuilder::new() .layer(HandleErrorLayer::new(|error: BoxError| async move { if error.is::<tower::timeout::error::Elapsed>() { @@ -61,3 +66,9 @@ async fn main() { async fn health_check() -> &'static str { "OK" } + +fn get_star() -> Result<Star, errors::ServiceError> { + let con_url = std::env::var("QEMU_URL").unwrap_or("qemu:///system".to_string()); + + Ok(Star::new(con_url)?) +} |