forked from NationTech/harmony
		
	wip: Implement basic K8sAnywhere setup with K3d support
- Added initial K8sAnywhere topology and related modules. - Implemented a basic K3d installation score for cluster bootstrapping. - Introduced LocalhostTopology for local development and testing. - Added necessary module structure and dependencies. - Implemented user prompt for K3d installation confirmation. - Added basic error handling and logging. - Refactored existing code to improve modularity and maintainability. - Included necessary tests to ensure functionality.
This commit is contained in:
		
							parent
							
								
									6812d05849
								
							
						
					
					
						commit
						3f6f1fa0d4
					
				| @ -1,8 +1,12 @@ | |||||||
|  | use std::io; | ||||||
|  | 
 | ||||||
| use async_trait::async_trait; | use async_trait::async_trait; | ||||||
| use log::info; | use log::{info, warn}; | ||||||
| use tokio::sync::OnceCell; | use tokio::sync::OnceCell; | ||||||
| 
 | 
 | ||||||
| use crate::interpret::{InterpretError, Outcome}; | use crate::{ | ||||||
|  |     interpret::{InterpretError, Outcome}, inventory::Inventory, maestro::Maestro, topology::LocalhostTopology | ||||||
|  | }; | ||||||
| 
 | 
 | ||||||
| use super::{Topology, k8s::K8sClient}; | use super::{Topology, k8s::K8sClient}; | ||||||
| 
 | 
 | ||||||
| @ -13,8 +17,8 @@ struct K8sState { | |||||||
| } | } | ||||||
| 
 | 
 | ||||||
| enum K8sSource { | enum K8sSource { | ||||||
|     Existing, |     RemoteCluster, | ||||||
|     K3d, |     LocalK3d, | ||||||
|     // TODO: Add variants for cloud providers like AwsEks, Gke, Aks
 |     // TODO: Add variants for cloud providers like AwsEks, Gke, Aks
 | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| @ -23,7 +27,7 @@ pub struct K8sAnywhereTopology { | |||||||
| } | } | ||||||
| 
 | 
 | ||||||
| impl K8sAnywhereTopology { | impl K8sAnywhereTopology { | ||||||
|     async fn try_load_default_kubeconfig(&self) -> Option<K8sClient> { |     async fn try_load_system_kubeconfig(&self) -> Option<K8sClient> { | ||||||
|         todo!("Use kube-rs default behavior to load system kubeconfig"); |         todo!("Use kube-rs default behavior to load system kubeconfig"); | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
| @ -32,9 +36,12 @@ impl K8sAnywhereTopology { | |||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     async fn try_install_k3d(&self) -> Result<K8sClient, InterpretError> { |     async fn try_install_k3d(&self) -> Result<K8sClient, InterpretError> { | ||||||
|  |         let maestro = Maestro::new(Inventory::autoload(), LocalhostTopology::new()); | ||||||
|  |         let k3d_score = K3DInstallationScore::default(); | ||||||
|  |         maestro.interpret(Box::new(k3d_score)).await; | ||||||
|         todo!( |         todo!( | ||||||
|             "Create Maestro with LocalDockerTopology or something along these lines and run a K3dInstallationScore on it" |             "Create Maestro with LocalDockerTopology or something along these lines and run a K3dInstallationScore on it" | ||||||
|         ) |         ); | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     async fn try_get_or_install_k8s_client(&self) -> Result<Option<K8sState>, InterpretError> { |     async fn try_get_or_install_k8s_client(&self) -> Result<Option<K8sState>, InterpretError> { | ||||||
| @ -49,7 +56,7 @@ impl K8sAnywhereTopology { | |||||||
|         }; |         }; | ||||||
| 
 | 
 | ||||||
|         if k8s_anywhere_config.use_system_kubeconfig { |         if k8s_anywhere_config.use_system_kubeconfig { | ||||||
|             match self.try_load_default_kubeconfig().await { |             match self.try_load_system_kubeconfig().await { | ||||||
|                 Some(client) => todo!(), |                 Some(client) => todo!(), | ||||||
|                 None => todo!(), |                 None => todo!(), | ||||||
|             } |             } | ||||||
| @ -61,17 +68,36 @@ impl K8sAnywhereTopology { | |||||||
|                 None => todo!(), |                 None => todo!(), | ||||||
|             } |             } | ||||||
|         } |         } | ||||||
|  | 
 | ||||||
|         info!("No kubernetes configuration found"); |         info!("No kubernetes configuration found"); | ||||||
| 
 | 
 | ||||||
|         if !k8s_anywhere_config.autoinstall { |         if !k8s_anywhere_config.autoinstall { | ||||||
|             info!( |             info!( | ||||||
|                 "Harmony autoinstallation is not activated, do you wish to launch autoinstallation?" |                 "Harmony autoinstallation is not activated, do you wish to launch autoinstallation? (y/N) : " | ||||||
|             ); |             ); | ||||||
|             todo!("Prompt user"); |             let mut input = String::new(); | ||||||
|  | 
 | ||||||
|  |             io::stdin() | ||||||
|  |                 .read_line(&mut input) | ||||||
|  |                 .expect("Failed to read line"); | ||||||
|  | 
 | ||||||
|  |             let input = input.trim(); | ||||||
|  | 
 | ||||||
|  |             if !input.eq_ignore_ascii_case("y") { | ||||||
|  |                 warn!( | ||||||
|  |                     "Installation cancelled, K8sAnywhere could not initialize a valid Kubernetes client" | ||||||
|  |                 ); | ||||||
|  |                 return Ok(None); | ||||||
|  |             } | ||||||
|         } |         } | ||||||
| 
 | 
 | ||||||
|  |         info!("Starting K8sAnywhere installation"); | ||||||
|         match self.try_install_k3d().await { |         match self.try_install_k3d().await { | ||||||
|             Ok(client) => todo!(), |             Ok(client) => Ok(Some(K8sState { | ||||||
|  |                 client, | ||||||
|  |                 source: K8sSource::LocalK3d, | ||||||
|  |                 message: "Successfully installed K3D cluster and acquired client".to_string(), | ||||||
|  |             })), | ||||||
|             Err(_) => todo!(), |             Err(_) => todo!(), | ||||||
|         } |         } | ||||||
|     } |     } | ||||||
|  | |||||||
							
								
								
									
										20
									
								
								harmony/src/domain/topology/localhost.rs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										20
									
								
								harmony/src/domain/topology/localhost.rs
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,20 @@ | |||||||
|  | use async_trait::async_trait; | ||||||
|  | use derive_new::new; | ||||||
|  | 
 | ||||||
|  | use crate::interpret::{InterpretError, Outcome}; | ||||||
|  | 
 | ||||||
|  | use super::Topology; | ||||||
|  | 
 | ||||||
|  | #[derive(new)] | ||||||
|  | pub struct LocalhostTopology; | ||||||
|  | 
 | ||||||
|  | #[async_trait] | ||||||
|  | impl Topology for LocalhostTopology { | ||||||
|  |     fn name(&self) -> &str { | ||||||
|  |         "LocalHostTopology" | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     async fn ensure_ready(&self) -> Result<Outcome, InterpretError> { | ||||||
|  |         Ok(Outcome::success("Localhost is Chuck Norris, always ready.".to_string())) | ||||||
|  |     } | ||||||
|  | } | ||||||
| @ -2,6 +2,8 @@ mod ha_cluster; | |||||||
| mod host_binding; | mod host_binding; | ||||||
| mod http; | mod http; | ||||||
| mod k8s_anywhere; | mod k8s_anywhere; | ||||||
|  | mod localhost; | ||||||
|  | pub use localhost::*; | ||||||
| pub use k8s_anywhere::*; | pub use k8s_anywhere::*; | ||||||
| mod load_balancer; | mod load_balancer; | ||||||
| pub mod k8s; | pub mod k8s; | ||||||
|  | |||||||
							
								
								
									
										25
									
								
								harmony/src/modules/k3d/install.rs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										25
									
								
								harmony/src/modules/k3d/install.rs
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,25 @@ | |||||||
|  | use serde::Serialize; | ||||||
|  | 
 | ||||||
|  | use crate::{score::Score, topology::Topology}; | ||||||
|  | 
 | ||||||
|  | #[derive(Debug, Clone, Serialize)] | ||||||
|  | pub struct K3DInstallationScore {} | ||||||
|  | 
 | ||||||
|  | impl<T: Topology> Score<T> for K3DInstallationScore { | ||||||
|  |     fn create_interpret(&self) -> Box<dyn crate::interpret::Interpret<T>> { | ||||||
|  |         todo!(" | ||||||
|  |         1. Decide if I create a new crate for k3d management, especially to avoid the ocrtograb dependency | ||||||
|  |         2. Implement k3d management | ||||||
|  |         3. Find latest tag | ||||||
|  |         4. Download k3d to some path managed by harmony (or not?) | ||||||
|  |         5. Bootstrap cluster | ||||||
|  |         6. Get kubeconfig | ||||||
|  |         7. Load kubeconfig in k8s anywhere | ||||||
|  |         8. Complete k8sanywhere setup | ||||||
|  |         ")
 | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     fn name(&self) -> String { | ||||||
|  |         todo!() | ||||||
|  |     } | ||||||
|  | } | ||||||
							
								
								
									
										3
									
								
								harmony/src/modules/k3d/mod.rs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										3
									
								
								harmony/src/modules/k3d/mod.rs
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,3 @@ | |||||||
|  | 
 | ||||||
|  | mod install; | ||||||
|  | 
 | ||||||
| @ -8,3 +8,4 @@ pub mod load_balancer; | |||||||
| pub mod okd; | pub mod okd; | ||||||
| pub mod opnsense; | pub mod opnsense; | ||||||
| pub mod tftp; | pub mod tftp; | ||||||
|  | mod k3d; | ||||||
|  | |||||||
		Loading…
	
		Reference in New Issue
	
	Block a user