use yaml_rust::YamlLoader;
use std::borrow::Cow;
use std::collections::HashMap;
use std::env;
use std::path;
use super::{Context, Module, ModuleConfig};
use crate::configs::kubernetes::KubernetesConfig;
use crate::formatter::StringFormatter;
use crate::utils;
struct KubeCtxComponents {
user: Option<String>,
namespace: Option<String>,
cluster: Option<String>,
}
fn get_kube_context(filename: path::PathBuf) -> Option<String> {
let contents = utils::read_file(filename).ok()?;
let yaml_docs = YamlLoader::load_from_str(&contents).ok()?;
if yaml_docs.is_empty() {
return None;
}
let conf = &yaml_docs[0];
let current_ctx = conf["current-context"].as_str()?;
if current_ctx.is_empty() {
return None;
}
Some(current_ctx.to_string())
}
fn get_kube_ctx_component(filename: path::PathBuf, current_ctx: &str) -> Option<KubeCtxComponents> {
let contents = utils::read_file(filename).ok()?;
let yaml_docs = YamlLoader::load_from_str(&contents).ok()?;
if yaml_docs.is_empty() {
return None;
}
let conf = &yaml_docs[0];
let ctx_yaml = conf["contexts"].as_vec().and_then(|contexts| {
contexts
.iter()
.filter_map(|ctx| Some((ctx, ctx["name"].as_str()?)))
.find(|(_, name)| *name == current_ctx)
});
let ctx_components = KubeCtxComponents {
user: ctx_yaml
.and_then(|(ctx, _)| ctx["context"]["user"].as_str())
.and_then(|s| {
if s.is_empty() {
return None;
}
Some(s.to_owned())
}),
namespace: ctx_yaml
.and_then(|(ctx, _)| ctx["context"]["namespace"].as_str())
.and_then(|s| {
if s.is_empty() {
return None;
}
Some(s.to_owned())
}),
cluster: ctx_yaml
.and_then(|(ctx, _)| ctx["context"]["cluster"].as_str())
.and_then(|s| {
if s.is_empty() {
return None;
}
Some(s.to_owned())
}),
};
Some(ctx_components)
}
fn get_kube_user<'a>(config: &'a KubernetesConfig, kube_user: &'a str) -> Cow<'a, str> {
return get_alias(&config.user_aliases, kube_user).unwrap_or(Cow::Borrowed(kube_user));
}
fn get_kube_context_name<'a>(config: &'a KubernetesConfig, kube_ctx: &'a str) -> Cow<'a, str> {
return get_alias(&config.context_aliases, kube_ctx).unwrap_or(Cow::Borrowed(kube_ctx));
}
fn get_alias<'a>(
aliases: &'a HashMap<String, &'a str>,
alias_candidate: &'a str,
) -> Option<Cow<'a, str>> {
if let Some(val) = aliases.get(alias_candidate) {
return Some(Cow::Borrowed(val));
}
return aliases.iter().find_map(|(k, v)| {
let re = regex::Regex::new(&format!("^{k}$")).ok()?;
let replaced = re.replace(alias_candidate, *v);
match replaced {
Cow::Owned(replaced) => Some(Cow::Owned(replaced)),
_ => None,
}
});
}
pub fn module<'a>(context: &'a Context) -> Option<Module<'a>> {
let mut module = context.new_module("kubernetes");
let config: KubernetesConfig = KubernetesConfig::try_load(module.config);
// As we default to disabled=true, we have to check here after loading our config module,
// before it was only checking against whatever is in the config starship.toml
if config.disabled {
return None;
};
// If