# source me to have all the nice things

if [ "$0" == "$BASH_SOURCE" ]; then
    echo "You should be sourcing this."
    exit 1
fi

hscloud_root="$( cd "$(dirname "$BASH_SOURCE")"; pwd -P )"

if [ ! -f "$hscloud_root/WORKSPACE" ]; then
    echo "Could not find WORKSPACE"
    exit 1
fi

hscloud_path="$hscloud_root/bazel-bin/tools"

[[ ":$PATH:" != *":$hscloud_path:"* ]] && PATH="$hscloud_path:${PATH}"

# legacy crap follows

hscloud-dc() {
    ( cd "$hscloud_root" && docker-compose -f "docker/docker-compose.yml" "$@" )
}

hscloud-pki-dev() {
    (
        set -e

        cd "$hscloud_root"
        rm -rf docker/pki

        cp -rv go/pki/dev-certs docker/pki
        cd docker/pki
        bash gen.sh m6220-proxy arista-proxy cmc-proxy topo client
        ls *pem
    )
}

# Generate a per-node certificate remotely on the node.
hscloud-node-remote-cert() {
    (
        set -e
        if [ -z "$1" ] || [ -z "$2" ] || [ -x "$3" ]; then
            echo >&2 "Usage: hscloud-node-remote-cert node.fqdn.com certname subj"
            exit 1
        fi
        fqdn="$1"
        certname="$2"
        subj="$3"

        echo "Node: ${fqdn}; Cert: ${certname}"

        echo "Checking node livenes..."
        ssh root@$fqdn uname -a

        echo "Checking if node already has key..."
        ssh root@$fqdn stat /opt/hscloud/${certname}.key || (
            echo "Generating key..."
            ssh root@$fqdn -- mkdir -p /opt/hscloud
            ssh root@$fqdn -- nix-shell -p openssl --command "\"openssl genrsa -out /opt/hscloud/${certname}.key 4096\"" 
            ssh root@$fqdn -- chmod 400 /opt/hscloud/${certname}.key
        )

        echo "Checking if node already has cert..."
        ssh root@$fqdn stat /opt/hscloud/${certname}.crt && exit 0
        echo "No cert, will generate..."

        cd "$hscloud_root"
        secrets="$hscloud_root/secrets"
        ca="$secrets/ca.key"
        [ ! -f "$ca" ] && ( scripts/secretstore decrypt "$secrets/cipher/ca.key" > $ca )

        cp data/openssl.cnf san.cnf
        echo -ne "\n[SAN]\nsubjectAltName=DNS:${fqdn}" >> san.cnf
        scp san.cnf root@$fqdn:/opt/hscloud/san.cnf

        ssh root@$fqdn -- nix-shell -p openssl --command "\"openssl req -new -key /opt/hscloud/${certname}.key -out /opt/hscloud/${certname}.csr -subj '${subj}' -config /opt/hscloud/san.cnf -reqexts SAN\""
        scp root@$fqdn:/opt/hscloud/${certname}.csr ${fqdn}-${certname}.csr
        openssl x509 -req \
                -in ${fqdn}-${certname}.csr \
                -CA data/ca.crt \
                -CAkey "$ca" -CAcreateserial \
                -out "data/${fqdn}-${certname}.crt" \
                -extensions SAN -extfile san.cnf

        scp "data/${fqdn}-${certname}.crt" root@$fqdn:/opt/hscloud/${certname}.crt
        scp "data/ca.crt" root@$fqdn:/opt/hscloud/ca.crt
        ssh root@$fqdn -- chmod 444 /opt/hscloud/${certname}.crt /opt/hscloud/ca.crt
        rm ${fqdn}-${certname}.csr
        rm san.cnf
    )
}

# Generate locally (if not present) a shared certificate, and upload it to the node
hscloud-node-shared-cert() {
    (
        set -e
        if [ -z "$1" ] || [ -z "$2" ] || [ -x "$3" ]; then
            echo >&2 "Usage: hscloud-node-shared-cert node.fqdn.com certname subj"
            exit 1
        fi
        fqdn="$1"
        certname="$2"
        subj="$3"

        cd "$hscloud_root"
        secrets="$hscloud_root/secrets"
        keyfile="$secrets/$certname.key"
        cert="$hscloud_root/data/$certname.crt"
        csr="$hscloud_root/data/$certname.csr"
        ca="$secrets/ca.key"
        [ ! -f "$ca" ] && ( scripts/secretstore decrypt "$secrets/cipher/ca.key" > $ca )

        echo "Checking if key exists..."
        if [ ! -f "$keyfile" ]; then
            echo "No key, trying to decrypt..."
            if ! scripts/secretstore decrypt "$secrets/cipher/$certname.key" > "$keyfile" ; then
                echo "No encrypted key, generating..."
                openssl genrsa -out $keyfile 4096
                echo "Encrypting..."
                scripts/secretstore encrypt "$keyfile" > "$secrets/cipher/$certname.key"
            fi
        fi

        echo "Checking if cert exists..."
        if [ ! -f "$cert" ]; then
            echo "No cert, generating..."
            rm -f "${csr}"
            openssl req -new -key "${keyfile}" -out "${csr}" -subj "${subj}"
            openssl x509 -req -in "${csr}" -CA data/ca.crt -CAkey "$ca" -CAcreateserial -out "${cert}"
        fi

        echo "Copying certificate to node..."
        scp "${cert}" root@$fqdn:/opt/hscloud/${certname}.crt
        scp "${keyfile}" root@$fqdn:/opt/hscloud/${certname}.key
        ssh root@$fqdn -- chmod 444 /opt/hscloud/${certname}.crt
        ssh root@$fqdn -- chmod 400 /opt/hscloud/${certname}.key
    )
}

hscloud-node-certs() {
    (
        set -e
            
        if [ -z "$1" ]; then
            echo >&2 "Usage: hscloud-node-certs node.fqdn.com"
            exit 1
        fi
        fqdn="$1"

        hscloud-node-remote-cert ${fqdn} node "/C=PL/ST=Mazowieckie/L=Mazowieckie/O=Stowarzyszenie Warszawski Hackerspace/OU=Node Bootstrap Certificate/CN=\"$fqdn\""
        hscloud-node-remote-cert ${fqdn} kube-node "/C=PL/ST=Mazowieckie/L=Mazowieckie/O=system:nodes/OU=Kubernetes Node Certificate/CN=system:node:\"$fqdn\""
        for component in controller-manager proxy scheduler; do
            hscloud-node-shared-cert ${fqdn} kube-${component} "/C=PL/ST=Mazowieckie/L=Mazowieckie/O=system:kube-${component}/OU=Kubernetes Component ${component}/CN=system:kube-${component}"
        done
        hscloud-node-shared-cert ${fqdn} kube-apiserver "/C=PL/ST=Mazowieckie/L=Mazowieckie/O=Kubernetes API/CN=k0.hswaw.net"
        hscloud-node-shared-cert ${fqdn} kube-serviceaccounts "/C=PL/ST=Mazowieckie/L=Mazowieckie/O=Kubernetes Service Accounts/CN=service-accounts"
    )
}

hscloud-k8s-config() {
    (
        set -e

        if [ -z "$1" ]; then
            echo >&2 "Usage: hscloud-k8s-config username"
            exit 1
        fi
        username="$1"

        cd "$hscloud_root"
        mkdir -p .kubectl

        cert="$hscloud_root/.kubectl/client.crt"
        csr="$hscloud_root/.kubectl/client.csr"
        keyfile="$hscloud_root/.kubectl/client.key"
        secrets="$hscloud_root/secrets"
        ca="$secrets/ca.key"

        if [ ! -f "$keyfile" ]; then
            echo "Generating ${keyfile}..."
            openssl genrsa -out $keyfile 4096
            rm -f "$cert"
        fi
        if [ ! -f "$cert" ]; then
            echo "Signing ${cert}..."
            [ ! -f "$ca" ] && ( scripts/secretstore decrypt "$secrets/cipher/ca.key" > $ca )
            openssl req -new -key "${keyfile}" -out "${csr}" -subj "/C=PL/ST=Mazowieckie/O=system:masters/OU=Kubernetes Admin Account for ${username}/CN=${username}"
            openssl x509 -req -in "${csr}" -CA data/ca.crt -CAkey "$ca" -CAcreateserial -out "${cert}"
        fi

        kubeconfig="$hscloud_root/.kubectl/client.kubeconfig"
        echo "Generating ${kubeconfig}..."
        rm -rf ${kubeconfig}

        kubectl config set-cluster k0.hswaw.net \
          --certificate-authority=${hscloud_root}/data/ca.crt \
          --embed-certs=true \
          --server=https://k0.hswaw.net:4001 \
          --kubeconfig=${kubeconfig}

        kubectl config set-credentials ${username} \
          --client-certificate=${cert} \
          --client-key=${keyfile} \
          --embed-certs=true \
          --kubeconfig=${kubeconfig}

        kubectl config set-context default \
          --cluster=k0.hswaw.net \
          --user=${username} \
          --kubeconfig=${kubeconfig}

        kubectl config use-context default --kubeconfig=${kubeconfig}
    )
}
