#!/bin/bash # This script uses Kubernetes CertificateSigningRequest (CSR) to generate a # certificate signed by the Kubernetes CA itself. # It requires cluster admin permission. # # e.g.: ./create-user-openshift.sh alice oil # where `oil` is the Tenant and `alice` the owner # Exit immediately if a command exits with a non-zero status. set -e # Check if OpenSSL is installed if [[ ! -x "$(command -v openssl)" ]]; then echo "Error: openssl not found" exit 1 fi # Check if kubectl is installed if [[ ! -x "$(command -v kubectl)" ]]; then echo "Error: kubectl not found" exit 1 fi # Check if oc is installed if [[ ! -x "$(command -v oc)" ]]; then echo "Error: kubectl not found" exit 1 fi USER=$1 TENANT=$2 GROUP=$3 if [[ -z ${USER} ]]; then echo "User has not been specified!" exit 1 fi if [[ -z ${TENANT} ]]; then echo "Tenant has not been specified!" exit 1 fi if [[ -z ${GROUP} ]]; then GROUP=projectcapsule.dev fi TMPDIR=$(mktemp -d) echo "creating certs in TMPDIR ${TMPDIR} " MERGED_GROUPS=$(echo "/O=$GROUP" | sed "s/,/\/O=/g") echo "merging groups ${MERGED_GROUPS}" openssl genrsa -out ${TMPDIR}/tls.key 2048 openssl req -new -key ${TMPDIR}/tls.key -subj "/CN=${USER}${MERGED_GROUPS}" -out ${TMPDIR}/${USER}-${TENANT}.csr # Clean any previously created CSR for the same user. kubectl delete csr ${USER}-${TENANT} 2>/dev/null || true # # Create a new CSR file. # if [ $(kubectl version -o json | jq -r .serverVersion.minor) -gt 19 ]; then cat < ${TMPDIR}/${USER}-${TENANT}-csr.yaml apiVersion: certificates.k8s.io/v1 kind: CertificateSigningRequest metadata: name: ${USER}-${TENANT} spec: signerName: kubernetes.io/kube-apiserver-client groups: - system:authenticated request: $(cat ${TMPDIR}/${USER}-${TENANT}.csr | base64 | tr -d '\n') usages: - digital signature - key encipherment - client auth EOF else cat < ${TMPDIR}/${USER}-${TENANT}-csr.yaml apiVersion: certificates.k8s.io/v1beta1 kind: CertificateSigningRequest metadata: name: ${USER}-${TENANT} spec: groups: - system:authenticated request: $(cat ${TMPDIR}/${USER}-${TENANT}.csr | base64 | tr -d '\n') usages: - digital signature - key encipherment - client auth EOF fi # Create the CSR kubectl apply -f ${TMPDIR}/${USER}-${TENANT}-csr.yaml # Approve and fetch the signed certificate # In OCP why must use oc adm certificate approve oc adm certificate approve ${USER}-${TENANT} kubectl get csr ${USER}-${TENANT} -o jsonpath='{.status.certificate}' | base64 --decode > ${TMPDIR}/tls.crt # Create the kubeconfig file CONTEXT=$(kubectl config current-context) CLUSTER=$(kubectl config view -o jsonpath="{.contexts[?(@.name == \"$CONTEXT\"})].context.cluster}") SERVER=$(kubectl config view -o jsonpath="{.clusters[?(@.name == \"${CLUSTER}\"})].cluster.server}") #create context for the new user: oc config set-credentials ${USER} --client-certificate=${TMPDIR}/tls.crt --client-key=${TMPDIR}/tls.key --embed-certs --kubeconfig=${USER}-${TENANT}.kubeconfig #set current context for new user oc config set-context ${USER} --cluster=$(oc config view -o jsonpath='{.clusters[0].name}') --namespace=default --user=${USER} --kubeconfig=${USER}-${TENANT}.kubeconfig echo "kubeconfig file is:" ${USER}-${TENANT}.kubeconfig echo "to use it as ${USER}: 'oc config use-context ${USER} --kubeconfig=${USER}-${TENANT}.kubeconfig'"