Add routes to manipulate VM
This commit is contained in:
		@@ -3,7 +3,7 @@
 | 
				
			|||||||
use crate::controllers::HttpResult;
 | 
					use crate::controllers::HttpResult;
 | 
				
			||||||
use crate::virtweb_client;
 | 
					use crate::virtweb_client;
 | 
				
			||||||
use crate::virtweb_client::VMUuid;
 | 
					use crate::virtweb_client::VMUuid;
 | 
				
			||||||
use actix_web::HttpResponse;
 | 
					use actix_web::{web, HttpResponse};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#[derive(Debug, serde::Serialize)]
 | 
					#[derive(Debug, serde::Serialize)]
 | 
				
			||||||
pub struct VMInfoAndCaps {
 | 
					pub struct VMInfoAndCaps {
 | 
				
			||||||
@@ -27,7 +27,7 @@ pub async fn list() -> HttpResult {
 | 
				
			|||||||
    let mut res = vec![];
 | 
					    let mut res = vec![];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    for v in rights.list_vm() {
 | 
					    for v in rights.list_vm() {
 | 
				
			||||||
        let vm_info = virtweb_client::get_vm_info(v).await?;
 | 
					        let vm_info = virtweb_client::vm_info(v).await?;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        res.push(VMInfoAndCaps {
 | 
					        res.push(VMInfoAndCaps {
 | 
				
			||||||
            uiid: vm_info.uuid,
 | 
					            uiid: vm_info.uuid,
 | 
				
			||||||
@@ -46,3 +46,57 @@ pub async fn list() -> HttpResult {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
    Ok(HttpResponse::Ok().json(res))
 | 
					    Ok(HttpResponse::Ok().json(res))
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#[derive(serde::Deserialize)]
 | 
				
			||||||
 | 
					pub struct ReqPath {
 | 
				
			||||||
 | 
					    uid: VMUuid,
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/// Get the state of a VM
 | 
				
			||||||
 | 
					pub async fn state(path: web::Path<ReqPath>) -> HttpResult {
 | 
				
			||||||
 | 
					    Ok(HttpResponse::Ok().json(virtweb_client::vm_state(path.uid).await?))
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/// Start a VM
 | 
				
			||||||
 | 
					pub async fn start(path: web::Path<ReqPath>) -> HttpResult {
 | 
				
			||||||
 | 
					    virtweb_client::vm_start(path.uid).await?;
 | 
				
			||||||
 | 
					    Ok(HttpResponse::Ok().finish())
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/// Shutdown a VM
 | 
				
			||||||
 | 
					pub async fn shutdown(path: web::Path<ReqPath>) -> HttpResult {
 | 
				
			||||||
 | 
					    virtweb_client::vm_shutdown(path.uid).await?;
 | 
				
			||||||
 | 
					    Ok(HttpResponse::Ok().finish())
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/// Kill a VM
 | 
				
			||||||
 | 
					pub async fn kill(path: web::Path<ReqPath>) -> HttpResult {
 | 
				
			||||||
 | 
					    virtweb_client::vm_kill(path.uid).await?;
 | 
				
			||||||
 | 
					    Ok(HttpResponse::Ok().finish())
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/// Reset a VM
 | 
				
			||||||
 | 
					pub async fn reset(path: web::Path<ReqPath>) -> HttpResult {
 | 
				
			||||||
 | 
					    virtweb_client::vm_reset(path.uid).await?;
 | 
				
			||||||
 | 
					    Ok(HttpResponse::Ok().finish())
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/// Suspend a VM
 | 
				
			||||||
 | 
					pub async fn suspend(path: web::Path<ReqPath>) -> HttpResult {
 | 
				
			||||||
 | 
					    virtweb_client::vm_suspend(path.uid).await?;
 | 
				
			||||||
 | 
					    Ok(HttpResponse::Ok().finish())
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/// Resume a VM
 | 
				
			||||||
 | 
					pub async fn resume(path: web::Path<ReqPath>) -> HttpResult {
 | 
				
			||||||
 | 
					    virtweb_client::vm_resume(path.uid).await?;
 | 
				
			||||||
 | 
					    Ok(HttpResponse::Ok().finish())
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/// Take the screenshot of a VM
 | 
				
			||||||
 | 
					pub async fn screenshot(path: web::Path<ReqPath>) -> HttpResult {
 | 
				
			||||||
 | 
					    let screenshot = virtweb_client::vm_screenshot(path.uid).await?;
 | 
				
			||||||
 | 
					    Ok(HttpResponse::Ok()
 | 
				
			||||||
 | 
					        .insert_header(("content-type", "image/png"))
 | 
				
			||||||
 | 
					        .body(screenshot))
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -80,6 +80,23 @@ async fn main() -> std::io::Result<()> {
 | 
				
			|||||||
                web::get().to(auth_controller::sign_out),
 | 
					                web::get().to(auth_controller::sign_out),
 | 
				
			||||||
            )
 | 
					            )
 | 
				
			||||||
            .route("/api/vm/list", web::get().to(vm_controller::list))
 | 
					            .route("/api/vm/list", web::get().to(vm_controller::list))
 | 
				
			||||||
 | 
					            .route("/api/vm/{uid}/state", web::get().to(vm_controller::state))
 | 
				
			||||||
 | 
					            .route("/api/vm/{uid}/start", web::get().to(vm_controller::start))
 | 
				
			||||||
 | 
					            .route(
 | 
				
			||||||
 | 
					                "/api/vm/{uid}/shutdown",
 | 
				
			||||||
 | 
					                web::get().to(vm_controller::shutdown),
 | 
				
			||||||
 | 
					            )
 | 
				
			||||||
 | 
					            .route("/api/vm/{uid}/kill", web::get().to(vm_controller::kill))
 | 
				
			||||||
 | 
					            .route("/api/vm/{uid}/reset", web::get().to(vm_controller::reset))
 | 
				
			||||||
 | 
					            .route(
 | 
				
			||||||
 | 
					                "/api/vm/{uid}/suspend",
 | 
				
			||||||
 | 
					                web::get().to(vm_controller::suspend),
 | 
				
			||||||
 | 
					            )
 | 
				
			||||||
 | 
					            .route("/api/vm/{uid}/resume", web::get().to(vm_controller::resume))
 | 
				
			||||||
 | 
					            .route(
 | 
				
			||||||
 | 
					                "/api/vm/{uid}/screenshot",
 | 
				
			||||||
 | 
					                web::get().to(vm_controller::screenshot),
 | 
				
			||||||
 | 
					            )
 | 
				
			||||||
    })
 | 
					    })
 | 
				
			||||||
    .bind(&AppConfig::get().listen_address)?
 | 
					    .bind(&AppConfig::get().listen_address)?
 | 
				
			||||||
    .run()
 | 
					    .run()
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -76,6 +76,11 @@ pub struct VMInfo {
 | 
				
			|||||||
    pub description: Option<String>,
 | 
					    pub description: Option<String>,
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#[derive(serde::Deserialize, serde::Serialize, Debug)]
 | 
				
			||||||
 | 
					pub struct VMState {
 | 
				
			||||||
 | 
					    pub state: String,
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#[derive(serde::Deserialize, Debug)]
 | 
					#[derive(serde::Deserialize, Debug)]
 | 
				
			||||||
pub struct TokenRight {
 | 
					pub struct TokenRight {
 | 
				
			||||||
    verb: String,
 | 
					    verb: String,
 | 
				
			||||||
@@ -129,7 +134,7 @@ impl TokenInfo {
 | 
				
			|||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/// Perform a request on the API
 | 
					/// Perform a request on the API
 | 
				
			||||||
async fn request<D: Display, E: serde::de::DeserializeOwned>(uri: D) -> anyhow::Result<E> {
 | 
					async fn request<D: Display>(uri: D) -> anyhow::Result<reqwest::Response> {
 | 
				
			||||||
    let url = format!("{}{}", AppConfig::get().virtweb_base_url, uri);
 | 
					    let url = format!("{}{}", AppConfig::get().virtweb_base_url, uri);
 | 
				
			||||||
    log::debug!("Will query {uri}...");
 | 
					    log::debug!("Will query {uri}...");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -154,20 +159,73 @@ async fn request<D: Display, E: serde::de::DeserializeOwned>(uri: D) -> anyhow::
 | 
				
			|||||||
        return Err(VirtWebClientError::InvalidStatusCode(res.status().as_u16()).into());
 | 
					        return Err(VirtWebClientError::InvalidStatusCode(res.status().as_u16()).into());
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    Ok(res.json().await?)
 | 
					    Ok(res)
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/// Perform a request on the API
 | 
				
			||||||
 | 
					async fn json_request<D: Display, E: serde::de::DeserializeOwned>(uri: D) -> anyhow::Result<E> {
 | 
				
			||||||
 | 
					    Ok(request(uri).await?.json().await?)
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/// Get current token information
 | 
					/// Get current token information
 | 
				
			||||||
pub async fn get_token_info() -> anyhow::Result<TokenInfo> {
 | 
					pub async fn get_token_info() -> anyhow::Result<TokenInfo> {
 | 
				
			||||||
    let res: TokenInfo =
 | 
					    let res: TokenInfo =
 | 
				
			||||||
        request(format!("/api/token/{}", AppConfig::get().virtweb_token_id)).await?;
 | 
					        json_request(format!("/api/token/{}", AppConfig::get().virtweb_token_id)).await?;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    Ok(res)
 | 
					    Ok(res)
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/// Get a vm information
 | 
					/// Get a vm information
 | 
				
			||||||
pub async fn get_vm_info(id: VMUuid) -> anyhow::Result<VMInfo> {
 | 
					pub async fn vm_info(id: VMUuid) -> anyhow::Result<VMInfo> {
 | 
				
			||||||
    let res: VMInfo = request(format!("/api/vm/{}", id.0)).await?;
 | 
					    json_request(id.route_info()).await
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
    Ok(res)
 | 
					
 | 
				
			||||||
 | 
					/// Get a vm information
 | 
				
			||||||
 | 
					pub async fn vm_state(id: VMUuid) -> anyhow::Result<VMState> {
 | 
				
			||||||
 | 
					    json_request(id.route_state()).await
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/// Start a vm
 | 
				
			||||||
 | 
					pub async fn vm_start(id: VMUuid) -> anyhow::Result<()> {
 | 
				
			||||||
 | 
					    request(id.route_start()).await?;
 | 
				
			||||||
 | 
					    Ok(())
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/// Shutdown a vm
 | 
				
			||||||
 | 
					pub async fn vm_shutdown(id: VMUuid) -> anyhow::Result<()> {
 | 
				
			||||||
 | 
					    request(id.route_shutdown()).await?;
 | 
				
			||||||
 | 
					    Ok(())
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/// Kill a vm
 | 
				
			||||||
 | 
					pub async fn vm_kill(id: VMUuid) -> anyhow::Result<()> {
 | 
				
			||||||
 | 
					    request(id.route_kill()).await?;
 | 
				
			||||||
 | 
					    Ok(())
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/// Reset a vm
 | 
				
			||||||
 | 
					pub async fn vm_reset(id: VMUuid) -> anyhow::Result<()> {
 | 
				
			||||||
 | 
					    request(id.route_reset()).await?;
 | 
				
			||||||
 | 
					    Ok(())
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/// Suspend a vm
 | 
				
			||||||
 | 
					pub async fn vm_suspend(id: VMUuid) -> anyhow::Result<()> {
 | 
				
			||||||
 | 
					    request(id.route_suspend()).await?;
 | 
				
			||||||
 | 
					    Ok(())
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/// Resume a vm
 | 
				
			||||||
 | 
					pub async fn vm_resume(id: VMUuid) -> anyhow::Result<()> {
 | 
				
			||||||
 | 
					    request(id.route_resume()).await?;
 | 
				
			||||||
 | 
					    Ok(())
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/// Resume a vm
 | 
				
			||||||
 | 
					pub async fn vm_screenshot(id: VMUuid) -> anyhow::Result<Vec<u8>> {
 | 
				
			||||||
 | 
					    Ok(request(id.route_screenshot())
 | 
				
			||||||
 | 
					        .await?
 | 
				
			||||||
 | 
					        .bytes()
 | 
				
			||||||
 | 
					        .await?
 | 
				
			||||||
 | 
					        .to_vec())
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user