#!/bin/bash

## NOTE : only adding cloudflare host entry for [].company.io

#set -x

# passing configuration file eg : create_aks_cluster.sh bnz-uat.conf | create_aks_cluster.sh bnz-prd.conf | create_aks_cluster.sh tst.conf
path_script="$(readlink -f "$0")"
path_dir="${path_script%/*}"
source ${1:-$path_dir/az-dev.conf}
fn=`basename "$0"`

if [ -f "$2" ]; then #Local debug credentials in 2nd file not in git
  echo "#$fn: !!!## source second file $2"
  source $2
  #
  if [[ "$DebugAZlogin" = true ]]; then
    echo "#$fn: az login --service-principal --username $SP_DEPLOY_ID --tenant $TENANT"
    az login  --service-principal \
              --username $SP_DEPLOY_ID \
              --password $SP_DEPLOY_SECRET \
              --tenant $TENANT
    #az account list --output table
    echo "#$fn: az account set --subscription $SUBSCRIPTIONID"
    az account set --subscription $SUBSCRIPTIONID
    #az account list --output table
    echo "####$fn: get k8s credentials for cluster --name $AKSCLUSTERNAME"
    az aks get-credentials --resource-group $aksResourceGroup \
                        --name $AKSCLUSTERNAME \
                        --overwrite-existing
  fi
fi

# check the resouces availability from az pipeline
for resource in CFAUTHEMAIL CFZONEID CFAUTHKEY AKSCLUSTERNAME TENANT SUBSCRIPTIONID CH;
do
  if [ -z "${!resource}" ]; then
    echo "#$fn: $resource Not found. Check pipeline variables"
    exit 1;
  fi
done

aksResourceGroup=${AKSCLUSTERRESOURCEGROUP:-aks-$AKSCLUSTERNAME}


# check given aks cluster has been created
aks_cluster_status=$(az aks show --name $AKSCLUSTERNAME --resource-group $aksResourceGroup --output table)
echo "$aks_cluster_status" | grep "^$AKSCLUSTERNAME" | grep -o "Succeeded"
rc=$?

if [[ $rc == 0 ]]; then
  echo "#$fn: $AKSCLUSTERNAME Cluster already exsist on RC $aksResourceGroup"

  # get k8s credentials for given cluster
  # az aks get-credentials  --resource-group $aksResourceGroup \
  #                         --name $AKSCLUSTERNAME \
  #                         --overwrite-existing
  ## make sure kubectl context is set
  context=$(kubectl config current-context )
  if [[ "$context" != "$AKSCLUSTERNAME" ]]; then
    echo "####$fn: ERR the current kubectl context not AKSCLUSTERNAME=$AKSCLUSTERNAME , it is $context"
    exit 1
  fi

  # check able to see the cluster
  az aks show --name $AKSCLUSTERNAME --resource-group $aksResourceGroup --query name --output tsv | grep -o $AKSCLUSTERNAME
  rc=$?; if [[ $rc != 0 ]]; then echo "#$fn: aks $AKSCLUSTERNAME cluster not able to access"; exit $rc; fi

  echo "#$fn: getting pub ip $(date)"
  echo "#$fn: aksEnvironment=$AKSENVIRONMENT , ch=$CH , cfAuthEmail=$CFAUTHEMAIL, cfAuthKey=${CFAUTHKEY:0:3}..."


  # finding public IP or use from config
  aksClusterPubIPName=${RESERVEDPUBIPADDRNAME:-$AKSCLUSTERNAME-$AKSENVIRONMENT-ip-public}
  pubIPResGrp=${RESERVEDPUBIPRESOURCEGROUP:-$aksResourceGroup}

  if [ -z "$RESERVEDPUBIPADDRNAMEINGRESS" ]; then
    ## If Basic, use ip above , if Standard LB need seperate ingress ip
    aksClusterPubIPsku=$(az network public-ip show --resource-group $pubIPResGrp \
                                                  --name $aksClusterPubIPName \
                                                  --query sku \
                                                  --output tsv)
    if [[ "$aksClusterPubIPsku" == "Standard" ]]; then
      echo "#$fn: sku=$aksClusterPubIPsku for $aksClusterPubIPName , use new seperate ip for Ingress , pubIPResGrp=$pubIPResGrp"
      aksClusterPubIngressIPName=$AKSCLUSTERNAME-$AKSENVIRONMENT-ip-pub-ingress
    else
      echo "#$fn: sku=$aksClusterPubIPsku for $aksClusterPubIPName, use same ip for ingress , pubIPResGrp=$pubIPResGrp"
      aksClusterPubIngressIPName=$aksClusterPubIPName
    fi
  else
    aksClusterPubIngressIPName=$RESERVEDPUBIPADDRNAMEINGRESS
    echo "#$fn: use env RESERVEDPUBIPADDRNAMEINGRESS=$aksClusterPubIngressIPName , pubIPResGrp=$pubIPResGrp"
  fi

  #Get IP Addr
  aksClusterPubIP=$(az network public-ip show --resource-group $pubIPResGrp \
                                                --name $aksClusterPubIngressIPName \
                                                --query ipAddress \
                                                --output tsv)
  echo "#$fn: Retrieved k8s  $AKSCLUSTERNAME pub ip $aksClusterPubIngressIPName as \"$aksClusterPubIP\" ."

  # check cluster public ip is empty before we go forward.
  if [ -z "$aksClusterPubIP" ]; then
    echo "#$fn: Cluster Public IP cannot be empty!!!";
    exit 1;
  fi

  # connect to cluster and find the domain names which need to put cf entry only xxxx.company.io
  getcompanyHosts=$(kubectl -n $CH-$AKSENVIRONMENT get ingress \
                            -o jsonpath={.items[*].spec.rules[*].host})
  getcompanyHosts=$(echo $getcompanyHosts | grep -o '[^ ]\+.company.io\|')

  # remove duplicates hostnames
  getcompanyHosts=$(echo $getcompanyHosts | tr ' ' '\n' | sort -u | tr '\n' ' ')

  # set as bash array
  getcompanyHosts=($getcompanyHosts)

  echo "#$fn: All DNS host names [ ${getcompanyHosts[@]} ] ."

  for getcompanyHost in "${getcompanyHosts[@]}";
  do
    dnsName=$getcompanyHost
    echo -e "###\n###$fn: > Loop dnsName:\"$dnsName\"  , aksClusterPubIP=$aksClusterPubIP \n###"

    checkDNSIPget=$(curl -s -L -X GET "https://api.cloudflare.com/client/v4/zones/$CFZONEID/dns_records?name=$dnsName&match=all" \
      -H "X-Auth-Email: $CFAUTHEMAIL" \
      -H "X-Auth-Key: $CFAUTHKEY" \
      -H "Content-Type: application/json")
    rc=$?;  if [[ $rc != 0 ]]; then
              echo "#$fn: Error from CF rc=$? curl  GET name=$dnsName"
              echo "checkDNSIPget: $checkDNSIPget"
              exit rc
            fi
    echo "# response from CF  rc=$rc"
    DNScount=$( echo $checkDNSIPget | python3 -c "import sys, json; print( json.load(sys.stdin)['result_info']['count'] )" )
    rc=$?;  if [[ $rc != 0 ]]; then
              echo "#$fn: Error parsing response from CF rc=$? for ['result_info']['count']"
              echo "checkDNSIPget: $checkDNSIPget"
              exit rc
            fi
    if [[ $DNScount > 0 ]]; then
        checkDNSIP=$( echo $checkDNSIPget | python3 -c "import sys, json; print( json.load(sys.stdin)['result'][0]['content'] )" )
        rc=$?;  if [[ $rc != 0 ]]; then
                  echo "#$fn: Error parsing ip, got DNScount=$DNScount records, but parse ['result'][0]['content'] failed ?? EXITING"
                  echo "checkDNSIPget=$checkDNSIPget"
                  exit rc
                fi

      if [[ "$aksClusterPubIP" = "$checkDNSIP" ]]; then
        echo "#$fn: > DNS record already exsist for $dnsName -> $checkDNSIP"
      else
        if [[ "$checkDNSIP" =~ .+\.s3-website.*amazonaws.com ]]; then
          echo -e "#\n#$fn: > Skip dns dnsName=$dnsName  Looks like S3 Amazon public bucket !! \n#"
        else
          echo "#$fn: > ERR dnsName=$dnsName =CF checkDNSIP=\"$checkDNSIP\" <> aksClusterPubIP=\"$aksClusterPubIP\" "
          exit 1;
        fi
      fi
    else  # count=0
      echo "#$fn: > CF DNS search for name=$dnsName found DNScount=$DNScount, must be new recor."
      # assume there is no record "IndexError: list index out of range"
      # check if name contains "cdn" enable cache for CDN
      echo "$dnsName" | grep -o 'cdn'
      rc=$?;  if [[ $rc != 0 ]]; then
                  proxied_status="false"
              else
                  proxied_status="true"
              fi
      # With CFPROXYENABLED=true all new CF entries will be proxied
      proxied_status=${CFPROXYENABLED:-$proxied_status}
      echo "#$fn: > Create new DNS entry for \"$dnsName\"  proxied=$proxied_status"
      cfDNSPortalPost=$(curl -s -L -X POST "https://api.cloudflare.com/client/v4/zones/$CFZONEID/dns_records" \
            -H "X-Auth-Email: $CFAUTHEMAIL" \
            -H "X-Auth-Key: $CFAUTHKEY" \
            -H "Content-Type: application/json" \
            --data '{"type":"A","name":"'"$dnsName"'","content":"'"$aksClusterPubIP"'","ttl":120,"priority":10,"proxied":'$proxied_status'}' )
      cfDNSPortal=$( echo $cfDNSPortalPost | python3 -c "import sys, json; print( json.load(sys.stdin)['success'] )")
      rc=$?;  if [[ $rc != 0 ]]; then
                echo "#$fn: > CF put response not decode.  error."
                echo "cfDNSPortalPost: $cfDNSPortalPost"
              fi
      echo "#$fn: > cfDNSPortal: $cfDNSPortal"
      if [ "$cfDNSPortal" == "True" ]; then
        echo "#$fn: > DNS record added $dnsName -> $aksClusterPubIP"
      else
        echo "#$fn: > For $dnsName -> $aksClusterPubIP CF ERROR Adding DNS record!!!!"
        exit 1
      fi
    fi

  done

  echo "#$fn: Finished loop through hosts."

else
  echo "#$fn: Cluster not found resource-group=$aksResourceGroup name=$AKSCLUSTERNAME "
  exit 1
fi

echo "#$fn: The End $(date)"