Last active
May 29, 2024 18:11
-
-
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
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 | |
# 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