Can get VM caps

This commit is contained in:
2024-05-03 19:19:37 +02:00
parent b6e15d2cbb
commit 50600e4e56
6 changed files with 186 additions and 8 deletions

View File

@ -1,8 +1,10 @@
use crate::app_config::AppConfig;
use crate::utils::time;
use lazy_regex::regex;
use std::fmt::Display;
use std::str::FromStr;
use thiserror::Error;
use uuid::Uuid;
use uuid::{Error, Uuid};
#[derive(Error, Debug)]
pub enum VirtWebClientError {
@ -10,6 +12,53 @@ pub enum VirtWebClientError {
InvalidStatusCode(u16),
}
#[derive(Eq, PartialEq, Debug, Copy, Clone, serde::Serialize, serde::Deserialize)]
pub struct VMUuid(Uuid);
impl VMUuid {
pub fn route_info(&self) -> String {
format!("/api/vm/{}", self.0)
}
pub fn route_state(&self) -> String {
format!("/api/vm/{}/state", self.0)
}
pub fn route_start(&self) -> String {
format!("/api/vm/{}/start", self.0)
}
pub fn route_shutdown(&self) -> String {
format!("/api/vm/{}/shutdown", self.0)
}
pub fn route_kill(&self) -> String {
format!("/api/vm/{}/kill", self.0)
}
pub fn route_reset(&self) -> String {
format!("/api/vm/{}/reset", self.0)
}
pub fn route_suspend(&self) -> String {
format!("/api/vm/{}/suspend", self.0)
}
pub fn route_resume(&self) -> String {
format!("/api/vm/{}/resume", self.0)
}
pub fn route_screenshot(&self) -> String {
format!("/api/vm/{}/screenshot", self.0)
}
}
impl FromStr for VMUuid {
type Err = Error;
fn from_str(s: &str) -> Result<Self, Self::Err> {
Ok(VMUuid(Uuid::from_str(s)?))
}
}
#[derive(serde::Serialize, Debug)]
pub struct TokenClaims {
pub sub: String,
@ -20,6 +69,13 @@ pub struct TokenClaims {
pub nonce: String,
}
#[derive(serde::Deserialize, Debug)]
pub struct VMInfo {
pub uuid: VMUuid,
pub name: String,
pub description: Option<String>,
}
#[derive(serde::Deserialize, Debug)]
pub struct TokenRight {
verb: String,
@ -29,10 +85,49 @@ pub struct TokenRight {
pub type TokenRights = Vec<TokenRight>;
#[derive(serde::Deserialize)]
struct TokenInfo {
pub struct TokenInfo {
rights: TokenRights,
}
impl TokenInfo {
/// Check whether a route is allowed or not
pub fn is_route_allowed(&self, verb: &str, route: &str) -> bool {
let search_route_split = route.split('/').collect::<Vec<_>>();
for r in &self.rights {
if r.verb != verb {
continue;
}
let curr_route_split = r.path.split('/').collect::<Vec<_>>();
if search_route_split.len() != curr_route_split.len() {
continue;
}
if curr_route_split
.iter()
.zip(search_route_split.iter())
.all(|(curr, search)| curr == &"*" || curr == search)
{
return true;
}
}
false
}
/// List the virtual machines with access
pub fn list_vm(&self) -> Vec<VMUuid> {
self.rights
.iter()
.filter(|r| r.verb == "GET")
.filter(|r| regex!("^/api/vm/[^/]+$").is_match(&r.path))
.map(|r| VMUuid::from_str(r.path.rsplit_once('/').unwrap().1).unwrap())
.collect::<Vec<_>>()
}
}
/// Perform a request on the API
async fn request<D: Display, E: serde::de::DeserializeOwned>(uri: D) -> anyhow::Result<E> {
let url = format!("{}{}", AppConfig::get().virtweb_base_url, uri);
@ -62,10 +157,17 @@ async fn request<D: Display, E: serde::de::DeserializeOwned>(uri: D) -> anyhow::
Ok(res.json().await?)
}
/// Get current token rights
pub async fn get_token_rights() -> anyhow::Result<TokenRights> {
/// Get current token information
pub async fn get_token_info() -> anyhow::Result<TokenInfo> {
let res: TokenInfo =
request(format!("/api/token/{}", AppConfig::get().virtweb_token_id)).await?;
Ok(res.rights)
Ok(res)
}
/// Get a vm information
pub async fn get_vm_info(id: VMUuid) -> anyhow::Result<VMInfo> {
let res: VMInfo = request(format!("/api/vm/{}", id.0)).await?;
Ok(res)
}