#!/bin/bash

function kubernetes_configs(){
    # set KUBECONFIG to default kubeconfig and all *.yaml files in .kube
    local KUBE_CONFIG_DEFAULT="$HOME/.kube/config"
    local KUBE_CONFIG_DIR="$HOME/.kube"
    local KUBE_CONFIG_EXTENTION="*.yaml"
    if [[ -f "${KUBE_CONFIG_DEFAULT}" ]];then
      export KUBECONFIG="$KUBE_CONFIG_DEFAULT"
    fi
    [[ -d "${KUBE_CONFIG_DIR}" ]] || mkdir -p "${KUBE_CONFIG_DIR}"
    # shellcheck disable=SC2044
    for file in $(find "${KUBE_CONFIG_DIR}" -type f -name "$KUBE_CONFIG_EXTENTION"); do
        export KUBECONFIG="$file:$KUBECONFIG"
    done
    if [[ $(command -v kubectl) ]];then
        complete -W "$(kubectl config get-contexts -o name)" kuc
    fi
}
kubernetes_configs

function kc(){
    # print all kubernetes contexts
    kubectl config get-contexts
}

function kuc(){
    # use kubernetes context <param>
    kubectl config use-context "$1"
}

function k(){
    kubectl "$@"
}
[[ $(type -t __start_kubectl) == function ]] && complete -o default -F __start_kubectl k

function k8s_validate_private_ingress(){
    local PRIVATE_PROJECT_ID="${PRIVATE_PROJECT_ID:-p-c5fcj}"
    local WHITELIST_SOURCE_RANGE="${WHITELIST_SOURCE_RANGE:-10.0.0.0/8}"
    local OK='\e[32m\u2714\e[0m'
    local NOT_OK='\u274c'
    printf "Validating ingresses in private project (%s}\n" "$PRIVATE_PROJECT_ID"
    printf "%-22s %s\n" "namespace" "ingress"
    printf -- '-%.0s' {1..30}
    printf "\n"
    for NS in $(kubectl get namespaces --selector=field.cattle.io/projectId="$PRIVATE_PROJECT_ID" --template "{{range .items}}{{.metadata.name}}{{\"\n\"}}{{end}}"); do
        for INGRESS in  $(kubectl --namespace "$NS" get ingress --template "{{range .items}}{{.metadata.name}}{{\"\n\"}}{{end}}"); do
            if [[ $(kubectl --namespace "$NS" get ingress "$INGRESS" -o jsonpath='{.metadata.annotations.nginx\.ingress\.kubernetes\.io/whitelist-source-range}') == "$WHITELIST_SOURCE_RANGE" ]];then
                echo -n -e "$OK "
            else
                echo -n -e "$NOT_OK "
            fi
            printf "%-20s %s\n" "$NS" "$INGRESS"
        done
    done

}

function k8s_list_deprecation_apis(){
    #Prints all api deprecation warnings in cluster
    if ! command -v prom2json > /dev/null; then
        printf "You need prom2json for this function: https://github.com/prometheus/prom2json\n"
        return 1
    fi
    kubectl get --raw /metrics | prom2json | jq -c '.[] | select(.name=="apiserver_requested_deprecated_apis").metrics[].labels' | column -t -s'{}[],"'
}

function k8s_neuvector_cve_db_version(){
    local NAMESPACE="cattle-neuvector-system"

    printf "%-40s %s\n" "Pod" "CVE DB version"

    for POD in $(kubectl -n $NAMESPACE get pods -l 'app=neuvector-scanner-pod' --template "{{range .items}}{{.metadata.name}}{{\"\n\"}}{{end}}"); do
        version="$(kubectl -n "$NAMESPACE" logs "$POD" | grep "Expand new DB" | tail -1 | sed -n 's/.*Expand new DB - version=\([0-9]*\.[0-9]*\)/\1/p')"
        printf "%-40s %s\n" "$POD" "$version"
    done
}

function k8s_node_taints(){
    kubectl get nodes -o json | jq '.items[].spec.taints'
}

function k8s_apps(){
    # parameters,
    # stop = Set all deployments & statefultsets to replica=0
    # start = set all deployments & statefulsets to replica=1
    # show = show status of all deployments & statefulsets
    CHOICE="$1"
    if [[ ! "start stop show" =~ (" "|^)"$CHOICE"(" "|$) ]]; then
        echo "no parameter given"
        return 1
    fi
    local USER_PROJECT_IDS=(p-c5fcj p-q8pbm)
    local OK='\e[32m\u2714\e[0m'
    local NOT_OK='\u274c'
    printf "%-22s %s\n" "namespace" "application"
    printf -- '-%.0s' {1..34}
    printf "\n"
    for PROJECT in "${USER_PROJECT_IDS[@]}"; do
        for NS in $(kubectl get namespaces --selector=field.cattle.io/projectId="$PROJECT" --template "{{range .items}}{{.metadata.name}}{{\"\n\"}}{{end}}"); do
            for DEPLOYMENT in  $(kubectl --namespace "$NS" get deployments --template "{{range .items}}{{.metadata.name}}{{\"\n\"}}{{end}}"); do
                if [[ "$CHOICE" == "stop" ]];then
                    kubectl --namespace "$NS" scale deployment "$DEPLOYMENT" --replicas=0 > /dev/null
                elif [[ "$CHOICE" == "start" ]];then
                    kubectl --namespace "$NS" scale deployment "$DEPLOYMENT" --replicas=1 > /dev/null
                fi
                if [[ $(kubectl --namespace "$NS" get deployments "$DEPLOYMENT" -o jsonpath='{.spec.replicas}') == "0" ]];then
                    echo -n -e "$NOT_OK "
                else
                    echo -n -e "$OK "
                fi
                printf "%-20s %s\n" "$NS" "$DEPLOYMENT"
            done
            for STATEFULSET in  $(kubectl --namespace "$NS" get statefulsets --template "{{range .items}}{{.metadata.name}}{{\"\n\"}}{{end}}"); do
                if [[ "$CHOICE" == "stop" ]];then
                    kubectl --namespace "$NS" scale statefulset "$STATEFULSET" --replicas=0 > /dev/null
                elif [[ "$CHOICE" == "start" ]];then
                    kubectl --namespace "$NS" scale statefulset "$STATEFULSET" --replicas=1 > /dev/null
                fi
                if [[ $(kubectl --namespace "$NS" get statefulsets "$STATEFULSET" -o jsonpath='{.spec.replicas}') == "0" ]];then
                    echo -n -e "$NOT_OK "
                else
                    echo -n -e "$OK "
                fi
                printf "%-20s %s\n" "$NS" "$STATEFULSET"
            done
        done
    done
}
