Skip to content

Instantly share code, notes, and snippets.

@johnybradshaw
Last active May 29, 2024 18:11
Show Gist options
  • Save johnybradshaw/2dd1d5e2823abcd84eb3228d4794bfcf to your computer and use it in GitHub Desktop.
Save johnybradshaw/2dd1d5e2823abcd84eb3228d4794bfcf to your computer and use it in GitHub Desktop.
Automatically download LKE kubeconfigs and appends/replaces them to the ~/.kube/config files
#!/bin/bash
# Description:
# This script retrieves the kubeconfig files for all Linode Kubernetes Engine (LKE) clusters
# associated with the user's Linode account and merges them into a single kubeconfig file.
# The resulting kubeconfig file is saved as ~/.kube/config.
#
# Usage:
# ./lke_kubeconfig_merge.sh [--debug] [--op]
#
# Options:
# --debug Enable debug mode to print additional information during script execution.
# --op Use 1Password CLI (op) to retrieve the Linode CLI token.
#
# Requirements:
# - linode-cli: Linode CLI tool for interacting with Linode API.
# - jq: Command-line JSON processor for parsing JSON output.
# - kubectl: Kubernetes command-line tool for interacting with Kubernetes clusters.
# - 1Password CLI (op): Optional, required if --op flag is used.
#
# Configuration:
# - LINODE_CLI_TOKEN: Environment variable containing the Linode CLI token.
# If --op flag is used, the token is retrieved from 1Password using the specified path.
#
# Script Flow:
# 1. Parse command-line options (--debug and --op).
# 2. Check if required dependencies (linode-cli, jq, kubectl) are installed.
# 3. Create the ~/.kube directory if it doesn't exist.
# 4. Initialize an empty kubeconfig file if ~/.kube/config doesn't exist.
# 5. Retrieve the list of LKE cluster IDs associated with the user's Linode account.
# 6. Create a temporary directory for storing individual kubeconfig files.
# 7. Iterate through each cluster ID:
# - Retrieve the cluster details (name and region) using linode-cli.
# - Check if the cluster is already present in the kubeconfig file.
# - If the cluster is not present, retrieve its kubeconfig and save it as a temporary file.
# - Update the context and user names in the temporary kubeconfig file.
# - Append the temporary kubeconfig file path to the KUBECONFIG environment variable.
# 8. Merge all the kubeconfig files using kubectl and the KUBECONFIG environment variable.
# 9. Save the merged kubeconfig to ~/.kube/config.
# 10. Clean up the temporary directory.
#
# Note:
# - The script requires the Linode CLI token to be set in the LINODE_CLI_TOKEN environment variable
# or retrieved from 1Password using the --op flag.
# - The script uses the KUBECONFIG environment variable to specify multiple kubeconfig files for merging.
# - The script checks if a cluster is already present in the kubeconfig file to avoid duplicates.
# - Debug mode (--debug) can be enabled to print additional information during script execution.
# Set color variables
RED=$(tput setaf 1)
GREEN=$(tput setaf 2)
YELLOW=$(tput setaf 3)
BLUE=$(tput setaf 4)
CYAN=$(tput setaf 6)
RESET=$(tput sgr0)
# Function to print debug messages
debug() {
if [ "$DEBUG" = true ]; then
echo "DEBUG: $1"
fi
}
# Parse command line options
DEBUG=false
USE_OP=false
while [[ $# -gt 0 ]]; do
case "$1" in
--debug)
DEBUG=true
debug "Debug mode enabled"
shift
;;
--op)
USE_OP=true
debug "Using op to invoke linode-cli"
shift
;;
*)
echo "Invalid option: $1" 1>&2
exit 1
;;
esac
done
# Function to invoke linode-cli
invoke_linode_cli() {
if [ "$USE_OP" = true ]; then
LINODE_CLI_TOKEN_VALUE=$(op read "$LINODE_CLI_TOKEN")
LINODE_CLI_TOKEN="$LINODE_CLI_TOKEN_VALUE" linode-cli "$@"
else
linode-cli "$@"
fi
# Check if the command was successful
if [ $? -ne 0 ]; then
echo "${RED}Error:${RESET} Failed to invoke linode-cli command."
exit 1
fi
}
# Check if required dependencies are installed
dependencies=("linode-cli" "jq" "kubectl")
for dependency in "${dependencies[@]}"; do
if ! command -v "$dependency" >/dev/null 2>&1; then
echo "${RED}Error:${RESET} $dependency is not installed. Please install it and try again."
exit 1
fi
done
debug "Dependencies checked"
# Create the .kube directory if it doesn't exist
mkdir -p ~/.kube
# Initialize an empty kubeconfig file if it doesn't exist
if [ ! -f ~/.kube/config ]; then
echo "apiVersion: v1
kind: Config
clusters: []
contexts: []
users: []
current-context: \"\"" > ~/.kube/config
debug "Empty kubeconfig file created"
else
debug "Existing kubeconfig file found"
fi
# Get the list of cluster IDs
cluster_ids=$(invoke_linode_cli --json lke clusters-list | jq -r '.[].id' 2>/dev/null)
if [ $? -ne 0 ]; then
echo -e "${RED}Error:${RESET} Failed to retrieve cluster IDs. Please check your Linode CLI token (${CYAN}\$LINODE_CLI_TOKEN${RESET}) and try again."
exit 1
fi
debug "Cluster IDs: $cluster_ids"
# Initialize the KUBECONFIG variable with the existing kubeconfig file
KUBECONFIG="$HOME/.kube/config"
# Create a temporary directory for storing kubeconfig files
temp_dir=$(mktemp -d)
# Iterate through each cluster ID
for cluster_id in $cluster_ids; do
debug "Processing cluster ID: $cluster_id"
# Get the cluster details
cluster_details=$(invoke_linode_cli --json lke cluster-view "$cluster_id")
debug "Cluster details: $cluster_details"
# Extract the cluster name and region
cluster_name=$(echo "$cluster_details" | jq -r '.[].label')
cluster_region=$(echo "$cluster_details" | jq -r '.[].region')
debug "Cluster name: $cluster_name"
debug "Cluster region: $cluster_region"
# Check if the cluster already exists in the kubeconfig
if kubectl config get-contexts | grep -q "$cluster_name"; then
echo "Cluster $cluster_name already exists in the kubeconfig. Skipping..."
debug "Cluster $cluster_name already exists in the kubeconfig"
else
# Create a temporary kubeconfig file for the cluster
temp_kubeconfig="$temp_dir/kubeconfig-$cluster_id"
invoke_linode_cli --json lke kubeconfig-view "$cluster_id" | jq -r '.[].kubeconfig | @base64d' > "$temp_kubeconfig"
# Update the context and user names in the temporary kubeconfig file
sed -i.bak "s/name: lke$cluster_id-ctx/name: $cluster_name/" "$temp_kubeconfig"
#sed -i.bak "s/user: lke$cluster_id-admin/user: $cluster_name-admin/" "$temp_kubeconfig"
KUBECONFIG="$KUBECONFIG:$temp_kubeconfig"
echo "Added cluster $cluster_name (Region: $cluster_region) to the KUBECONFIG"
debug "Cluster $cluster_name (Region: $cluster_region) added to the KUBECONFIG"
fi
done
# Merge the kubeconfig files using kubectl and the KUBECONFIG variable
KUBECONFIG="$KUBECONFIG" kubectl config view --flatten > ~/.kube/config.tmp
if [ $? -eq 0 ]; then
mv ~/.kube/config.tmp ~/.kube/config
chmod 600 ~/.kube/config
echo "${GREEN}Success:${RESET} Kubeconfig updated successfully"
else
echo "${RED}Error:${RESET} Failed to merge kubeconfig files."
rm -f ~/.kube/config.tmp
exit 1
fi
# Clean up the temporary directory
rm -rf "$temp_dir"
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment