diff --git a/Cargo.lock b/Cargo.lock index fb8f3a4..2cad7e9 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -815,6 +815,21 @@ dependencies = [ "url", ] +[[package]] +name = "example-lamp" +version = "0.1.0" +dependencies = [ + "cidr", + "env_logger", + "harmony", + "harmony_macros", + "harmony_tui", + "harmony_types", + "log", + "tokio", + "url", +] + [[package]] name = "example-nanodc" version = "0.1.0" diff --git a/examples/lamp/Cargo.toml b/examples/lamp/Cargo.toml new file mode 100644 index 0000000..902548e --- /dev/null +++ b/examples/lamp/Cargo.toml @@ -0,0 +1,18 @@ +[package] +name = "example-lamp" +edition = "2024" +version.workspace = true +readme.workspace = true +license.workspace = true +publish = false + +[dependencies] +harmony = { path = "../../harmony" } +harmony_tui = { path = "../../harmony_tui" } +harmony_types = { path = "../../harmony_types" } +cidr = { workspace = true } +tokio = { workspace = true } +harmony_macros = { path = "../../harmony_macros" } +log = { workspace = true } +env_logger = { workspace = true } +url = { workspace = true } diff --git a/examples/lamp/php/index.php b/examples/lamp/php/index.php new file mode 100644 index 0000000..6cf1a50 --- /dev/null +++ b/examples/lamp/php/index.php @@ -0,0 +1,3 @@ + diff --git a/examples/lamp/src/main.rs b/examples/lamp/src/main.rs new file mode 100644 index 0000000..dad2673 --- /dev/null +++ b/examples/lamp/src/main.rs @@ -0,0 +1,21 @@ +use harmony::{ + data::Version, + maestro::Maestro, + modules::lamp::{LAMPConfig, LAMPScore}, + topology::Url, +}; + +#[tokio::main] +async fn main() { + let lamp_stack = LAMPScore { + name: "harmony-lamp-demo".to_string(), + domain: Url::Url(url::Url::parse("https://lampdemo.harmony.nationtech.io").unwrap()), + php_version: Version::from("8.4.4").unwrap(), + config: LAMPConfig { + project_root: "./php".into(), + ..Default::default() + }, + }; + + Maestro::load_from_env().interpret(Box::new(lamp_stack)).await.unwrap(); +} diff --git a/harmony/src/domain/maestro/mod.rs b/harmony/src/domain/maestro/mod.rs index 46ec8da..9f92ec5 100644 --- a/harmony/src/domain/maestro/mod.rs +++ b/harmony/src/domain/maestro/mod.rs @@ -26,6 +26,27 @@ impl Maestro { } } + // Load the inventory and inventory from environment. + // This function is able to discover the context that it is running in, such as k8s clusters, aws cloud, linux host, etc. + // When the HARMONY_TOPOLOGY environment variable is not set, it will default to install k3s + // locally (lazily, if not installed yet, when the first execution occurs) and use that as a topology + // So, by default, the inventory is a single host that the binary is running on, and the + // topology is a single node k3s + // + // By default : + // - Linux => k3s + // - macos, windows => docker compose + // + // To run more complex cases like OKDHACluster, either provide the default target in the + // harmony infrastructure as code or as an environment variable + pub fn load_from_env() -> Self { + // Load env var HARMONY_TOPOLOGY + match std::env::var("HARMONY_TOPOLOGY") { + Ok(_) => todo!(), + Err(_) => todo!(), + } + } + pub fn start(&mut self) { info!("Starting Maestro"); } diff --git a/harmony/src/domain/topology/mod.rs b/harmony/src/domain/topology/mod.rs index 438a3dd..9d5663c 100644 --- a/harmony/src/domain/topology/mod.rs +++ b/harmony/src/domain/topology/mod.rs @@ -21,14 +21,14 @@ pub type IpAddress = IpAddr; #[derive(Debug, Clone)] pub enum Url { LocalFolder(String), - Remote(url::Url), + Url(url::Url), } impl std::fmt::Display for Url { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { match self { Url::LocalFolder(path) => write!(f, "{}", path), - Url::Remote(url) => write!(f, "{}", url), + Url::Url(url) => write!(f, "{}", url), } } } diff --git a/harmony/src/infra/opnsense/http.rs b/harmony/src/infra/opnsense/http.rs index 3c33bba..a06fe5b 100644 --- a/harmony/src/infra/opnsense/http.rs +++ b/harmony/src/infra/opnsense/http.rs @@ -22,7 +22,7 @@ impl HttpServer for OPNSenseFirewall { .await .map_err(|e| ExecutorError::UnexpectedError(e.to_string()))?; } - Url::Remote(_url) => todo!(), + Url::Url(_url) => todo!(), } Ok(()) } diff --git a/harmony/src/infra/opnsense/tftp.rs b/harmony/src/infra/opnsense/tftp.rs index 3f1156e..6978150 100644 --- a/harmony/src/infra/opnsense/tftp.rs +++ b/harmony/src/infra/opnsense/tftp.rs @@ -22,7 +22,7 @@ impl TftpServer for OPNSenseFirewall { .await .map_err(|e| ExecutorError::UnexpectedError(e.to_string()))?; } - Url::Remote(url) => todo!("This url is not supported yet {url}"), + Url::Url(url) => todo!("This url is not supported yet {url}"), } Ok(()) } diff --git a/harmony/src/modules/lamp.rs b/harmony/src/modules/lamp.rs index b0aa94f..e6b7612 100644 --- a/harmony/src/modules/lamp.rs +++ b/harmony/src/modules/lamp.rs @@ -1,3 +1,5 @@ +use std::path::{Path, PathBuf}; + use async_trait::async_trait; use crate::{ @@ -6,12 +8,30 @@ use crate::{ inventory::Inventory, modules::k8s::deployment::K8sDeploymentScore, score::Score, - topology::HAClusterTopology, + topology::{HAClusterTopology, Url}, }; #[derive(Debug, Clone)] pub struct LAMPScore { pub name: String, + pub domain: Url, + pub config: LAMPConfig, + pub php_version: Version, +} + +#[derive(Debug, Clone)] +pub struct LAMPConfig { + pub project_root: PathBuf, + pub ssl_enabled: bool, +} + +impl Default for LAMPConfig { + fn default() -> Self { + LAMPConfig { + project_root: Path::new("./src").to_path_buf(), + ssl_enabled: true, + } + } } impl Score for LAMPScore { @@ -41,7 +61,7 @@ impl Interpret for LAMPInterpret { topology: &HAClusterTopology, ) -> Result { let deployment_score = K8sDeploymentScore { - name: self.score.name.clone(), + name: self.score.name(), image: "local_image".to_string(), };