Last active
June 19, 2024 01:06
-
-
Save bitti/1ea6d80ecfa8872cef0fc8e5452cc62c to your computer and use it in GitHub Desktop.
kubectl plugin/wrapper to match kubectl binary version to current cluster version
This file contains 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 | |
set -e | |
cache=${XDG_CACHE_HOME:-$HOME/.cache}/kubectl-v | |
errors="$cache/errors-$$" | |
mkdir -p "$cache" | |
[[ $1 = "v" ]] && shift # Avoid recursive calls | |
get_sys() { | |
uname | tr '[:upper:]' '[:lower:]' | |
} | |
get_cpu() { | |
local -r machine_hardware_name=$(uname -m) | |
case "$machine_hardware_name" in | |
x86_64) echo amd64 ;; | |
powerpc64le|ppc64le) echo ppc64le ;; | |
aarch64) echo arm64 ;; | |
armv7l) echo arm ;; | |
*) echo "$machine_hardware_name" ;; | |
esac | |
} | |
fetch_kubectl() { | |
[[ -x $2 ]] && return | |
echo "Download kubectl $1" | |
local sys cpu | |
sys=$(get_sys) | |
cpu=$(get_cpu) | |
# ARM binaries not available before 1.20.0 | |
if [[ $sys = "darwin" && $cpu = "arm64" && $(semver compare $1 v1.20.0) = -1 ]]; then | |
cpu="amd64" | |
fi | |
curl -L "https://storage.googleapis.com/kubernetes-release/release/$1/bin/${sys}/${cpu}/kubectl" -o "$2" | |
chmod +x "$2" | |
} | |
link_kubectl() { | |
ln -sf "$(basename "$1")" "$cache/$(basename "$2")" | |
} | |
fetch_kubectl_latest() { | |
kubectl_latest="$cache/kubectl-latest" | |
[[ -x $kubectl_latest ]] && return | |
local -r stable_version=$(curl -s https://storage.googleapis.com/kubernetes-release/release/stable.txt) | |
local -r kubectl_stable="$cache/kubectl-${stable_version}" | |
fetch_kubectl "$stable_version" "$kubectl_stable" | |
link_kubectl "$kubectl_stable" "$kubectl_latest" | |
} | |
current_cluster_name() { | |
kubectl_cluster="$cache/kubectl-$($kubectl_default config view --minify -o jsonpath='{.clusters[].name}')" | |
echo ${cluster_name/*\//} # Remove path prefixes (i.e. from arn URIs) | |
} | |
kubectl_path_for_current_cluster() { | |
cluster_name=$($kubectl_default config view --minify -o jsonpath='{.clusters[].name}') | |
cluster_name=${cluster_name/*\//} # Remove path prefixes (i.e. from arn URIs) | |
echo "$cache/kubectl-$cluster_name" | |
} | |
fetch_kubectl_current() { | |
kubectl_path=$(kubectl_path_for_current_cluster) | |
[[ -x $kubectl_path ]] && return | |
local current_version | |
current_version=$($kubectl_default version --output=yaml 2> >(grep -v "version difference" >&2)) | |
current_version=${current_version/*gitVersion: } # Remove preamble | |
current_version=${current_version%%-*} # Remove suffixes | |
kubectl_current="$cache/kubectl-$current_version" | |
fetch_kubectl "$current_version" "$kubectl_current" | |
link_kubectl "$kubectl_current" "$kubectl_path" | |
} | |
kubectl_default=${HOMEBREW_PREFIX:-/opt/homebrew}/bin/kubectl | |
[[ -x $kubectl_default ]] || { fetch_kubectl_latest && kubectl_default=$kubectl_latest; } | |
if [[ $1 = "config" ]]; then | |
$kubectl_default "$@" | |
else | |
if [[ $1 = "update" ]]; then | |
kubectl_path=$(kubectl_path_for_current_cluster) | |
rm $kubectl_path | |
echo "Updating kubectl for ${kubectl_path/*kubectl-/}..." | |
fetch_kubectl_current | |
$kubectl_path version | |
else | |
fetch_kubectl_current | |
$kubectl_path "$@" | |
fi | |
fi |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Setup
Put content into a file in
$PATH
, and make executable$ chmod +x kubectl-v
Usage
Use as a
kubectl
plugin by prefixing arguments withv
. E.g.$ kubectl v version
Or call
kubectl-v
in akubectl
wrapper script or aliasGotchas
--context
argument is ignored to determine the cluster version, only the current-context is consideredkubectl
binaries beforev1.13.0
are not compatible with macOS Montery. You need to use special builds with updated Golang-libs for these