Skip to content

Instantly share code, notes, and snippets.

@noizo
Last active January 29, 2026 14:55
Show Gist options
  • Select an option

  • Save noizo/997adc0a18cb7280f6eeb325c0034e4f to your computer and use it in GitHub Desktop.

Select an option

Save noizo/997adc0a18cb7280f6eeb325c0034e4f to your computer and use it in GitHub Desktop.
gk8 is a script to connect to gcloud and select a gke cluster context with a namespace
# Add to .zshrc
# Run `source ~/.zshrc`
# Run gk8
# Select project
# Select cluster
# Select namespace
# Enjoy
gk8() {
emulate -L zsh
setopt local_options pipefail
# Requirements:
# - gcloud (Google Cloud SDK)
# - gke-gcloud-auth-plugin
# - kubectl
# - fzf
#
# Auth model:
# - kubeconfig uses an exec plugin (`gke-gcloud-auth-plugin`) instead of static tokens.
# - kubectl calls the plugin to mint short-lived access tokens.
# - tokens auto-refresh as long as `gcloud auth list` shows an ACTIVE account.
# - you only need `gcloud container clusters get-credentials` when the context is missing
# (or if cluster endpoint/CA changes). Use `gk8 -r` to force a refresh.
local -a req_cmds
req_cmds=(fzf gcloud kubectl gke-gcloud-auth-plugin)
local c
for c in "${req_cmds[@]}"; do
command -v "$c" >/dev/null 2>&1 || {
echo "Missing required command: $c" >&2
echo "Install requirements (macOS/Homebrew example):" >&2
echo " brew install fzf kubectl google-cloud-sdk" >&2
echo " gcloud components install gke-gcloud-auth-plugin" >&2
return 1
}
done
export USE_GKE_GCLOUD_AUTH_PLUGIN=True
local force_refresh=false
local skip_namespace=false
local kubeconfig="${KUBECONFIG:-$HOME/.kube/config}"
while getopts ":rn" opt; do
case ${opt} in
r) force_refresh=true ;;
n) skip_namespace=true ;;
\?) echo "Usage: gk8 [-r] [-n]"; return 1 ;;
esac
done
shift $((OPTIND - 1))
# --- Ensure gcloud is authenticated ---
local acct
acct="$(gcloud auth list --filter="status:ACTIVE" --format="value(account)" 2>/dev/null | head -n1)"
[[ -z "$acct" ]] && { gcloud auth login || { echo "gcloud auth login failed" >&2; return 1; }; }
# --- Pick project ---
local proj_list project
if [[ -n "${GKE_ALLOWED_PROJECTS:-}" ]]; then
proj_list="$(printf "%s\n" ${=GKE_ALLOWED_PROJECTS})"
else
proj_list="$(gcloud projects list --format="value(projectId)" 2>/dev/null)"
fi
[[ -z "$proj_list" ]] && { echo "No GCP projects visible" >&2; return 1; }
project="$(printf "%s\n" "$proj_list" | fzf --select-1 --exit-0 --no-multi --height=60% --border --prompt="GCP project> " || true)"
[[ -z "$project" ]] && { echo "No project selected"; return 1; }
# Clean project string of whitespace and carriage returns
setopt extended_glob
project="${project//$'\r'/}"
project="${project##[[:space:]]#}"
project="${project%%[[:space:]]#}"
# --- Pick cluster in that project ---
local cmd_out cmd_rc rows sel cluster location loc_flag
cmd_out="$(gcloud container clusters list --project "$project" --format="value(name,location)" 2>&1)"
cmd_rc=$?
if [[ $cmd_rc -ne 0 ]]; then
echo "gcloud container clusters list failed for project [$project] (rc=$cmd_rc):" >&2
printf "%s\n" "$cmd_out" >&2
return 1
fi
rows="$cmd_out"
[[ -z "$rows" ]] && { echo "No GKE clusters visible in project [$project]" >&2; return 1; }
sel="$(printf "%s\n" "$rows" | fzf --select-1 --exit-0 --no-multi --height=60% --border --prompt="GKE cluster> " || true)"
[[ -z "$sel" ]] && { echo "No cluster selected"; return 1; }
cluster="${sel%%$'\t'*}"
location="${sel#*$'\t'}"
[[ "$location" == "$sel" ]] && { echo "Parse failed (expected tab-delimited name/location): [$sel]" >&2; return 1; }
[[ -z "$cluster" || -z "$location" ]] && { echo "Parse failed: [$sel]" >&2; return 1; }
if [[ "$location" == *-*-* ]]; then
loc_flag="--zone=$location"
else
loc_flag="--region=$location"
fi
local ctx="gke_${project}_${location}_${cluster}"
# --- Decide whether to run get-credentials ---
local need_creds=false
if ! kubectl config get-contexts -o name 2>/dev/null | grep -qx "$ctx"; then
need_creds=true
else
local cfg
cfg="$(kubectl config view --raw --minify --context "$ctx" -o json 2>/dev/null || true)"
if [[ -z "$cfg" ]]; then
need_creds=true
else
printf "%s" "$cfg" | grep -q '"auth-provider"' && need_creds=true
printf "%s" "$cfg" | grep -q 'gke-gcloud-auth-plugin' || need_creds=true
fi
fi
[[ "$force_refresh" == true ]] && need_creds=true
if [[ "$need_creds" == true ]]; then
KUBECONFIG="$kubeconfig" gcloud container clusters get-credentials \
"$cluster" --project "$project" $loc_flag >/dev/null \
|| { echo "get-credentials failed" >&2; return 1; }
fi
kubectl config use-context "$ctx" >/dev/null 2>&1 || true
echo "Context: $ctx KUBECONFIG: $kubeconfig"
# --- Namespace picker ---
if [[ "$skip_namespace" == false ]]; then
local ns
ns="$(
kubectl get ns -o jsonpath='{range .items[*]}{.metadata.name}{"\n"}{end}' 2>/dev/null \
| fzf --select-1 --exit-0 --no-multi --height=60% --border --prompt="NS> " \
|| true
)"
[[ -z "$ns" ]] && { echo "No namespace selected"; return 0; }
kubectl config set-context --current --namespace="$ns" >/dev/null || return 1
echo "Namespace: $ns"
else
echo "Skipping namespace selection."
fi
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment