use async_trait::async_trait; use derive_new::new; use serde::Serialize; use crate::{ data::{FileContent, FilePath, Version}, interpret::{Interpret, InterpretError, InterpretName, InterpretStatus, Outcome}, inventory::Inventory, score::Score, topology::{HttpServer, Topology}, }; use harmony_types::net::Url; use harmony_types::{id::Id, net::MacAddress}; /// Configure an HTTP server that is provided by the Topology /// /// This Score will let you easily specify a file path to be served by the HTTP server /// /// For example, if you have a folder of assets at `/var/www/assets` simply do : /// /// ```rust,ignore /// StaticFilesHttpScore { /// files_to_serve: url!("file:///var/www/assets"), /// } /// ``` #[derive(Debug, new, Clone, Serialize)] pub struct StaticFilesHttpScore { // TODO this should be split in two scores, one for folder and // other for files pub folder_to_serve: Option, pub files: Vec, pub remote_path: Option, } impl Score for StaticFilesHttpScore { fn create_interpret(&self) -> Box> { Box::new(StaticFilesHttpInterpret::new(self.clone())) } fn name(&self) -> String { "HttpScore".to_string() } } #[derive(Debug, new, Clone)] pub struct StaticFilesHttpInterpret { score: StaticFilesHttpScore, } #[async_trait] impl Interpret for StaticFilesHttpInterpret { async fn execute( &self, _inventory: &Inventory, http_server: &T, ) -> Result { http_server.ensure_initialized().await?; // http_server.set_ip(topology.router.get_gateway()).await?; if let Some(folder) = self.score.folder_to_serve.as_ref() { http_server .serve_files(folder, &self.score.remote_path) .await?; } for f in self.score.files.iter() { http_server.serve_file_content(&f).await? } http_server.commit_config().await?; http_server.reload_restart().await?; Ok(Outcome::success(format!( "Http Server running and serving files from folder {:?} and content for {}", self.score.folder_to_serve, self.score .files .iter() .map(|f| f.path.to_string()) .collect::>() .join(",") ))) } fn get_name(&self) -> InterpretName { InterpretName::Http } fn get_version(&self) -> Version { todo!() } fn get_status(&self) -> InterpretStatus { todo!() } fn get_children(&self) -> Vec { todo!() } } #[derive(Debug, new, Clone, Serialize)] pub struct IPxeMacBootFileScore { pub content: String, pub mac_address: Vec, } impl Score for IPxeMacBootFileScore { fn name(&self) -> String { "IPxeMacBootFileScore".to_string() } fn create_interpret(&self) -> Box> { StaticFilesHttpScore { remote_path: None, folder_to_serve: None, files: self .mac_address .iter() .map(|mac| FileContent { path: FilePath::Relative(format!( "byMAC/01-{}.ipxe", mac.to_string().replace(":", "-") )), content: self.content.clone(), }) .collect(), } .create_interpret() } }