diff --git a/src/commands.rs b/src/commands.rs index c76ca4c..0e989c4 100644 --- a/src/commands.rs +++ b/src/commands.rs @@ -89,7 +89,7 @@ pub fn selectable_list(input: Vec) -> Option { pub fn set_context(ctx: &str, temp_dir: &str, config: &Kubeconfig) -> Result<(), SetContextError> { if let Some(choice) = config.contexts.iter().find(|x| x.name == ctx) { - config::write(choice, None, temp_dir); + config::write(choice, None, temp_dir, config); Ok(()) } else { Err(SetContextError::KubeContextNotFound { diff --git a/src/config.rs b/src/config.rs index 0580011..95db66f 100644 --- a/src/config.rs +++ b/src/config.rs @@ -27,7 +27,7 @@ pub fn get() -> Kubeconfig { println!("Loaded Kubeconfig from: {:?}", path); merged_config.contexts.extend(kubeconfig.contexts); merged_config.clusters.extend(kubeconfig.clusters); - // base.auth_infos.extend(additional.auth_infos); + merged_config.auth_infos.extend(kubeconfig.auth_infos); } Err(err) => { println!("Failed to parse file {:?} as a Kubeconfig: {:?}", path, err); @@ -41,35 +41,59 @@ pub fn get() -> Kubeconfig { merged_config } -fn build(ctx: &NamedContext, ns: Option<&str>, strbuf: &str) -> KubeConfig { - let mut config: KubeConfig = serde_yaml::from_str(strbuf).unwrap(); - config.api_version = "v1".to_string(); - config.kind = "Config".to_string(); - config.current_context = ctx.name.to_string(); +pub fn build( + selected_context: &NamedContext, + namespace: Option<&str>, + kubeconfig: &Kubeconfig, +) -> Kubeconfig { + let context_name = &selected_context.name; - let ns = match ns { - Some(namespace) => namespace.to_string(), + // Handle the case where the context is None + let context = match &selected_context.context { + Some(ctx) => ctx, None => { - if !config.contexts.is_empty() && !config.contexts[0].context.namespace.is_empty() { - config.contexts[0].context.namespace.to_string() - // } else if !ctx.context.namespace.is_empty() { - // ctx.context.namespace.to_string() - } else { - "default".to_string() - } + eprintln!("Error: The selected context has no associated context data."); + return Kubeconfig::default(); } }; - // config.contexts = vec![NamedContext { - // context: NamedContext { - // namespace: ns, - // cluster: ctx.context.cluster.to_string(), - // user: ctx.context.user.to_string(), - // }, - // name: ctx.name.to_string(), - // }]; + // Find the corresponding cluster based on the context's cluster reference + let cluster_name = &context.cluster; + let selected_cluster = kubeconfig + .clusters + .iter() + .find(|cluster| &cluster.name == cluster_name) + .expect("Cluster for the selected context not found"); + + // Find the corresponding auth_info (user) based on the context's user reference + let user_name = &context.user; + let selected_auth_info = kubeconfig + .auth_infos + .iter() + .find(|auth_info| &auth_info.name == user_name) + .expect("Auth info for the selected context not found"); + + // Determine the namespace: use the provided one or fallback to the context's namespace + let final_namespace = match namespace { + Some(ns) => ns.to_string(), + None => context + .namespace + .clone() + .unwrap_or_else(|| "default".to_string()), + }; - config + let mut minimal_context = selected_context.clone(); + if let Some(ref mut ctx) = minimal_context.context { + ctx.namespace = Some(final_namespace); + } + + Kubeconfig { + current_context: Some(context_name.clone()), + contexts: vec![minimal_context], + clusters: vec![selected_cluster.clone()], + auth_infos: vec![selected_auth_info.clone()], + ..Kubeconfig::default() + } } fn get_file(path: &String) -> File { @@ -83,8 +107,10 @@ fn get_file(path: &String) -> File { f } -fn get_path(ctx: &NamedContext, dest: &str) -> String { - let path = Path::new(ctx.name.as_str()); +fn get_path(ctx: &str, namespace: &str, dest: &str) -> String { + let filename = ctx.to_owned() + "_" + &namespace.to_owned(); + + let path = Path::new(&filename); let parent = path.parent().unwrap(); let dirname = str::replace(&parent.display().to_string(), ":", "_"); @@ -96,63 +122,21 @@ fn get_path(ctx: &NamedContext, dest: &str) -> String { path.display().to_string() } -pub fn write(ctx: &NamedContext, namespace: Option<&str>, dest: &str) { - let path = get_path(ctx, dest); +pub fn write(ctx: &NamedContext, namespace: Option<&str>, dest: &str, config: &Kubeconfig) { + let minimal_config = build(ctx, namespace, config); + let selected_context = minimal_config.current_context.clone().unwrap_or_default(); + let selected_ns = minimal_config + .contexts + .first() + .and_then(|ctx| ctx.context.as_ref().and_then(|c| c.namespace.clone())) + .unwrap_or_else(|| "default".to_string()); - let strbuf = match fs::read_to_string(&path) { - Ok(file) => file, - Err(_error) => "".to_string(), - }; + let path = get_path(&selected_context, &selected_ns, dest); let options = get_file(&path); let writer = BufWriter::new(&options); - let config = build(ctx, namespace, &strbuf); - - serde_yaml::to_writer(writer, &config).unwrap(); -} -// pub fn get() -> KubeConfig { -// let mut configs = KubeConfig::default(); -// -// for s in KUBECONFIG.rsplit(':') { -// if s.contains("/kubesess/cache") { -// continue; -// } -// let config: KubeConfig = get_config(s); -// -// configs.current_context = config.current_context; -// configs.api_version = config.api_version; -// configs.kind = config.kind; -// configs.contexts.extend(config.contexts); -// } -// -// let dir = format!("{}/.kube", dirs::home_dir().unwrap().display()); -// for entry in fs::read_dir(dir).unwrap() { -// let path = entry.unwrap().path(); -// if let Some(extension) = path.extension() { -// if extension == "yaml" { -// let config: KubeConfig = get_config(path.to_str().unwrap()); -// -// configs.contexts.extend(config.contexts); -// } -// } -// } -// -// configs -// } - -fn get_config(path: &str) -> KubeConfig { - let f = File::open(path).unwrap(); - - let mut reader = BufReader::new(f); - let mut tmp = String::new(); - reader - .read_to_string(&mut tmp) - .expect("Unable to read file"); - - let config: KubeConfig = serde_yaml::from_str(tmp.trim()).unwrap(); - - config + serde_yaml::to_writer(writer, &minimal_config).unwrap(); } pub fn get_current_session() -> KubeConfig {