Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
81 changes: 61 additions & 20 deletions src/cmd/context.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,26 +12,73 @@ use crate::shell::spawn_shell;
use crate::state::State;
use crate::vars;

fn enter_context(
fn enter_cloned_context(
settings: &Settings,
installed: Installed,
context_name: &str,
namespace_name: Option<&str>,
recursive: bool,
) -> Result<()> {
let session = Session::load()?;

let previous_ctx = session
.get_last_context()
.context("There is no previous context to switch to.")?;
let namespace_name = namespace_name.or(previous_ctx.namespace.as_deref());
let kubeconfig = installed.make_kubeconfig_for_context(&previous_ctx.context, namespace_name)?;

if settings.behavior.validate_namespaces {
if let Some(namespace_name) = namespace_name {
let namespaces = kubectl::get_namespaces(Some(&kubeconfig))?;
if !namespaces.iter().any(|x| x == namespace_name) {
eprintln!("Warning: namespace {} does not exist.", namespace_name);
}
}
}

if vars::is_kubie_active() && !recursive {
let path = kubeconfig::get_kubeconfig_path()?;
let file = File::create(&path).context("could not write in temporary KUBECONFIG file")?;
kubeconfig.write_to(file)?;
session.save(None)?;
} else {
spawn_shell(settings, kubeconfig, &session)?;
}

Ok(())
}

fn enter_context(
settings: &Settings,
skim_optons: &SkimOptions,
mut installed: Installed,
context_name: Option<String>,
mut namespace_name: Option<&str>,
recursive: bool,
) -> Result<()> {
let context_name = match context_name {
Some(context_name) => context_name,
None => match select_or_list_context(skim_optons, &mut installed)? {
SelectResult::Selected(x) => {
namespace_name = None;
x
}
_ => return Ok(()),
},
};

let state = State::load()?;
let mut session = Session::load()?;

let namespace_name =
namespace_name.or_else(|| state.namespace_history.get(context_name).and_then(|s| s.as_deref()));
namespace_name.or_else(|| state.namespace_history.get(&context_name).and_then(|s| s.as_deref()));

let kubeconfig = if context_name == "-" {
let kubeconfig = if &context_name == "-" {
let previous_ctx = session
.get_last_context()
.get_previous_context()
.context("There is no previous context to switch to.")?;
installed.make_kubeconfig_for_context(&previous_ctx.context, previous_ctx.namespace.as_deref())?
} else {
installed.make_kubeconfig_for_context(context_name, namespace_name)?
installed.make_kubeconfig_for_context(&context_name, namespace_name)?
};

session.add_history_entry(
Expand Down Expand Up @@ -64,26 +111,20 @@ pub fn context(
settings: &Settings,
skim_options: &SkimOptions,
context_name: Option<String>,
mut namespace_name: Option<String>,
namespace_name: Option<String>,
kubeconfigs: Vec<String>,
clone: bool,
recursive: bool,
) -> Result<()> {
let mut installed = if kubeconfigs.is_empty() {
let installed = if kubeconfigs.is_empty() {
kubeconfig::get_installed_contexts(settings)?
} else {
kubeconfig::get_kubeconfigs_contexts(&kubeconfigs)?
};

let context_name = match context_name {
Some(context_name) => context_name,
None => match select_or_list_context(skim_options, &mut installed)? {
SelectResult::Selected(x) => {
namespace_name = None;
x
}
_ => return Ok(()),
},
};

enter_context(settings, installed, &context_name, namespace_name.as_deref(), recursive)
if clone {
enter_cloned_context(settings, installed, namespace_name.as_deref(), recursive)
} else {
enter_context(settings, skim_options, installed, context_name, namespace_name.as_deref(), recursive)
}
}
4 changes: 4 additions & 0 deletions src/cmd/meta.rs
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,10 @@ pub enum Kubie {
#[clap(short = 'r', long = "recursive")]
recursive: bool,

/// Spawn a new shell by cloning current shell context
#[structopt(short = 'c', long = "clone")]
clone: bool,

/// Name of the context to enter. Use '-' to switch back to the previous context.
context_name: Option<String>,
},
Expand Down
2 changes: 2 additions & 0 deletions src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ fn main() -> Result<()> {
namespace_name,
context_name,
kubeconfigs,
clone,
recursive,
} => {
cmd::context::context(
Expand All @@ -33,6 +34,7 @@ fn main() -> Result<()> {
context_name,
namespace_name,
kubeconfigs,
clone,
recursive,
)?;
}
Expand Down
6 changes: 5 additions & 1 deletion src/session.rs
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ impl Session {
})
}

pub fn get_last_context(&self) -> Option<&HistoryEntry> {
pub fn get_previous_context(&self) -> Option<&HistoryEntry> {
let current_context = self.history.last()?;
for entry in self.history.iter().rev().skip(1) {
if current_context.context != entry.context {
Expand All @@ -55,6 +55,10 @@ impl Session {
None
}

pub fn get_last_context(&self) -> Option<&HistoryEntry> {
return self.history.last()
}

pub fn get_last_namespace(&self) -> Option<&str> {
let current_context = self.history.last()?;
for entry in self.history.iter().rev().skip(1) {
Expand Down