Last active
September 21, 2024 05:40
-
-
Save naingyeminn/24160831a1965c69e683c094e9975ae4 to your computer and use it in GitHub Desktop.
Generate kubeconfig with user-based client certificate and assign role.
This file contains hidden or 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 | |
if [ -z "${1}" ]; then | |
echo "Please provide a username and the namespace or the username only for the cluster role..." | |
echo "Usage: ${0} USERNAME [NAMESPACE] [ROLE]" | |
echo "Example: ${0} auditor default view" | |
exit | |
fi | |
USERNAME=${1} | |
if [ -z ${2} ]; then | |
NAMESPACE=default | |
else | |
NAMESPACE=${2} | |
fi | |
CERT_NAME=${USERNAME}-${NAMESPACE} | |
CLUSTER_SERVER=$(kubectl config view --flatten --minify -o jsonpath='{.clusters[0].cluster.server}') | |
CLUSTER_NAME=$(kubectl config view --flatten --minify -o jsonpath='{.clusters[0].name}') | |
CA_CERT=$(kubectl config view --flatten --minify -o jsonpath='{.clusters[0].cluster.certificate-authority-data}') | |
echo "Removing old csr..." | |
kubectl get csr ${CERT_NAME} && kubectl delete csr ${CERT_NAME} | |
echo "Generating new key (${USERNAME}.key) and csr (${USERNAME}.csr)..." | |
openssl req -new -newkey rsa:4096 -keyout ${USERNAME}.key -out ${USERNAME}.csr -noenc -subj "/CN=${USERNAME}/O=${NAMESPACE}" | |
echo "Creating csr (${CERT_NAME}) in k8s..." | |
cat <<EOF | kubectl create -f - | |
apiVersion: certificates.k8s.io/v1 | |
kind: CertificateSigningRequest | |
metadata: | |
name: ${CERT_NAME} | |
spec: | |
groups: | |
- system:authenticated | |
request: $(cat ${USERNAME}.csr | base64 | tr -d '\n') | |
signerName: kubernetes.io/kube-apiserver-client | |
usages: | |
- digital signature | |
- key encipherment | |
- client auth | |
EOF | |
echo "Signing the csr (${CERT_NAME})..." | |
kubectl certificate approve ${CERT_NAME} | |
echo "Exporting the certificate (${CERT_NAME}.crt)..." | |
kubectl get csr $CERT_NAME -o jsonpath='{.status.certificate}' | base64 -d > ${CERT_NAME}.crt | |
echo "Generating the config for ${USERNAME} (${CERT_NAME}.kubeconfig)..." | |
cat <<EOF > ${CERT_NAME}.kubeconfig | |
apiVersion: v1 | |
clusters: | |
- cluster: | |
certificate-authority-data: ${CA_CERT} | |
server: ${CLUSTER_SERVER} | |
name: ${USERNAME}-${CLUSTER_NAME} | |
contexts: | |
- context: | |
cluster: ${USERNAME}-${CLUSTER_NAME} | |
namespace: ${NAMESPACE} | |
user: ${USERNAME} | |
name: ${CERT_NAME} | |
current-context: ${CERT_NAME} | |
kind: Config | |
users: | |
- name: ${USERNAME} | |
user: | |
client-certificate-data: $(base64 -w0 < ${CERT_NAME}.crt) | |
client-key-data: $(base64 -w0 < ${USERNAME}.key) | |
EOF | |
############################################################# | |
bind_role () { | |
ROLE_TYPE=`([ $(kubectl get role -o custom-columns=NAME:.metadata.name --no-headers -A | grep "^${1}$") ] && echo role) || ([ $(kubectl get clusterrole -o custom-columns=NAME:.metadata.name --no-headers | grep "^${1}$") ] && echo clusterrole)` | |
if [ -z "${ROLE_TYPE}" ]; then | |
echo "There is no Role/ClusterRole named ${1}" | |
exit | |
fi | |
RB_NAME=${NAMESPACE}-${1} | |
echo "Binding the ${USERNAME} user with the cluster ${1} role..." | |
kubectl -n ${NAMESPACE} get rolebinding ${RB_NAME} &> /dev/null | |
if [ $? -gt 0 ]; then | |
kubectl -n ${NAMESPACE} create rolebinding ${RB_NAME} --${ROLE_TYPE} ${1} --user ${USERNAME} | |
else | |
kubectl -n ${NAMESPACE} patch rolebinding ${RB_NAME} --type='json' -p='[{"op": "add", "path": "/subjects/0", "value": {"kind": "User", "name": "'${USERNAME}'" } }]' | |
fi | |
} | |
bind_role ${3} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment