Skip to content

Instantly share code, notes, and snippets.

@rleap-m
Last active November 13, 2024 20:34
Show Gist options
  • Save rleap-m/5b26df8750a80cc4f43e8fafc9042db5 to your computer and use it in GitHub Desktop.
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
#!/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