Compare commits
	
		
			2 Commits
		
	
	
		
			23971ecd7c
			...
			065e3904b8
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
| 065e3904b8 | |||
| 22752960f9 | 
| @ -8,6 +8,7 @@ use harmony::{ | ||||
| 
 | ||||
| #[tokio::main] | ||||
| async fn main() { | ||||
|     // let _ = env_logger::Builder::from_default_env().filter_level(log::LevelFilter::Info).try_init();
 | ||||
|     let lamp_stack = LAMPScore { | ||||
|         name: "harmony-lamp-demo".to_string(), | ||||
|         domain: Url::Url(url::Url::parse("https://lampdemo.harmony.nationtech.io").unwrap()), | ||||
|  | ||||
| @ -116,17 +116,22 @@ impl K8sAnywhereTopology { | ||||
|         info!("Starting K8sAnywhere installation"); | ||||
|         self.try_install_k3d().await?; | ||||
|         let k3d_score = self.get_k3d_installation_score(); | ||||
|         match k3d_rs::K3d::new(k3d_score.installation_path, Some(k3d_score.cluster_name)) | ||||
|             .get_client() | ||||
|             .await | ||||
|         { | ||||
|             Ok(client) => Ok(Some(K8sState { | ||||
|         // I feel like having to rely on the k3d_rs crate here is a smell
 | ||||
|         // I think we should have a way to interact more deeply with scores/interpret. Maybe the
 | ||||
|         // K3DInstallationScore should expose a method to get_client ? Not too sure what would be a
 | ||||
|         // good implementation due to the stateful nature of the k3d thing. Which is why I went
 | ||||
|         // with this solution for now
 | ||||
|         let k3d = k3d_rs::K3d::new(k3d_score.installation_path, Some(k3d_score.cluster_name)); | ||||
|         let state = match k3d.get_client().await { | ||||
|             Ok(client) => K8sState { | ||||
|                 _client: K8sClient::new(client), | ||||
|                 _source: K8sSource::LocalK3d, | ||||
|                 message: "Successfully installed K3D cluster and acquired client".to_string(), | ||||
|             })), | ||||
|             }, | ||||
|             Err(_) => todo!(), | ||||
|         } | ||||
|         }; | ||||
| 
 | ||||
|         Ok(Some(state)) | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| @ -154,7 +159,7 @@ struct K8sAnywhereConfig { | ||||
| #[async_trait] | ||||
| impl Topology for K8sAnywhereTopology { | ||||
|     fn name(&self) -> &str { | ||||
|         todo!() | ||||
|         "K8sAnywhereTopology" | ||||
|     } | ||||
| 
 | ||||
|     async fn ensure_ready(&self) -> Result<Outcome, InterpretError> { | ||||
|  | ||||
| @ -117,7 +117,7 @@ impl K3d { | ||||
|     /// 2. It has proper executable permissions (on Unix systems)
 | ||||
|     /// 3. It responds correctly to a simple command (`k3d --version`)
 | ||||
|     pub fn is_installed(&self) -> bool { | ||||
|         let binary_path = self.base_dir.join(K3D_BIN_FILE_NAME); | ||||
|         let binary_path = self.get_k3d_binary_path(); | ||||
| 
 | ||||
|         if !binary_path.exists() { | ||||
|             debug!("K3d binary not found at {:?}", binary_path); | ||||
| @ -131,15 +131,15 @@ impl K3d { | ||||
|         self.can_execute_binary_check(&binary_path) | ||||
|     } | ||||
| 
 | ||||
|     /// Verifies if the specified cluster is already running
 | ||||
|     /// Verifies if the specified cluster is already created
 | ||||
|     ///
 | ||||
|     /// Executes `k3d cluster list <cluster_name>` and checks for a successful response,
 | ||||
|     /// indicating that the cluster exists and is registered with k3d.
 | ||||
|     pub fn is_cluster_initialized(&self) -> bool { | ||||
|         let cluster_name = match &self.cluster_name { | ||||
|             Some(name) => name, | ||||
|             None => { | ||||
|                 debug!("No cluster name specified, can't verify if cluster is initialized"); | ||||
|         let cluster_name = match self.get_cluster_name() { | ||||
|             Ok(name) => name, | ||||
|             Err(_) => { | ||||
|                 debug!("Could not get cluster name, can't verify if cluster is initialized"); | ||||
|                 return false; | ||||
|             } | ||||
|         }; | ||||
| @ -152,6 +152,13 @@ impl K3d { | ||||
|         self.verify_cluster_exists(&binary_path, cluster_name) | ||||
|     } | ||||
| 
 | ||||
|     fn get_cluster_name(&self) -> Result<&String, String> { | ||||
|         match &self.cluster_name { | ||||
|             Some(name) => Ok(name), | ||||
|             None => Err("No cluster name available".to_string()), | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     /// Creates a new k3d cluster with the specified name
 | ||||
|     ///
 | ||||
|     /// This method:
 | ||||
| @ -163,22 +170,29 @@ impl K3d { | ||||
|     /// - `Ok(Client)` - Successfully created cluster and connected client
 | ||||
|     /// - `Err(String)` - Error message detailing what went wrong
 | ||||
|     pub async fn initialize_cluster(&self) -> Result<Client, String> { | ||||
|         let cluster_name = match &self.cluster_name { | ||||
|             Some(name) => name, | ||||
|             None => return Err("No cluster name specified for initialization".to_string()), | ||||
|         let cluster_name = match self.get_cluster_name() { | ||||
|             Ok(name) => name, | ||||
|             Err(_) => return Err("Could not get cluster_name, cannot initialize".to_string()), | ||||
|         }; | ||||
| 
 | ||||
|         let binary_path = self.base_dir.join(K3D_BIN_FILE_NAME); | ||||
|         if !binary_path.exists() { | ||||
|             return Err(format!("K3d binary not found at {:?}", binary_path)); | ||||
|         } | ||||
| 
 | ||||
|         info!("Initializing k3d cluster '{}'", cluster_name); | ||||
| 
 | ||||
|         self.create_cluster(&binary_path, cluster_name)?; | ||||
|         self.create_cluster(cluster_name)?; | ||||
|         self.create_kubernetes_client().await | ||||
|     } | ||||
| 
 | ||||
|     fn get_k3d_binary_path(&self) -> PathBuf { | ||||
|         self.base_dir.join(K3D_BIN_FILE_NAME) | ||||
|     } | ||||
| 
 | ||||
|     fn get_k3d_binary(&self) -> Result<PathBuf, String> { | ||||
|         let path = self.get_k3d_binary_path(); | ||||
|         if !path.exists() { | ||||
|             return Err(format!("K3d binary not found at {:?}", path)); | ||||
|         } | ||||
|         Ok(path) | ||||
|     } | ||||
| 
 | ||||
|     /// Ensures k3d is installed and the cluster is initialized
 | ||||
|     ///
 | ||||
|     /// This method provides a complete setup flow:
 | ||||
| @ -206,6 +220,8 @@ impl K3d { | ||||
|             return self.initialize_cluster().await; | ||||
|         } | ||||
| 
 | ||||
|         self.start_cluster().await?; | ||||
| 
 | ||||
|         info!("K3d and cluster are already properly set up"); | ||||
|         self.create_kubernetes_client().await | ||||
|     } | ||||
| @ -282,11 +298,27 @@ impl K3d { | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     fn create_cluster(&self, binary_path: &PathBuf, cluster_name: &str) -> Result<(), String> { | ||||
|         let output = std::process::Command::new(binary_path) | ||||
|             .args(["cluster", "create", cluster_name]) | ||||
|             .output() | ||||
|             .map_err(|e| format!("Failed to execute k3d command: {}", e))?; | ||||
|     pub fn run_k3d_command<I, S>(&self, args: I) -> Result<std::process::Output, String> | ||||
|     where | ||||
|         I: IntoIterator<Item = S>, | ||||
|         S: AsRef<std::ffi::OsStr>, | ||||
|     { | ||||
|         let binary_path = self.get_k3d_binary()?; | ||||
|         let output = std::process::Command::new(binary_path).args(args).output(); | ||||
|         match output { | ||||
|             Ok(output) => { | ||||
|                 let stderr = String::from_utf8_lossy(&output.stderr); | ||||
|                 debug!("stderr : {}", stderr); | ||||
|                 let stdout = String::from_utf8_lossy(&output.stdout); | ||||
|                 debug!("stdout : {}", stdout); | ||||
|                 Ok(output) | ||||
|             } | ||||
|             Err(e) => Err(format!("Failed to execute k3d command: {}", e)), | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     fn create_cluster(&self, cluster_name: &str) -> Result<(), String> { | ||||
|         let output = self.run_k3d_command(["cluster", "create", cluster_name])?; | ||||
| 
 | ||||
|         if !output.status.success() { | ||||
|             let stderr = String::from_utf8_lossy(&output.stderr); | ||||
| @ -310,6 +342,19 @@ impl K3d { | ||||
|             false => Err("Cannot get client! Cluster not initialized yet".to_string()), | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     async fn start_cluster(&self) -> Result<(), String> { | ||||
|         let cluster_name = self.get_cluster_name()?; | ||||
|         let output = self.run_k3d_command(["cluster", "start", cluster_name])?; | ||||
| 
 | ||||
|         if !output.status.success() { | ||||
|             let stderr = String::from_utf8_lossy(&output.stderr); | ||||
|             return Err(format!("Failed to start cluster: {}", stderr)); | ||||
|         } | ||||
| 
 | ||||
|         info!("Successfully started k3d cluster '{}'", cluster_name); | ||||
|         Ok(()) | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| #[cfg(test)] | ||||
|  | ||||
| @ -23,7 +23,7 @@ pub struct Config { | ||||
| } | ||||
| 
 | ||||
| impl Serialize for Config { | ||||
|     fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error> | ||||
|     fn serialize<S>(&self, _serializer: S) -> Result<S::Ok, S::Error> | ||||
|     where | ||||
|         S: serde::Serializer, | ||||
|     { | ||||
|  | ||||
| @ -10,11 +10,11 @@ mod test { | ||||
|     use std::net::Ipv4Addr; | ||||
| 
 | ||||
|     use crate::Config; | ||||
|     use pretty_assertions::assert_eq; | ||||
| 
 | ||||
|     #[cfg(opnsenseendtoend)] | ||||
|     #[tokio::test] | ||||
|     async fn test_public_sdk() { | ||||
|         use pretty_assertions::assert_eq; | ||||
|         let mac = "11:22:33:44:55:66"; | ||||
|         let ip = Ipv4Addr::new(10, 100, 8, 200); | ||||
|         let hostname = "test_hostname"; | ||||
|  | ||||
		Loading…
	
		Reference in New Issue
	
	Block a user