#!/bin/sh
export TEXTDOMAINDIR='/usr/share/locale'
export TEXTDOMAIN='podsec-k8s-rbac'

export PROGRAMM=$0
. podsec-k8s-rbac-functions

cmdname=$(basename $0)
if [ $# -lt 1 ]
then
  echo "$(gettext 'Format'):\n $PROGRAMM $(gettext 'user')[@<(gettext 'remote_user')>] [<(gettext 'group')1> ...]" >&2
  exit 1
fi
user=$1
shift
if [ $# -lt 1 ]
then
  set -- k8s
fi
groups=
for group
do
        groups="$groups/O=$group"
done

ifs=$IFS IFS=@
set -- $user
IFS=$ifs
remoteUser=
if [ $# -gt 1 ]
then  # rootless kuber
  user=$1
  remoteUser=$2
else
  remoteUser='u7s-admin'
fi

setEnv $user
setUserKubeconfigAccess
clusterName=$(getClusterName)

if [ ! -d $KUBECONFIGDIR ]
then
  echo "$KUBECONFIG $(gettext 'directory') $KUBECONFIGDIR $(gettext 'absent')" >&2
  exit 1
fi

if ! cd $KUBECONFIGDIR
then
  echo "$(gettext 'No rights to access the directory') $KUBECONFIGDIR" >&2
  exit 1
fi

# Создание личного (private) ключа
echo "$(gettext 'Creating a personal') (private) $(gettext 'key')" >&2
openssl genrsa -out $user.key 2048 >/dev/null 2>&1
if [ ! -s "$user.key" ]
then
  echo "$(gettext 'Private key file') '$user.key' $(gettext 'not created')" >&2
  exit 1
fi
echo "$(gettext 'Private key file') '$user.key' $(gettext 'created')" >&2

# Создание запроса на подпись сертификата (CSR)
echo -ne "$(gettext 'Creating a Certificate Signing Request') (CSR)..." >&2
openssl req -new -key $user.key -out $user.csr -subj "/CN=$user$groups"
if [ ! -s "$user.csr" ]
then
  echo "$(gettext 'Certificate Signing Request file') 'csr' $(gettext 'not created')" >&2
  exit 1
fi
echo "$(gettext 'Certificate Signing Request file') 'csr' $(gettext 'created')" >&2

# Удалить предыдущий запрос если есть
kubectl delete certificatesigningrequest.certificates.k8s.io $user >/dev/null
request=$(base64 < $user.csr | tr -d "\n")

# Запись CSR в кластер
echo -ne "$(gettext 'Writing CSR certificate signing request to cluster')..." >&2
cat <<EOF | kubectl apply -f -
apiVersion: certificates.k8s.io/v1
kind: CertificateSigningRequest
metadata:
  name: $user
spec:
  request: $request
  signerName: kubernetes.io/kube-apiserver-client
  expirationSeconds: 157680000  # 5 years
  usages:
  - client auth
EOF

status=$(kubectl get certificatesigningrequest.certificates.k8s.io $user -o json | jq '.status')
if [ "$status" != '{}' ]
then
  echo -ne "\n$(gettext 'Certificate signing request failed')\n" >&2
  echo "$(gettext 'Status'): $status" >&2
  exit 1
fi

# Подтверждение CSR
echo -ne "\n$(gettext 'Confirming the Certificate Signing Request') (CSR)..." >&2
kubectl certificate approve $user

statusType=$(kubectl get certificatesigningrequest.certificates.k8s.io $user -o json | jq '.status.conditions[].type')
if [ "$statusType" != '"Approved"' ]
then
  echo "$(gettext 'Certificate verification request failed')" >&2
  exit 1
fi
echo ""

# Создание сертификата
echo -ne "\n$(gettext 'Creating a certificate')... " >&2
kubectl get csr $user -o jsonpath='{.status.certificate}'| base64 -d > $user.crt
if [ ! -s "$user.crt" ]
then
  echo "$(gettext 'Certificate') '$user.crt' $(gettext 'not created')" >&2
  exit 1
fi
echo "$(gettext 'Certificate') '$user.crt' $(gettext 'created')" >&2

# Проверка корректности сертификата
echo -ne "\n$(gettext 'Checking the correctness of the certificate')... " >&2
TMPFILE=/tmp/$cmdname.$$
openssl rsa  -noout -modulus -in $user.key | openssl md5 > $TMPFILE
openssl x509 -noout -modulus -in $user.crt | openssl md5 | cmp $TMPFILE
if [ $? -gt 0 ]
then
  echo -ne "\n$(gettext 'The users private key does not match the generated certificate')\n" >&2
  exit 1
fi
rm -f $TMPFILE
echo

clusterIP=$(getClusterIP)
URL="/etc/kubernetes/pki/ca.crt"

echo "$(gettext 'Enter user password') $remoteUser $(gettext 'in a cluster')" >&2
if scp $remoteUser@${clusterIP}:$URL ca.crt
then
  :;
else
  echo "$(gettext 'Copying certificate failed')" >&2
  exit 1
fi

clustername=`kubectl config  view -o jsonpath='{.clusters[0].name}'`
clusterapi=`kubectl config  view -o jsonpath='{.clusters[0].cluster.server}'`

kind=$(curl -s --key $user.key --cert $user.crt --cacert ca.crt  $clusterapi/api | jq '.kind')
if [ "$kind" != '"APIVersions"' ]
then
  echo "$(gettext 'Request to get server API version failed')" >&2
  exit 1
fi

# Формирование файла конфигурации пользователя
echo -ne "$(gettext 'Generating a user configuration file')... " >&2
kubectl config set-cluster $clustername --certificate-authority=ca.crt --embed-certs=true --server=$clusterapi --kubeconfig=config
kubectl config set-credentials $user --client-certificate=$user.crt --client-key=$user.key --embed-certs=true --kubeconfig=config
kubectl config set-context default --cluster=$clustername --user=$user --kubeconfig=config
kubectl config use-context default --kubeconfig=config
if [ -s "$user.csr" ]
then
  echo "$(gettext 'User configuration file') 'config' $(gettext 'created')" >&2
else
  echo "$(gettext 'User configuration file') 'config' $(gettext 'not created')" >&2
  exit 1
fi

# Добавление контекста созданного пользователя
echo -ne "$(gettext 'Adding context to created user')... " >&2
clustername=$(getClusterName)
kubectl config set-credentials $user --client-certificate=$user.crt --client-key=$user.key --embed-certs=true
kubectl config set-context $user --cluster=$clustername --user=$user
echo -ne "$(gettext 'context added')... " >&2


unsetUserKubeconfigAccess $user
