Skip to content

Instantly share code, notes, and snippets.

@btamayo
Last active June 18, 2022 09:47
Show Gist options
  • Save btamayo/d6fc8088752c3548b073984347f182ce to your computer and use it in GitHub Desktop.
Save btamayo/d6fc8088752c3548b073984347f182ce to your computer and use it in GitHub Desktop.
Exec into the latest pod. works most of the time, forgot to implement search I think. It's been a while since i've needed this.
# Load colors, use like this:
# autoload colors; colors
# echo $fg[green]text$reset_color
autoload -U colors; colors
for COLOR in RED GREEN YELLOW BLUE MAGENTA CYAN BLACK WHITE; do
eval $COLOR='%{$fg_no_bold[${(L)COLOR}]%}' #wrap colours between %{ %} to avoid weird gaps in autocomplete
eval BOLD_$COLOR='%{$fg_bold[${(L)COLOR}]%}'
done
eval RESET='%{$reset_color%}'
kube_exec_pod_hint() {
echo ""
echo " $emoji[electric_light_bulb] Tip! Use \`kube_exec_pod\` to exec into a pod more easily"
echo ""
}
__k_exec_pod_usage() {
# Since we can't use $0 here (since that will print the name of the function), we pass in the name instead
# this way we don't have to do find-and-replaces
command_name="$1"
echo "$1: Attaches a tty to a pod. Convenience over 'kubectl exec'"
echo ""
echo " Usage: $1 <pod_name> [container_name] [exec_command]"
echo ""
echo " Options:"
echo " pod_name (required): Name of pod to exec into."
echo " container_name: Container to exec into. Use if pod has more than 1 container."
echo " exec_command: Command to run in the pod/container. [Default: /bin/bash]"
}
# Useful kubectl+JQ: https://gist.github.com/so0k/42313dbb3b547a0f51a547bb968696ba
# Kubectl ref: https://kubernetes.io/docs/reference/generated/kubectl/kubectl-commands
# Jq cheatsheets: https://gist.github.com/olih/f7437fb6962fb3ee9fe95bda8d2c8fa4
# https://earthly.dev/blog/jq-select/
# https://remysharp.com/drafts/jq-recipes
# Filter for arbitrary most recent RUNNING pod by creationTimestamp
# This selects a random pod from multiple replicas if they're all deployed at the same time
__get_most_recent_podname() {
local all_pods_filter=".items | sort_by(.metadata.creationTimestamp) | reverse | .[0] | del(.metadata.managedFields, .spec, .status) | .metadata.name"
local podname_filter=".items | map(select(.metadata.name | startswith(\""$1"\"))) | sort_by(.metadata.creationTimestamp) | reverse | .[0] | del(.metadata.managedFields, .spec, .status) | .metadata.name"
if [ -z "$1" ]; then
local pod=$(kubectl get pods -o json --field-selector=status.phase==Running | jq --raw-output $all_pods_filter)
else
local pod=$(kubectl get pods -o json --field-selector=status.phase==Running | jq --raw-output $podname_filter)
fi
# This is the 'return' - don't print anything before this or it will be used as the return
echo $pod
}
__get_nonexistent_pod() {
kubectl get pod pod_name_sdfskfjhsd
}
__print_warn_with_prefix() {
# #1 = Prefix
# $2 = Error message
# https://unix.stackexchange.com/questions/579773/difference-between-fcolor-and-fgcolor-in-zsh-promptm
# https://stackoverflow.com/a/2534676/1354493
# https://stackoverflow.com/questions/16562123/zsh-trouble-when-using-echo-with-color-formatting-characters
# https://unix.stackexchange.com/a/92576
# It's a bit weird to use this, because `fg` is a command generally. BUT in zsh with autocolors loaded, it's actually a map of colors that's globally accessible.
printf "%s$fg[yellow]WARN:$fg[default] %s\n" "$1" "$2"
}
__print_success_with_prefix() {
# #1 = Prefix
# $2 = Error message
# https://unix.stackexchange.com/questions/579773/difference-between-fcolor-and-fgcolor-in-zsh-promptm
# https://stackoverflow.com/a/2534676/1354493
# https://stackoverflow.com/questions/16562123/zsh-trouble-when-using-echo-with-color-formatting-characters
# https://unix.stackexchange.com/a/92576
# It's a bit weird to use this, because `fg` is a command generally. BUT in zsh with autocolors loaded, it's actually a map of colors that's globally accessible.
printf "%s$fg[green]ERROR:$fg[default] %s\n" "$1" "$2"
}
__print_error_with_prefix() {
# #1 = Prefix
# $2 = Error message
# https://unix.stackexchange.com/questions/579773/difference-between-fcolor-and-fgcolor-in-zsh-promptm
# https://stackoverflow.com/a/2534676/1354493
# https://stackoverflow.com/questions/16562123/zsh-trouble-when-using-echo-with-color-formatting-characters
# https://unix.stackexchange.com/a/92576
# It's a bit weird to use this, because `fg` is a command generally. BUT in zsh with autocolors loaded, it's actually a map of colors that's globally accessible.
printf "%s$fg[red]ERROR:$fg[default] %s\n" "$1" "$2"
}
kube_exec_pod() {
local pod_name=$1
local container_name=$2
local exec_command=${3:-/bin/bash}
echo " pod_name: $pod_name"
echo " container_name: $container_name"
echo " exec_command: $exec_command"
if [ ! -z "$pod_name" ]; then
# Container name not provided
if [[ -z "$container_name" ]] || [[ ! -n "$container_name" ]]; then
# Kubectl doesn't always let you save all outputs
# Optimistically try to exec into the pod
kubectl exec $pod_name --tty --stdin -- $exec_command
# If an error code is thrown, assume that
# it's because the pod wasn't found. Try to find a pod with the correct name.
if [ $? -ne 0 ]; then
__print_error_with_prefix "" "$0: Pod exec to $fg_bold[default]$pod_name$reset_color failed. Maybe the pod doesn't exist?"
pod_name=$(__get_most_recent_podname "$1")
echo "Attempting to use pod: $fg_bold[default]$pod_name$reset_color"
kubectl exec $pod_name --tty --stdin -- $exec_command
# If it still doesn't work, then:
if [ $? -ne 0 ]; then
echo ""
echo "List of pods:"
kubectl get pods
fi
fi
return $?
else
# Container name provided
kubectl exec $pod_name -c $container_name --tty -stdin -- $exec_command
return $?
fi
else
echo ""
echo "ERROR: Missing required argument: pod_name"
echo ""
__k_exec_pod_usage "$0"
echo ""
echo "List of pods:"
k get pods
return 1
fi
set +x
}
# This works because I alias k to kubectl but first pass it through here
k() {
local command=$1
if [[ "$command" = "exec" ]]; then
kube_exec_pod_hint
shift 1
kubectl exec "$@"
elif [[ -z "$1" ]]; then
kubectl
else
kubectl "$@"
fi
}
@btamayo
Copy link
Author

btamayo commented Jun 17, 2022

I tested this on macOS using zsh. I think some of the options might not be implemented but I don't need this anymore all the time so I may not remember. I also use .oh-my-zsh jic that does something.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment