| 
						
					 | 
				
			
			 | 
			 | 
			
				@ -2,7 +2,7 @@ use std::{process::Command, sync::Arc};
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				use async_trait::async_trait;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				use inquire::Confirm;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				use log::{info, warn};
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				use log::{debug, info, warn};
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				use tokio::sync::OnceCell;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				use crate::{
 | 
			
		
		
	
	
		
			
				
					
					| 
						
					 | 
				
			
			 | 
			 | 
			
				@ -38,6 +38,7 @@ enum K8sSource {
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				pub struct K8sAnywhereTopology {
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    k8s_state: OnceCell<Option<K8sState>>,
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    tenant_manager: OnceCell<K8sTenantManager>,
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    config: K8sAnywhereConfig,
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				}
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				#[async_trait]
 | 
			
		
		
	
	
		
			
				
					
					| 
						
					 | 
				
			
			 | 
			 | 
			
				@ -58,10 +59,19 @@ impl K8sclient for K8sAnywhereTopology {
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				}
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				impl K8sAnywhereTopology {
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    pub fn new() -> Self {
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    pub fn from_env() -> Self {
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        Self {
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				            k8s_state: OnceCell::new(),
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				            tenant_manager: OnceCell::new(),
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				            config: K8sAnywhereConfig::from_env(),
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        }
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    }
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    pub fn with_config(config: K8sAnywhereConfig) -> Self {
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        Self {
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				            k8s_state: OnceCell::new(),
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				            tenant_manager: OnceCell::new(),
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				            config,
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        }
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    }
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
	
		
			
				
					
					| 
						
					 | 
				
			
			 | 
			 | 
			
				@ -102,22 +112,10 @@ impl K8sAnywhereTopology {
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    }
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    async fn try_get_or_install_k8s_client(&self) -> Result<Option<K8sState>, InterpretError> {
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        let k8s_anywhere_config = K8sAnywhereConfig {
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				            kubeconfig: std::env::var("KUBECONFIG").ok().map(|v| v.to_string()),
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				            use_system_kubeconfig: std::env::var("HARMONY_USE_SYSTEM_KUBECONFIG")
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				                .map_or_else(|_| false, |v| v.parse().ok().unwrap_or(false)),
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				            autoinstall: std::env::var("HARMONY_AUTOINSTALL")
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				                .map_or_else(|_| false, |v| v.parse().ok().unwrap_or(false)),
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        };
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        let k8s_anywhere_config = &self.config;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        if k8s_anywhere_config.use_system_kubeconfig {
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				            match self.try_load_system_kubeconfig().await {
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				                Some(_client) => todo!(),
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				                None => todo!(),
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				            }
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        }
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        if let Some(kubeconfig) = k8s_anywhere_config.kubeconfig {
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        if let Some(kubeconfig) = &k8s_anywhere_config.kubeconfig {
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				            debug!("Loading kubeconfig {kubeconfig}");
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				            match self.try_load_kubeconfig(&kubeconfig).await {
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				                Some(client) => {
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				                    return Ok(Some(K8sState {
 | 
			
		
		
	
	
		
			
				
					
					| 
						
					 | 
				
			
			 | 
			 | 
			
				@ -134,6 +132,14 @@ impl K8sAnywhereTopology {
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				            }
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        }
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        if k8s_anywhere_config.use_system_kubeconfig {
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				            debug!("Loading system kubeconfig");
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				            match self.try_load_system_kubeconfig().await {
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				                Some(_client) => todo!(),
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				                None => todo!(),
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				            }
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        }
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        info!("No kubernetes configuration found");
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        if !k8s_anywhere_config.autoinstall {
 | 
			
		
		
	
	
		
			
				
					
					| 
						
					 | 
				
			
			 | 
			 | 
			
				@ -197,25 +203,37 @@ impl K8sAnywhereTopology {
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    }
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				}
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				struct K8sAnywhereConfig {
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				pub struct K8sAnywhereConfig {
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    /// The path of the KUBECONFIG file that Harmony should use to interact with the Kubernetes
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    /// cluster
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    ///
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    /// Default : None
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    kubeconfig: Option<String>,
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    pub kubeconfig: Option<String>,
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    /// Whether to use the system KUBECONFIG, either the environment variable or the file in the
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    /// default or configured location
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    ///
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    /// Default : false
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    use_system_kubeconfig: bool,
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    pub use_system_kubeconfig: bool,
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    /// Whether to install automatically a kubernetes cluster
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    ///
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    /// When enabled, autoinstall will setup a K3D cluster on the localhost. https://k3d.io/stable/
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    ///
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    /// Default: true
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    autoinstall: bool,
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    pub autoinstall: bool,
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				}
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				impl K8sAnywhereConfig {
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    fn from_env() -> Self {
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        Self {
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				            kubeconfig: std::env::var("KUBECONFIG").ok().map(|v| v.to_string()),
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				            use_system_kubeconfig: std::env::var("HARMONY_USE_SYSTEM_KUBECONFIG")
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				                .map_or_else(|_| false, |v| v.parse().ok().unwrap_or(false)),
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				            autoinstall: std::env::var("HARMONY_AUTOINSTALL")
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				                .map_or_else(|_| false, |v| v.parse().ok().unwrap_or(false)),
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        }
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    }
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				}
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				#[async_trait]
 | 
			
		
		
	
	
		
			
				
					
					| 
						
					 | 
				
			
			 | 
			 | 
			
				
 
 |