Last active
January 21, 2026 15:48
-
-
Save ahmadasjad/b1863a38a22448bb38232eae4fd5b43a to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| #!/bin/bash | |
| # ANSI colors | |
| RED='\033[0;31m' | |
| GREEN='\033[0;32m' | |
| BLUE='\033[0;34m' | |
| CYAN='\033[0;36m' | |
| YELLOW='\033[1;33m' | |
| NC='\033[0m' # No Color | |
| # Initial state | |
| CURRENT_NS=$(kubectl config view --minify --output 'jsonpath={..namespace}') | |
| if [ -z "$CURRENT_NS" ]; then | |
| CURRENT_NS="default" | |
| fi | |
| CURRENT_CTX=$(kubectl config current-context) | |
| # Trap Ctrl+C to exit cleanly | |
| trap "echo -e '\n${RED}Exiting...${NC}'; exit 0" SIGINT | |
| # Function: Render menu and get selection using arrow keys | |
| # Arguments: "Title" "Option1" "Option2" ... | |
| function menu_select() { | |
| local title="$1" | |
| shift | |
| local options=("$@") | |
| local cur=0 | |
| local count=${#options[@]} | |
| local key="" | |
| local esc=$(echo -en "\033") | |
| # Hide cursor | |
| echo -ne "\033[?25l" | |
| while true; do | |
| # Clear screen from current position up needed amount roughly, or just redraw | |
| # To be safe and simple in a script, we'll clear the screen or just reprint | |
| # specific lines. For better UI, let's clear screen. | |
| # clear | |
| printf '\033[2J\033[H' | |
| echo -e "${CYAN}=========================================${NC}" | |
| echo -e "${YELLOW} Context: ${NC}$CURRENT_CTX | ${YELLOW}Namespace: ${NC}$CURRENT_NS" | |
| echo -e "${CYAN}=========================================${NC}" | |
| echo -e "${BLUE} $title ${NC}" | |
| echo -e "${CYAN}-----------------------------------------${NC}" | |
| for ((i=0; i<count; i++)); do | |
| if [ $i -eq $cur ]; then | |
| echo -e " > ${GREEN}${options[$i]}${NC}" | |
| else | |
| echo -e " ${options[$i]}" | |
| fi | |
| done | |
| read -s -n 1 key | |
| if [[ $key == $esc ]]; then | |
| read -s -n 2 key # Read next 2 chars | |
| if [[ $key == "[A" ]]; then # Up arrow | |
| ((cur--)) | |
| if [ $cur -lt 0 ]; then cur=$((count-1)); fi | |
| elif [[ $key == "[B" ]]; then # Down arrow | |
| ((cur++)) | |
| if [ $cur -ge $count ]; then cur=0; fi | |
| fi | |
| elif [[ "$key" == "" ]]; then # Enter key (empty string from read) | |
| break | |
| fi | |
| done | |
| # Show cursor | |
| echo -ne "\033[?25h" | |
| # Return index and value | |
| SELECTED_INDEX=$cur | |
| SELECTED_VALUE="${options[$cur]}" | |
| } | |
| function select_namespace() { | |
| echo "Fetching namespaces..." | |
| # Get namespaces list | |
| local ns_list=($(kubectl get ns --no-headers -o custom-columns=":metadata.name")) | |
| if [ ${#ns_list[@]} -eq 0 ]; then | |
| echo -e "${RED}No namespaces found or error connecting to cluster.${NC}" | |
| read -p "Press Enter to continue..." | |
| return | |
| fi | |
| menu_select "Select Namespace" "${ns_list[@]}" "Cancel" | |
| if [[ "$SELECTED_VALUE" != "Cancel" ]]; then | |
| CURRENT_NS="$SELECTED_VALUE" | |
| # Optional: Set it in kubectl config too so it persists for this session effectively | |
| kubectl config set-context --current --namespace="$CURRENT_NS" > /dev/null 2>&1 | |
| fi | |
| } | |
| function select_pod() { | |
| echo "Fetching pods in $CURRENT_NS..." | |
| # Get pods list | |
| local pod_list=($(kubectl get pods -n "$CURRENT_NS" --no-headers -o custom-columns=":metadata.name")) | |
| if [ ${#pod_list[@]} -eq 0 ]; then | |
| echo -e "${RED}No pods found in namespace $CURRENT_NS${NC}" | |
| read -p "Press Enter to continue..." | |
| return | |
| fi | |
| pod_list+=("Back") | |
| while true; do | |
| menu_select "Select Pod (Namespace: $CURRENT_NS)" "${pod_list[@]}" | |
| local pod="$SELECTED_VALUE" | |
| if [[ "$pod" == "Back" ]]; then | |
| return | |
| fi | |
| # Pod Action Menu | |
| local actions=("Logs" "Describe" "Exec (Shell)" "Delete" "Back") | |
| menu_select "Action for Pod: $pod" "${actions[@]}" | |
| case "$SELECTED_VALUE" in | |
| "Logs") | |
| printf '\033[2J\033[H' | |
| echo -e "${GREEN}Showing logs for $pod (Press Ctrl+C to exit logs)...${NC}" | |
| kubectl logs -f -n "$CURRENT_NS" "$pod" | |
| read -p "Press Enter to return..." | |
| ;; | |
| "Describe") | |
| clear | |
| kubectl describe pod -n "$CURRENT_NS" "$pod" | less | |
| ;; | |
| "Exec (Shell)") | |
| printf '\033[2J\033[H' | |
| echo -e "${GREEN}Entering shell in $pod...${NC}" | |
| # Try sh, then bash if sh fails (or just try generic one) | |
| kubectl exec -it -n "$CURRENT_NS" "$pod" -- /bin/sh || kubectl exec -it -n "$CURRENT_NS" "$pod" -- /bin/bash | |
| ;; | |
| "Delete") | |
| echo -ne "${RED}Are you sure you want to delete $pod? (y/N): ${NC}" | |
| read -r confirm | |
| if [[ "$confirm" =~ ^[Yy]$ ]]; then | |
| kubectl delete pod -n "$CURRENT_NS" "$pod" | |
| read -p "Press Enter to continue..." | |
| return # Go back to pod list refresh | |
| fi | |
| ;; | |
| "Back") | |
| # Do nothing, loop repeats to pod list | |
| ;; | |
| esac | |
| done | |
| } | |
| function select_deployment() { | |
| echo "Fetching deployments..." | |
| local deploy_list=($(kubectl get deploy -n "$CURRENT_NS" --no-headers -o custom-columns=":metadata.name")) | |
| if [ ${#deploy_list[@]} -eq 0 ]; then | |
| echo -e "${RED}No deployments found in $CURRENT_NS${NC}" | |
| read -p "Press Enter to continue..." | |
| return | |
| fi | |
| deploy_list+=("Back") | |
| while true; do | |
| menu_select "Select Deployment" "${deploy_list[@]}" | |
| local deploy="$SELECTED_VALUE" | |
| if [[ "$deploy" == "Back" ]]; then return; fi | |
| local actions=("Describe" "Scale" "Back") | |
| menu_select "Action for Deployment: $deploy" "${actions[@]}" | |
| case "$SELECTED_VALUE" in | |
| "Describe") | |
| clear | |
| kubectl describe deploy -n "$CURRENT_NS" "$deploy" | less | |
| ;; | |
| "Scale") | |
| echo -ne "Enter new replica count: " | |
| read -r replicas | |
| if [[ "$replicas" =~ ^[0-9]+$ ]]; then | |
| kubectl scale deploy -n "$CURRENT_NS" "$deploy" --replicas="$replicas" | |
| read -p "Press Enter..." | |
| else | |
| echo "Invalid number." | |
| read -p "Press Enter..." | |
| fi | |
| ;; | |
| esac | |
| done | |
| } | |
| # Main Loop | |
| while true; do | |
| change_ns_opt="Change Namespace ($CURRENT_NS)" | |
| options=("$change_ns_opt" "Get Pods" "Get Deployments" "Exit") | |
| menu_select "Main Menu" "${options[@]}" | |
| case "$SELECTED_VALUE" in | |
| "$change_ns_opt") | |
| select_namespace | |
| ;; | |
| "Get Pods") | |
| select_pod | |
| ;; | |
| "Get Deployments") | |
| select_deployment | |
| ;; | |
| "Exit") | |
| printf '\033[2J\033[H' | |
| echo -e "${GREEN}Goodbye!${NC}" | |
| exit 0 | |
| ;; | |
| esac | |
| done |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment