From 9fed36e6ee904c0d7f6581c0b1576f0c2d8bbfb9 Mon Sep 17 00:00:00 2001 From: John Ogle Date: Sat, 2 Aug 2025 10:41:13 -0700 Subject: [PATCH] [kubectl] Add home module --- home/home.nix | 7 +- home/modules/kubectl/default.nix | 249 +++++++++++++++++++++++++++++++ 2 files changed, 252 insertions(+), 4 deletions(-) create mode 100644 home/modules/kubectl/default.nix diff --git a/home/home.nix b/home/home.nix index d0db08e..4d445ef 100644 --- a/home/home.nix +++ b/home/home.nix @@ -68,9 +68,7 @@ in pkgs.wofi pkgs.vlc - ## Kubernetes cluster management - pkgs.kubectl - pkgs.kubernetes-helm + ## Kubernetes cluster management handled by kubectl-secure module globalInputs.google-cookie-retrieval.packages.${system}.default ]; @@ -117,6 +115,7 @@ in imports = [ ./modules/emacs ./modules/i3+sway + ./modules/kubectl ./modules/plasma-manager ./modules/tmux ]; @@ -152,7 +151,7 @@ in programs.jq.enable = true; - programs.k9s.enable = true; + programs.kubectl-secure.enable = true; programs.neovim = { enable = true; diff --git a/home/modules/kubectl/default.nix b/home/modules/kubectl/default.nix new file mode 100644 index 0000000..0da3d8c --- /dev/null +++ b/home/modules/kubectl/default.nix @@ -0,0 +1,249 @@ +{ config, lib, pkgs, ... }: + +with lib; + +let + cfg = config.programs.kubectl-secure; +in +{ + options.programs.kubectl-secure = { + enable = mkEnableOption "secure kubectl configuration with Bitwarden integration"; + }; + + config = mkIf cfg.enable { + home.packages = with pkgs; [ + kubectl + kubernetes-helm + ]; + + programs.k9s.enable = true; + + programs.bash.initExtra = mkAfter '' + # Kubectl secure session management + export KUBECTL_SESSION_DIR="/dev/shm/kubectl-$$" + + kube-select() { + if [[ $# -ne 1 ]]; then + echo "Usage: kube-select " + echo "Available contexts: $(kube-list)" + return 1 + fi + + local context="$1" + + # Clean up any existing session first + kube-clear 2>/dev/null + + # Create new session directory + mkdir -p "$KUBECTL_SESSION_DIR" + chmod 700 "$KUBECTL_SESSION_DIR" + + # Set cleanup trap for this shell session + trap "rm -rf '$KUBECTL_SESSION_DIR' 2>/dev/null" EXIT + + # Set KUBECONFIG for this session + export KUBECONFIG="$KUBECTL_SESSION_DIR/config" + + # Load config from Bitwarden secure notes + if ! rbw get "kubectl-$context" > "$KUBECONFIG" 2>/dev/null; then + echo "Error: Could not retrieve kubectl-$context from Bitwarden" + echo "Make sure the entry exists with name: kubectl-$context" + kube-clear + return 1 + fi + + # Verify the kubeconfig is valid + if ! kubectl config view >/dev/null 2>&1; then + echo "Error: Invalid kubeconfig retrieved from Bitwarden" + kube-clear + return 1 + fi + + echo "✓ Loaded kubectl context: $context (session: $$)" + echo " Config location: $KUBECONFIG" + } + + kube-list() { + echo "Available kubectl contexts in Bitwarden:" + rbw search kubectl- 2>/dev/null | grep "^kubectl-" | sed 's/^kubectl-/ - /' || echo " (none found or rbw not accessible)" + } + + kube-clear() { + if [[ -n "$KUBECTL_TIMEOUT_PID" ]]; then + kill "$KUBECTL_TIMEOUT_PID" 2>/dev/null + unset KUBECTL_TIMEOUT_PID + fi + + if [[ -d "$KUBECTL_SESSION_DIR" ]]; then + rm -rf "$KUBECTL_SESSION_DIR" + echo "Cleared kubectl session ($$)" + fi + + unset KUBECONFIG + } + + kube-status() { + if [[ -f "$KUBECONFIG" ]]; then + local current_context + current_context=$(kubectl config current-context 2>/dev/null) + if [[ -n "$current_context" ]]; then + echo "Active kubectl context: $current_context" + echo "Session: $$ | Config: $KUBECONFIG" + + # Show cluster info + local cluster_server + cluster_server=$(kubectl config view --minify -o jsonpath='{.clusters[0].cluster.server}' 2>/dev/null) + if [[ -n "$cluster_server" ]]; then + echo "Cluster: $cluster_server" + fi + else + echo "No active context in current session" + fi + else + echo "No kubectl session active in this shell" + echo "Use 'kube-select ' to start a session" + fi + } + + # Helper function to show available commands + kube-help() { + echo "Secure kubectl session management commands:" + echo "" + echo "Session management:" + echo " kube-select - Load kubeconfig from Bitwarden" + echo " kube-status - Show current session status" + echo " kube-clear - Clear current session" + echo "" + echo "Configuration management:" + echo " kube-list - List available contexts in Bitwarden" + echo "" + echo "Help:" + echo " kube-help - Show this help" + echo "" + echo "Examples:" + echo " kube-select prod # Loads from secure note" + echo " kubectl get pods" + echo " kube-clear" + echo "" + echo "Note: Kubeconfigs are stored as secure notes in Bitwarden" + } + ''; + + programs.zsh.initExtra = mkAfter '' + # Kubectl secure session management (zsh) + export KUBECTL_SESSION_DIR="/dev/shm/kubectl-$$" + + kube-select() { + if [[ $# -ne 1 ]]; then + echo "Usage: kube-select " + echo "Available contexts: $(kube-list)" + return 1 + fi + + local context="$1" + + # Clean up any existing session first + kube-clear 2>/dev/null + + # Create new session directory + mkdir -p "$KUBECTL_SESSION_DIR" + chmod 700 "$KUBECTL_SESSION_DIR" + + # Set cleanup trap for this shell session + trap "rm -rf '$KUBECTL_SESSION_DIR' 2>/dev/null" EXIT + + # Set KUBECONFIG for this session + export KUBECONFIG="$KUBECTL_SESSION_DIR/config" + + # Load config from Bitwarden secure notes + if ! rbw get "kubectl-$context" > "$KUBECONFIG" 2>/dev/null; then + echo "Error: Could not retrieve kubectl-$context from Bitwarden" + echo "Make sure the entry exists with name: kubectl-$context" + kube-clear + return 1 + fi + + # Verify the kubeconfig is valid + if ! kubectl config view >/dev/null 2>&1; then + echo "Error: Invalid kubeconfig retrieved from Bitwarden" + kube-clear + return 1 + fi + + echo "✓ Loaded kubectl context: $context (session: $$)" + echo " Config location: $KUBECONFIG" + + # Optional: Set timeout cleanup + if [[ ${toString cfg.sessionTimeout} -gt 0 ]]; then + (sleep ${toString cfg.sessionTimeout}; kube-clear 2>/dev/null) & + export KUBECTL_TIMEOUT_PID=$! + fi + } + + kube-list() { + echo "Available kubectl contexts in Bitwarden:" + rbw search kubectl- 2>/dev/null | grep "^kubectl-" | sed 's/^kubectl-/ - /' || echo " (none found or rbw not accessible)" + } + + kube-clear() { + if [[ -n "$KUBECTL_TIMEOUT_PID" ]]; then + kill "$KUBECTL_TIMEOUT_PID" 2>/dev/null + unset KUBECTL_TIMEOUT_PID + fi + + if [[ -d "$KUBECTL_SESSION_DIR" ]]; then + rm -rf "$KUBECTL_SESSION_DIR" + echo "Cleared kubectl session ($$)" + fi + + unset KUBECONFIG + } + + kube-status() { + if [[ -f "$KUBECONFIG" ]]; then + local current_context + current_context=$(kubectl config current-context 2>/dev/null) + if [[ -n "$current_context" ]]; then + echo "Active kubectl context: $current_context" + echo "Session: $$ | Config: $KUBECONFIG" + + # Show cluster info + local cluster_server + cluster_server=$(kubectl config view --minify -o jsonpath='{.clusters[0].cluster.server}' 2>/dev/null) + if [[ -n "$cluster_server" ]]; then + echo "Cluster: $cluster_server" + fi + else + echo "No active context in current session" + fi + else + echo "No kubectl session active in this shell" + echo "Use 'kube-select ' to start a session" + fi + } + + # Helper function to show available commands + kube-help() { + echo "Secure kubectl session management commands:" + echo "" + echo "Session management:" + echo " kube-select - Load kubeconfig from Bitwarden" + echo " kube-status - Show current session status" + echo " kube-clear - Clear current session" + echo "" + echo "Configuration management:" + echo " kube-list - List available contexts in Bitwarden" + echo "" + echo "Help:" + echo " kube-help - Show this help" + echo "" + echo "Examples:" + echo " kube-select prod # Loads from secure note" + echo " kubectl get pods" + echo " kube-clear" + echo "" + echo "Note: Kubeconfigs are stored as secure notes in Bitwarden" + } + ''; + }; +}