#!/bin/sh

. podsec-k8s-rbac-functions

cmdname=$(basename $0)
if [ $# -lt 1 ]
then
  echo "Формат вызова: $0 <пользователь>[@<удаленный_пользователь>] [<группа1> ...]"
  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 каталог $KUBECONFIGDIR отсутствует" >&1
  exit 1
fi

if ! cd $KUBECONFIGDIR
then
  echo "Нет прав на доступ в каталог $KUBECONFIGDIR"
  exit 1
fi

# Создание личного (private) ключа
echo -ne "Создании личного (private) ключа..."
openssl genrsa -out $user.key 2048 >/dev/null 2>&1
if [ ! -s "$user.key" ]
then
  echo "Файл личного ключа '$user.key' не создан"
  exit 1
fi
echo "личный (private) ключ создан"

# Создание запроса на подпись сертификата (CSR)
echo -ne "Создание запроса на подпись сертификата (CSR)..."
openssl req -new -key $user.key -out $user.csr -subj "/CN=$user$groups"
if [ ! -s "$user.csr" ]
then
  echo "Файл запроса на подпись сертификата '$user.key' не создан"
  exit 1
fi
echo "запрос на подпись сертификата создан"

# Удалить предыдущий запрос если есть
kubectl delete certificatesigningrequest.certificates.k8s.io $user >/dev/null 2>&1
request=$(base64 < $user.csr | tr -d "\n")
# Запись CSR в кластер
echo -ne "Запись запроса на подпись сертификата CSR в кластер..."
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"Запрос на подпись сертификата не выполнен\n"
  echo "Статус: $status"
  exit 1
fi

# Подтверждение CSR
echo -ne "Подтверждение запроса на подпись сертификата (CSR)..."
kubectl certificate approve $user

statusType=$(kubectl get certificatesigningrequest.certificates.k8s.io $user -o json | jq '.status.conditions[].type')
if [ "$statusType" != '"Approved"' ]
then
  echo "Запрос на подтверждение сертификата не выполнен"
  exit 1
fi

# Создание сертификата
echo "Создание сертификата..."
kubectl get csr $user -o jsonpath='{.status.certificate}'| base64 -d > $user.crt
if [ ! -s "$user.crt" ]
then
  echo "сертификат '$user.crt' не создан"
  exit 1
fi
echo "сертификат '$user.crt' создан"

# Проверка корректности сертификата
echo -ne "Проверка корректности сертификата..."
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Личный ключ пользователя не соответствуют сгенерированному сертификату\n" >&1
  exit 1
fi
rm -f $TMPFILE
echo

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

echo "Введите пароль пользователя $remoteUser в кластере"
if scp $remoteUser@${clusterIP}:$URL ca.crt
then
  :;
else
  echo "Копирование сертификата неудачное" >&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 "Запрос на получение API-версии сервера не прошел"
  exit 1
fi

# Формирование файла конфигурации пользователя
echo "Формирование файла конфигурации пользователя..."
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
echo "Файл конфигурации пользователя 'config' создан"
if [ ! -s "$user.csr" ]
then
  echo "Файл конфинурации 'config' не создан"
  exit 1
fi

# Добавление контекста созданного пользователя
echo -ne "Добавление контекста созданного пользователя..."
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 "контекст добавлен"


unsetUserKubeconfigAccess $user
