#!/bin/bash
#
# Copyright (c) 2021 Oracle and/or its affiliates. All rights reserved.
# Licensed under the GNU General Public License Version 2 as shown at https://oss.oracle.com/licenses/GPL-2.

whitelist="install
status
delete
upgrade
"

set -e

while [[ $# -gt 0 ]]; do
  flag="$1"
  case $flag in
    -c | --kubeconfig )
       kubecfg="$2"
       shift
       shift
    ;;
    -n | --namespace )
       namespace="$2"
       shift
       shift
    ;;
    -l | --delete-legacy-resources )
       cleanup_legacy_resources="$2"
       shift
       shift
    ;;
    -v | --version )
       # Only used in the "install" path
       desired_istio_install_version="$2"
       shift
       shift
     ;;
    -o | --current-istio-profile )
       # Only used in the "install" path
       current_version_profile="$2"
       shift
       shift
    ;;
    -a | --action )
       act="$2"
       shift
       shift
    ;;
    -i | --istio-profile )
       istio_profile="$2"
       shift
       shift
    ;;
    -g | --grafana-profile )
       grafana_profile="$2"
       shift
       shift
    ;;
    -p | --prometheus-profile )
       prometheus_profile="$2"
       shift
       shift
    ;;
    *)
       echo "invalid argument $1" >> /dev/stderr
       exit 1
    ;;
  esac
done

# Returns not found so we can mark the resource as uninstalled
if [ ! -f /usr/local/bin/istioctl ]; then
    echo "istioctl not found" >> /dev/stderr
    exit 1
fi

# Validate input
if ! echo "$whitelist" | grep -q -x "$act"; then
    echo "$act cannot be performed by this script"
    exit 1
fi

echo "kubecfg: $kubecfg namespace: $namespace act: $act cleanup_legacy_resources: $cleanup_legacy_resources"
tmp_verArr=( ${desired_istio_install_version//-/ } )
externalVerArr=( ${tmp_verArr[0]//./ } )

export KUBECONFIG="$kubecfg"

if [[ "${act}" == "delete" ]]; then
    # TODO: Generate from the manfest we installed with rather than the default
    set +e
    /usr/local/bin/istioctl manifest generate -f "${istio_profile}" | kubectl delete --ignore-not-found=true -f -
    set -e
    kubectl delete --ignore-not-found=true ClusterRoleBinding -l app=istio-init
    kubectl delete --ignore-not-found=true ClusterRoleBinding -l release=istio
    kubectl delete --ignore-not-found=true ClusterRoleBinding istio-multi

    kubectl delete --ignore-not-found=true ServiceAccount istio-multi -n istio-system
    kubectl delete --ignore-not-found=true ServiceAccount istio-init-service-account  -n istio-system

    kubectl delete --ignore-not-found=true ClusterRole -l app=istio-init
    kubectl delete --ignore-not-found=true ClusterRole -l release=istio
    kubectl delete --ignore-not-found=true ClusterRole istio-reader

    # Delete the CRD Jobs
    kubectl get job --ignore-not-found=true -n istio-system | grep istio-init-crd | awk '{ print $1 }' | xargs --no-run-if-empty -n1 kubectl --ignore-not-found=true delete job -n istio-system

    # From 1.8.x onwards, addon components needs to be installed/removed separately
    if [[ (${externalVerArr[0]} -eq 1 && ${externalVerArr[1]} -ge 8) || ${externalVerArr[0]} -gt 1 ]]; then
	set +e
	kubectl delete -f "${grafana_profile}"
	kubectl delete -f "${prometheus_profile}"
	set -e
    fi

    kubectl delete ns --ignore-not-found=true istio-system
fi

if [[ "${act}" == "install" ]]; then
	kubectl get namespace "$namespace" || kubectl create namespace "$namespace"

    if [[ ${desired_istio_install_version} == "1.5"* ]]; then
        # Is == 1.5
	    /usr/local/bin/istioctl manifest apply --skip-confirmation -f "${istio_profile}"
    else
        # Is >= 1.6
	    /usr/local/bin/istioctl install --skip-confirmation -f "${istio_profile}"
	    # From 1.8.x onwards, addon components needs to be installed separately
        if [[ (${externalVerArr[0]} -eq 1 && ${externalVerArr[1]} -ge 8) || ${externalVerArr[0]} -gt 1 ]]; then
	    kubectl apply -f "${grafana_profile}"
	    kubectl apply -f "${prometheus_profile}"
        fi

    fi
fi

if [[ "${act}" == "status" ]]; then
    /usr/local/bin/istioctl proxy-status
fi

if [[ "${act}" == "upgrade" ]]; then
    # Using --force allows us to upgrade from 1.4.10 -> 1.5.10
    /usr/local/bin/istioctl upgrade --force -y -f "${istio_profile}" --currentVersionProfile  "${current_version_profile}"

    if [[ "${cleanup_legacy_resources}" != "" ]]; then
        set +e
        kubectl -n istio-system delete --ignore-not-found=true deployment istio-citadel istio-galley istio-pilot istio-policy istio-sidecar-injector istio-telemetry
        kubectl -n istio-system delete --ignore-not-found=true service istio-citadel istio-policy istio-sidecar-injector istio-telemetry
        kubectl -n istio-system delete --ignore-not-found=true horizontalpodautoscaler.autoscaling/istio-pilot horizontalpodautoscaler.autoscaling/istio-telemetry
        kubectl -n istio-system delete --ignore-not-found=true pdb istio-citadel istio-galley istio-pilot istio-policy istio-sidecar-injector istio-telemetry
        kubectl -n istio-system delete --ignore-not-found=true deployment istiocoredns
        kubectl -n istio-system delete --ignore-not-found=true service istiocoredns

        kubectl delete --ignore-not-found=true policies.authentication.istio.io --all-namespaces --all
        kubectl delete --ignore-not-found=true meshpolicies.authentication.istio.io --all
        set -e
    fi

    # From 1.8.x onwards, addon components needs to be installed separately
    if [[ (${externalVerArr[0]} -eq 1 && ${externalVerArr[1]} -ge 8) || ${externalVerArr[0]} -gt 1 ]]; then
        kubectl apply -f "${grafana_profile}" --force
        kubectl apply -f "${prometheus_profile}" --force
    fi
fi
