#!/usr/bin/env bash

set -euo pipefail
IFS=$'\n\t'

username="${1-}"
host="${2-}"
output_path="${3:-.}"

if [ -z "$username" ] || [ -z "$host" ]
  then
    echo "Usage: $0 USERNAME HOST [OUTPUTPATH]"
    exit 1
fi

if [ ! -d "$output_path" ]; then
    echo "Output directory $output_path does not exist!"
    exit 1
fi

# Create a temporary directory
temp=$(mktemp -d)

# Function to cleanup temporary directory on exit
cleanup() {
  rm -rf "$temp"
}
trap cleanup EXIT

echo Generating the private key
openssl genpkey -algorithm ed25519 -out "$temp/key.pem"

echo Generating the certificate request
openssl req -new -key "$temp/key.pem" -out "$temp/req.csr" -subj "/CN=$username"

echo Creating K8S CSR manifest
csr="$(cat "$temp/req.csr" | base64 | tr -d '\n')"
k8s_csr="apiVersion: certificates.k8s.io/v1
kind: CertificateSigningRequest
metadata:
  name: $username-csr
spec:
  request: $csr
  expirationSeconds: 307584000 # 10 years
  signerName: kubernetes.io/kube-apiserver-client
  usages:
    - digital signature
    - key encipherment
    - client auth
"

echo Creating K8S CSR resource
ssh "root@$host" "echo \"$k8s_csr\" | k3s kubectl apply -f -"

echo Approving K8S CSR
ssh "root@$host" "k3s kubectl certificate approve $username-csr"

echo Retrieving approved certificate
encoded_cert="$(ssh root@"$host" "k3s kubectl get csr $username-csr -o jsonpath='{.status.certificate}'")"

echo Retrieving default K3S kubeconfig
base_kubeconfig="$(ssh root@"$host" "cat /etc/rancher/k3s/k3s.yaml")"

echo Getting certificate authority data from default kubeconfig
cert_authority_data="$(echo -n "$base_kubeconfig" | yq -r '.clusters[0].cluster."certificate-authority-data"')"

echo Generating final kubeconfig
result_kubeconfig="apiVersion: v1
clusters:
- cluster:
    certificate-authority-data: $cert_authority_data
    server: https://$host:6443
  name: default
contexts:
- context:
    cluster: default
    user: $username
  name: default
current-context: default
kind: Config
preferences: {}
users:
- name: $username
  user:
    client-certificate: $username.crt
    client-key: $username.key
"

echo Writing resulting files to "$output_path"
echo -n "$encoded_cert" | base64 -d > $output_path/$username.crt
echo -n "$result_kubeconfig" > $output_path/config
cp $temp/key.pem $output_path/$username.key