Kubernetes cluster configuration merger
/kubeconfig/add-kubeconfig.sh
If you tend to work with lots of Kubernetes clusters, you’ll probably have
a ~/.kube/config
file full of cluster configurations, users and contexts. Then
you provision a new cluster, you get your shiny new cluster configuration file
and then you have to copy over those entries to your main config file.
This script does that automatically. You just provide the name of the new
context you want to create for this configuration and it takes care of adding
the entries to your kubectl
config file.
The name of the new context is the only mandatory argument. Then you can pass up to two additional arguments:
- The name of the configuration file that you want to copy to your main config
file. Default:
admin.conf
because that’s what I mostly get. - The name of the destination
kubectl
config file. I decided to add this third argument just in case you have your config file elsewhere or you want to do some testing. Default:~/.kube/config
.
Finally, for editing and merging the YAML entries, this script makes use of the
yq
tool from Mike Farah. You must download the single binary from the
releases page in GitHub and put it somewhere in your $PATH
. Don’t confuse
it with the yq
Python package: that’s just a wrapper around jq
and works in
a completely different way.
Download
this script
Secondary click/Save as…
#!/usr/bin/env bash
#
# add-kubeconfig.sh
# Copyright 2020 eth0 <ethernet.zero@gmail.com>
#
# This work is free. You can redistribute it and/or modify it under the terms of
# the ISC License.
#
yq="$(command -v yq)"
if [[ -z "$yq" ]]; then
echo "$0: you need the yq tool, download it from https://github.com/mikefarah/yq/releases" >&2
exit 1
fi
if [[ ! "$1" ]]; then
echo "$0: you must specify a context name" >&2
exit 1
fi
context_name="$1"
kcfile="${2-admin.conf}"
kubeconfig=${3-~/.kube/config}
if [[ ! -f "$kcfile" ]]; then
echo "$0: missing cluster config file" >&2
exit 1
fi
if [[ ! -f "$kubeconfig" ]]; then
mkdir -p "$(cd "$(dirname "$kubeconfig")"; pwd)"
fi
kctemp="$(< "$kcfile")"
# First, clean the cluster config file
if [[ -f "$kubeconfig" ]]; then
kctemp="$("$yq" eval "del(.[\"apiVersion\", \"current-context\", \"kind\", \"preferences\"])" - <<< "$kctemp")"
fi
# Set the context name for all entries
kcexpr="$(printf '"%s" as $contextname |\n' "$context_name"; cat <<-'EOF'
. * {
"contexts": [.contexts[] | (.context | (.cluster,.user),.name) |= $contextname],
"users": [.users[] | .name |= $contextname],
"clusters": [.clusters[] | .name |= $contextname]
}
EOF
)"
kctemp="$("$yq" eval "$kcexpr" - <<< "$kctemp")"
# Then, merge the cleaned config to the kubeconfig file
if [[ -f "$kubeconfig" ]]; then
kcexpr="$(printf '"%s" as $contextname |\n' "$context_name"; cat <<-'EOF'
(
select(fileIndex == 0) |
del(.["contexts", "users", "clusters"][] | select(.name == $contextname))
) *+d select(fileIndex == 1)
EOF
)"
"$yq" -i eval-all "$kcexpr" "$kubeconfig" - <<< "$kctemp"
else
cat > "$kubeconfig" <<< "$kctemp"
fi