Last active
November 13, 2024 20:34
-
-
Save rleap-m/5b26df8750a80cc4f43e8fafc9042db5 to your computer and use it in GitHub Desktop.
Creates kubeconfig files for MKE (Mirantis Kubernetes Engine) admin users based on their clusterrolebinding to the 'cluster-admin' role
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 | |
show_help() { | |
echo "Usage: $0 [--expires-in-days <days> | -e <days>] [--output-dir <directory> | -o <directory>] [-h|--help]" | |
echo "" | |
echo "Purpose: This script creates kubeconfig files for MKE (Mirantis Kubernetes Engine) admin users" | |
echo " based on their clusterrolebinding to the 'cluster-admin' role." | |
echo "" | |
echo "Options:" | |
echo " -h, --help Show this help message" | |
echo " -e, --expires-in-days Set the expiration time in days for the certificates (default: 7)" | |
echo " -o, --output-dir Set the output directory for kubeconfig files (default: current directory)" | |
echo "" | |
echo "Requirements:" | |
echo " - KUBECONFIG environment variable should be set to the MKE cluster 'admin' user." | |
echo " - Required binaries: kubectl, openssl, jq" | |
exit 0 | |
} | |
# Check for required binaries | |
for cmd in openssl kubectl jq; do | |
if ! command -v $cmd &> /dev/null; then | |
echo "Error: $cmd is required but not installed. Please install it and try again." | |
exit 1 | |
fi | |
done | |
if [ -z "$KUBECONFIG" ]; then | |
echo "Warning: KUBECONFIG is not set. This may cause kubectl commands to fail." | |
echo "Please ensure that KUBECONFIG points to your Kubernetes config file." | |
exit 1 | |
fi | |
# Default expiration time in days and output directory | |
DEFAULT_EXPIRES_IN_DAYS=7 | |
DEFAULT_OUTPUT_DIR="." | |
# Parse the input arguments | |
while [[ $# -gt 0 ]]; do | |
case $1 in | |
-h|--help) | |
show_help | |
;; | |
-e|--expires-in-days) | |
# Ensure the expiration days are valid | |
if [[ "$2" =~ ^[0-9]+$ ]] && [ "$2" -ge 1 ] && [ "$2" -le 365 ]; then | |
EXPIRES_IN_DAYS="$2" | |
else | |
echo "Invalid value for --expires-in-days. Must be between 1 and 365. Using default value of $DEFAULT_EXPIRES_IN_DAYS days." | |
EXPIRES_IN_DAYS=$DEFAULT_EXPIRES_IN_DAYS | |
fi | |
shift 2 | |
;; | |
-o|--output-dir) | |
OUTPUT_DIR="$2" | |
# Ensure the directory exists | |
if [[ ! -d "$OUTPUT_DIR" ]]; then | |
echo "Error: The directory $OUTPUT_DIR does not exist. Please provide a valid directory." | |
exit 1 | |
fi | |
# Remove trailing slash from OUTPUT_DIR if present | |
OUTPUT_DIR="${OUTPUT_DIR%/}" | |
shift 2 | |
;; | |
*) | |
echo "Usage: $0 [--expires-in-days <days> | -e <days>] [--output-dir <directory> | -o <directory>] [-h|--help]" | |
exit 1 | |
;; | |
esac | |
done | |
EXPIRES_IN_DAYS=${EXPIRES_IN_DAYS:-$DEFAULT_EXPIRES_IN_DAYS} | |
OUTPUT_DIR=${OUTPUT_DIR:-$DEFAULT_OUTPUT_DIR} | |
EXPIRES_IN_SECONDS=$((EXPIRES_IN_DAYS * 24 * 60 * 60)) | |
# Get the list of users with `cluster-admin` ClusterRoleBindings, excluding `mke-cluster-admin-admin` | |
USERNAMES=$(kubectl get clusterrolebindings -o json | jq -r '.items[] | select(.roleRef.name == "cluster-admin" and .subjects[]?.kind == "User" and .metadata.name != "mke-cluster-admin-admin") | .metadata.name') | |
if [ -z "$USERNAMES" ]; then | |
echo "No MKE admin users found for which to create kubeconfig files." | |
exit 0 | |
fi | |
# Loop through each username | |
for FULL_USERNAME in $USERNAMES; do | |
# Remove 'mke-cluster-admin-' prefix | |
USERNAME="${FULL_USERNAME#mke-cluster-admin-}" | |
echo "Creating kubeconfig for user: $USERNAME" | |
openssl genrsa -out "$OUTPUT_DIR/$USERNAME.key" 2048 | |
openssl req -new -key "$OUTPUT_DIR/$USERNAME.key" -out "$OUTPUT_DIR/$USERNAME.csr" -subj "/CN=$USERNAME" | |
# Read the CSR content into a variable without newlines | |
CSR_CONTENT=$(base64 -w0 < "$OUTPUT_DIR/$USERNAME.csr") | |
CSR_NAME="${USERNAME}-csr-$(openssl rand -hex 5)" # Using openssl to generate a random hex string | |
cat <<EOF | envsubst | kubectl apply -f - | |
apiVersion: certificates.k8s.io/v1 | |
kind: CertificateSigningRequest | |
metadata: | |
name: $CSR_NAME | |
spec: | |
request: $CSR_CONTENT | |
signerName: kubernetes.io/kube-apiserver-client | |
expirationSeconds: $EXPIRES_IN_SECONDS | |
usages: | |
- client auth | |
EOF | |
kubectl certificate approve "$CSR_NAME" | |
kubectl get csr "$CSR_NAME" -o jsonpath='{.status.certificate}' | base64 --decode > "$OUTPUT_DIR/$USERNAME.crt" | |
kubectl config view --minify --flatten > "$OUTPUT_DIR/$USERNAME.kubeconfig" | |
kubectl config unset users --kubeconfig="$OUTPUT_DIR/$USERNAME.kubeconfig" > /dev/null | |
kubectl config unset contexts --kubeconfig="$OUTPUT_DIR/$USERNAME.kubeconfig" > /dev/null | |
kubectl config set-credentials "$USERNAME" --client-certificate="$OUTPUT_DIR/$USERNAME.crt" --client-key="$OUTPUT_DIR/$USERNAME.key" --embed-certs=true --kubeconfig="$OUTPUT_DIR/$USERNAME.kubeconfig" | |
kubectl config set-context "mke-$USERNAME" --cluster=mke --user="$USERNAME" --kubeconfig="$OUTPUT_DIR/$USERNAME.kubeconfig" | |
kubectl config use-context "mke-$USERNAME" --kubeconfig="$OUTPUT_DIR/$USERNAME.kubeconfig" | |
# Cleanup temporary files | |
rm "$OUTPUT_DIR/$USERNAME.crt" "$OUTPUT_DIR/$USERNAME.csr" "$OUTPUT_DIR/$USERNAME.key" | |
echo "Kubeconfig for $USERNAME created as $OUTPUT_DIR/$USERNAME.kubeconfig" | |
done |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment