{ 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" } ''; }; }