#!/usr/bin/env bash
# Copyright 2020 IBM Corp.
# SPDX-License-Identifier: Apache-2.0

# This script configures Vault which is deployed on the control-plane namespace (usually fybrik-system)
# in multi clusters setup which includes two kind clusters.
# It defines Vault role for modules running in fybrik-blueprints namespace to authentication against
# Vault to retrieve dataset credentials.
# To create the two kind clusters the create_kind.sh script should be used as follows:
# ./create_kind.sh multi

set -x
set -e

op=$1

source ./common.sh
source ./vault_utils.sh

: ${KUBE_NAMESPACE:=fybrik-system}
: ${INGRESS_ADDRESS:=http://localhost:80}
: ${KIND_CLUSTER_KUBE_HOST:=https://kind-control-plane:6443}
: ${CONTROL_CLUSTER_KUBE_HOST:=https://control-control-plane:6443}
: ${MODULE_NAMESPACE:="fybrik-blueprints"}
: ${MODULES_ROLE:=module}
: ${FYBRIK_ROLE:=fybrik}
# Add policy and role for modules running in fybrik-blueprints namespace to
# use the vault-plugin-secrets-kubernetes-reader plugin enabled in Vault
# path kubernetes-secrets.
: ${PLUGIN_PATH:=kubernetes-secrets}
: ${OMD_PLUGIN_PATH:=omd-secrets}
: ${DATA_PROVIDER_USERNAME:=data_provider}
: ${DATA_PROVIDER_PASSWORD:=password}

# $1 - cluster name
# $2 - kube host of the cluster
enable_k8s_auth_for_cluster() {
        bin/kubectl config use-context kind-"$1"
        bin/kubectl create ns $KUBE_NAMESPACE || true
        bin/kubectl apply -f vault_auth_sa.yaml -n "$KUBE_NAMESPACE"
        enable_k8s_auth "$1" vault-auth "$KUBE_NAMESPACE" "$2"
}

configure_vault() {
        create_policy_with_plugin_path "allow-all-dataset-creds" "$PLUGIN_PATH/*" "$OMD_PLUGIN_PATH/*"
}


# $1 - cluster name
add_role() {
	create_role "$MODULES_ROLE" "allow-all-dataset-creds" "$1" "$MODULE_NAMESPACE"
	create_role "$FYBRIK_ROLE" "allow-all-dataset-creds" "$1" "$KUBE_NAMESPACE"
}

add_userpass_auth_method() {
	bin/kubectl config use-context kind-control
	enable_userpass_auth "$DATA_PROVIDER_USERNAME" "$DATA_PROVIDER_PASSWORD" "allow-all-dataset-creds"
}

# test Vault configuration by calling Kubernetes Auth Method login command
# to authenticate services in fybrik-blueprints namespace.
# ref: https://developer.hashicorp.com/vault/docs/auth/kubernetes
# params:
# $1 - Auth path. for example: kubernetes
test_vault_configuration() {
	bin/kubectl config use-context kind-"$1"
	# get the JWT of the default service account in fybrik-blueprints namespace
	TOKEN=$(bin/kubectl create token default --namespace "$MODULE_NAMESPACE")
	STATUS_CODE=$(bin/kubectl run curl --image=radial/busyboxplus:curl  -i --rm --restart=Never -- curl http://control-control-plane/v1/auth/"$1"/login -w "%{http_code}\n" --output /dev/null --silent  -H "Content-Type: application/json" --data '{"jwt":"'"$TOKEN"'", "role": "'"$MODULES_ROLE"'"}')
	echo $STATUS_CODE
	OK=200
	if [[ "$STATUS_CODE" == *"$OK"* ]] ; then
		echo "status code is $STATUS_CODE"
	else
		exit 1
	fi
}

case "$op" in
    *)
        header_text "Configure Vault on kind multi-cluster"
        bin/kubectl config use-context kind-control --namespace=$KUBE_NAMESPACE
        export VAULT_ADDR=$INGRESS_ADDRESS
        export VAULT_TOKEN=$(bin/kubectl get secrets vault-credentials -n $KUBE_NAMESPACE -o jsonpath={.data.VAULT_TOKEN} | base64 --decode)
        bin/vault login "$VAULT_TOKEN"
        enable_k8s_auth_for_cluster control "$CONTROL_CLUSTER_KUBE_HOST"
        enable_k8s_auth_for_cluster kind "$KIND_CLUSTER_KUBE_HOST"
        configure_vault
        add_role kind
        add_role control
        add_userpass_auth_method
        test_vault_configuration kind
        test_vault_configuration control
        # Switch to control cluster after configuration
        bin/kubectl config use-context kind-control

        ;;
esac
