#!/bin/bash

set -e

function logger() {
  TIMESTAMP=$(date +'%Y-%m-%d %H:%M:%S')
  case "$1" in
    debug)
      echo -e "$TIMESTAMP \033[36mDEBUG\033[0m $2"
      ;;
    info)
      echo -e "$TIMESTAMP \033[32mINFO\033[0m $2"
      ;;
    warn)
      echo -e "$TIMESTAMP \033[33mWARN\033[0m $2"
      ;;
    error)
      echo -e "$TIMESTAMP \033[31mERROR\033[0m $2"
      ;;
    *)
      ;;
  esac
}

function new_cluster() {
  edition=$(grep -r 'EDITION' $BASE/ai.config |cut -d'=' -f2)

  #重建clusters/ai/config.yml,clusters/ai/hosts
  new
  logger debug "正在配置集群信息"
  #从配置文件获取etcd节点IP
  etcdIPs=$(grep -r 'MGR_NODE_IP' $BASE/ai.config |cut -d'=' -f2|awk '{print $1}')
  for etcdIP in $etcdIPs
  do
    # 检查etcdIP正则表达式
    [[ $etcdIP =~ ^(2(5[0-5]{1}|[0-4][0-9]{1})|[0-1]?[0-9]{1,2})(\.(2(5[0-5]{1}|[0-4][0-9]{1})|[0-1]?[0-9]{1,2})){3}$ ]] || { logger error "Invalid ip etcd:$etcdIP"; return 1; }
    # 检查etcdIP是否已存在
    if [[ `sed -n '/^\[etcd/,/^\[kube_master/p' "$BASE/clusters/ai/hosts"|grep $etcdIP` ]];then
      logger warn "etcd $etcdIP already existed in $BASE/clusters/ai/hosts"
    else
      sed -i "/\[etcd/a $etcdIP" "$BASE/clusters/ai/hosts"
    fi
  done

  #从配置文件获取master节点IP
  masterIPs=$(grep -r 'MGR_NODE_IP' $BASE/ai.config |cut -d'=' -f2|awk '{print $1}')
  for masterIP in $masterIPs
  do
    # 检查masterIP正则表达式
    [[ $masterIP =~ ^(2(5[0-5]{1}|[0-4][0-9]{1})|[0-1]?[0-9]{1,2})(\.(2(5[0-5]{1}|[0-4][0-9]{1})|[0-1]?[0-9]{1,2})){3}$ ]] || { logger error "Invalid ip master:$masterIP"; return 1; }
    # 检查masterIP是否已存在
    if [[ `sed -n '/^\[kube_master/,/^\[kube_node/p' "$BASE/clusters/ai/hosts"|grep $masterIP` ]];then
      logger warn "master $masterIP already existed in $BASE/clusters/ai/hosts"
    else
      sed -i "/\[kube_master/a $masterIP" "$BASE/clusters/ai/hosts"
    fi
  done

  #从配置文件获取node节点IP
  nodeIPs=$(grep -r 'COMPUTE_NODE_IP' $BASE/ai.config |cut -d'=' -f2|awk '{print $1}')
  for nodeIP in $nodeIPs
  do
    # 检查nodeIP正则表达式
    [[ $nodeIP =~ ^(2(5[0-5]{1}|[0-4][0-9]{1})|[0-1]?[0-9]{1,2})(\.(2(5[0-5]{1}|[0-4][0-9]{1})|[0-1]?[0-9]{1,2})){3}$ ]] || { logger error "Invalid ip node:$nodeIP"; return 1; }
    # 检查nodeIP是否已存在
    if [[ `sed -n '/^\[kube_node/,/^\[harbor/p' "$BASE/clusters/ai/hosts"|grep $nodeIP` ]];then
      logger warn "node $nodeIP already existed in $BASE/clusters/ai/hosts"
    else
      sed -i "/\[kube_node/a $nodeIP" "$BASE/clusters/ai/hosts"
    fi
  done

  #从配置文件获取chrony节点IP
  chronyIP=$(grep -r 'MGR_NODE_IP' $BASE/ai.config |cut -d'=' -f2|awk 'NR==1{print $1}')
  # 检查chronyIP正则表达式
  [[ $chronyIP =~ ^(2(5[0-5]{1}|[0-4][0-9]{1})|[0-1]?[0-9]{1,2})(\.(2(5[0-5]{1}|[0-4][0-9]{1})|[0-1]?[0-9]{1,2})){3}$ ]] || { logger error "Invalid ip chrony:$chronyIP"; return 1; }
  # 检查chronyIP是否已存在
  if [[ `sed -n '/^\[chrony/,/^\[all:vars/p' "$BASE/clusters/ai/hosts"|grep $chronyIP` ]];then
    logger warn "chrony $chronyIP already existed in $BASE/clusters/ai/hosts"
  else
    sed -i "/\[chrony/a $chronyIP" "$BASE/clusters/ai/hosts"
  fi

  #从配置文件获取harbor IP 端口和admin用户密码
  harborNodeIP=$(grep -r 'HARBOR_NODE_IP' $BASE/ai.config |cut -d'=' -f2|awk '{print $1}')
  harborDomain=$(grep -r 'HARBOR_DOMAIN' $BASE/ai.config |cut -d'=' -f2|awk '{print $1}')
  harborExternalDomain=$(grep -r 'HARBOR_EXTERNAL_DOMAIN' $BASE/ai.config |cut -d'=' -f2|awk '{print $1}')
  harborPort=$(grep -r 'HARBOR_NODE_PORT' $BASE/ai.config |cut -d'=' -f2|awk '{print $1}')
  harborAdminPassword=$(grep -r 'HARBOR_ADMIN_PASSWORD' $BASE/ai.config |cut -d'=' -f2|awk '{print $1}')
  # 检查harborIP正则表达式
#  [[ $harborIP =~ ^(2(5[0-5]{1}|[0-4][0-9]{1})|[0-1]?[0-9]{1,2})(\.(2(5[0-5]{1}|[0-4][0-9]{1})|[0-1]?[0-9]{1,2})){3}$ ]] || { logger error "Invalid ip harbor:$harborIP"; return 1; }
  # 检查harborIP是否已存在
  if [[ `sed -n '/^\[harbor/,/^\[ex_lb/p' "$BASE/clusters/ai/hosts"|grep $harborNodeIP` ]];then
    logger warn "harbor $harborNodeIP already existed in $BASE/clusters/ai/hosts"
  else
    sed -i "s/__harbor_ip__/$harborNodeIP/g" "$BASE/clusters/ai/hosts"
    sed -i "s/__harbor_domain__/$harborDomain/g" "$BASE/clusters/ai/config.yml"
    sed -i "s/__harbor_external_domain__/$harborExternalDomain/g" "$BASE/clusters/ai/config.yml"
    sed -i "s/__harbor_port__/$harborPort/g" "$BASE/clusters/ai/config.yml"
    sed -i "s/__harbor_admin_password__/$harborAdminPassword/g" "$BASE/clusters/ai/config.yml"
  fi

  #从配置文件获取glusterfs/longhorn IP
  STORAGE_TYPE=$(grep -r 'STORAGE_TYPE' $BASE/ai.config |cut -d'=' -f2)
  if [[ $STORAGE_TYPE == glusterfs ]];then
    glusterfsIPs=$(grep -r 'STORAGE_NODE_IP' $BASE/ai.config |cut -d'=' -f2|awk '{print $1}')
    for glusterfsIP in $glusterfsIPs
    do
      # 检查glusterfsIP正则表达式
      [[ $glusterfsIP =~ ^(2(5[0-5]{1}|[0-4][0-9]{1})|[0-1]?[0-9]{1,2})(\.(2(5[0-5]{1}|[0-4][0-9]{1})|[0-1]?[0-9]{1,2})){3}$ ]] || { logger error "Invalid ip glusterfs:$glusterfsIP"; return 1; }
      # 检查glusterfsIP是否已存在
      if [[ `sed -n '/^\[glusterfs/,/^\[longhorn/p' "$BASE/clusters/ai/hosts"|grep $glusterfsIP` ]];then
        logger warn "glusterfs $glusterfsIP already existed in $BASE/clusters/ai/hosts"
      else
        rawDisk=$(grep -r 'STORAGE_NODE_IP' $BASE/ai.config |grep $glusterfsIP |cut -d'=' -f4)
        sed -i "/\[glusterfs/a $glusterfsIP RAW_DISK=$rawDisk" "$BASE/clusters/ai/hosts"
      fi
    done
  else
    longhornIPs=$(grep -r 'STORAGE_NODE_IP' $BASE/ai.config |cut -d'=' -f2|awk '{print $1}')
    for longhornIP in $longhornIPs
    do
      # 检查longhornIP正则表达式
      [[ $longhornIP =~ ^(2(5[0-5]{1}|[0-4][0-9]{1})|[0-1]?[0-9]{1,2})(\.(2(5[0-5]{1}|[0-4][0-9]{1})|[0-1]?[0-9]{1,2})){3}$ ]] || { logger error "Invalid ip longhorn:$longhornIP"; return 1; }
      # 检查longhornIP是否已存在
      if [[ `sed -n '/^\[longhorn/,/^\[chrony/p' "$BASE/clusters/ai/hosts"|grep $longhornIP` ]];then
        logger warn "longhorn $longhornIP already existed in $BASE/clusters/ai/hosts"
      else
        rawDisk=$(grep -r 'STORAGE_NODE_IP' $BASE/ai.config |grep $longhornIP |cut -d'=' -f4)
        sed -i "/\[longhorn/a $longhornIP RAW_DISK=$rawDisk" "$BASE/clusters/ai/hosts"
      fi
    done
  fi


  #从配置文件获取EFK IP
  if [[ $edition == professional ]];then
    efkIP=$(grep -r 'EFK_NODE_IP' $BASE/ai.config |cut -d'=' -f2|awk '{print $1}')
    # 检查efkIP正则表达式
    [[ $efkIP =~ ^(2(5[0-5]{1}|[0-4][0-9]{1})|[0-1]?[0-9]{1,2})(\.(2(5[0-5]{1}|[0-4][0-9]{1})|[0-1]?[0-9]{1,2})){3}$ ]] || { logger error "Invalid ip efk:$efkIP"; return 1; }
    sed -i "s/__efk_ip__/$efkIP/g" "$BASE/clusters/ai/config.yml"
    sed -i 's/efk_install: "no"/efk_install: "yes"/g' "$BASE/clusters/ai/config.yml"
  fi

  #从配置文件获取PROMETHEUS IP
  prometheusIP=$(grep -r 'PROMETHEUS_IP' $BASE/ai.config |cut -d'=' -f2|awk '{print $1}')
  # 检查prometheusIP正则表达式
  [[ $prometheusIP =~ ^(2(5[0-5]{1}|[0-4][0-9]{1})|[0-1]?[0-9]{1,2})(\.(2(5[0-5]{1}|[0-4][0-9]{1})|[0-1]?[0-9]{1,2})){3}$ ]] || { logger error "Invalid ip prometheus:$prometheusIP"; return 1; }
  sed -i "s/__prometheus_ip__/$prometheusIP/g" "$BASE/clusters/ai/config.yml"

  #从配置文件获取服务器ssh端口
  sshPort=$(grep -r 'SSH_PORT' $BASE/ai.config |cut -d'=' -f2|awk '{print $1}')
  sed -i "s/__ansible_ssh_port__/$sshPort/g" "$BASE/clusters/ai/hosts"

  #从配置文件获取nodeport range
  nodeportRange=$(grep -r 'NODE_PORT_RANGE' $BASE/ai.config |cut -d'=' -f2|awk '{print $1}')
  sed -i "s/__node_port_range__/$nodeportRange/g" "$BASE/clusters/ai/hosts"

  #从配置文件获取cluster cidr
  clusterCidr=$(grep -r 'CLUSTER_CIDR' $BASE/ai.config |cut -d'=' -f2|awk '{print $1}')
  sed -i "s#__cluster_cidr__#$clusterCidr#g" "$BASE/clusters/ai/hosts"

  #从配置文件获取harbor网络
  harborNetwork=$(grep -r 'HARBOR_NETWORK' $BASE/ai.config |cut -d'=' -f2|awk '{print $1}')
  harborClairNetwork=$(grep -r 'HARBOR_CLAIR_NETWORK' $BASE/ai.config |cut -d'=' -f2|awk '{print $1}')
  harborChartmuseumNetwork=$(grep -r 'HARBOR_CHARTMUSEUM_NETWORK' $BASE/ai.config |cut -d'=' -f2|awk '{print $1}')
  sed -i "s#__harbor_network__#$harborNetwork#g" "$BASE/clusters/ai/config.yml"
  sed -i "s#__harbor_clair_network__#$harborClairNetwork#g" "$BASE/clusters/ai/config.yml"
  sed -i "s#__harbor_chartmuseum_network__#$harborChartmuseumNetwork#g" "$BASE/clusters/ai/config.yml"
}

function new() {
    # check if already existed
    rm -f clusters/ai/hosts
    rm -f clusters/ai/config.yml
    cp example/hosts.multi-node "clusters/ai/hosts"
    sed -i "s/_cluster_name_/ai/g" "clusters/ai/hosts"
    cp example/config.yml "clusters/ai/config.yml"

    logger debug "set version of common plugins"
    calicoVer=$(grep 'calicoVer=' ezdown|cut -d'=' -f2)
    ciliumVer=$(grep 'ciliumVer=' ezdown|cut -d'=' -f2)
    flannelVer=$(grep 'flannelVer=' ezdown|cut -d'=' -f2)
    kubeRouterVer=$(grep 'kubeRouterVer=' ezdown|cut -d'=' -f2)
    kubeOvnVer=$(grep 'kubeOvnVer=' ezdown|cut -d'=' -f2)
    corednsVer=$(grep 'corednsVer=' ezdown|cut -d'=' -f2)
    dnsNodeCacheVer=$(grep 'dnsNodeCacheVer=' ezdown|cut -d'=' -f2)
    dashboardVer=$(grep 'dashboardVer=' ezdown|cut -d'=' -f2)
    dashboardMetricsScraperVer=$(grep 'dashboardMetricsScraperVer=' ezdown|cut -d'=' -f2)
    metricsVer=$(grep 'metricsVer=' ezdown|cut -d'=' -f2)
    nfsProvisionerVer=$(grep 'nfsProvisionerVer=' ezdown|cut -d'=' -f2)
    promChartVer=$(grep 'promChartVer=' ezdown|cut -d'=' -f2)
    traefikChartVer=$(grep 'traefikChartVer=' ezdown|cut -d'=' -f2)
    harborVer=$(grep 'HARBOR_VER=' ezdown|cut -d'=' -f2)
    elasticsearchVer=$(grep 'elasticsearchVer=' ezdown|cut -d'=' -f2)
    fluentdVer=$(grep 'fluentdVer=' ezdown|cut -d'=' -f2)
    kibanaVer=$(grep 'kibanaVer=' ezdown|cut -d'=' -f2)
    alpineVer=$(grep 'alpineVer=' ezdown|cut -d'=' -f2)
    registryMirror=true

    grep registry-mirrors /etc/docker/daemon.json > /dev/null 2>&1 || { logger debug "disable registry mirrors"; registryMirror=false; }

    sed -i -e "s/__flannel__/$flannelVer/g" \
           -e "s/__calico__/$calicoVer/g" \
           -e "s/__cilium__/$ciliumVer/g" \
           -e "s/__kube_ovn__/$kubeOvnVer/g" \
           -e "s/__kube_router__/$kubeRouterVer/g" \
           -e "s/__coredns__/$corednsVer/g" \
           -e "s/__dns_node_cache__/$dnsNodeCacheVer/g" \
           -e "s/__dashboard__/$dashboardVer/g" \
           -e "s/__dash_metrics__/$dashboardMetricsScraperVer/g" \
           -e "s/__nfs_provisioner__/$nfsProvisionerVer/g" \
	   -e "s/__elasticsearch__/$elasticsearchVer/g" \
           -e "s/__fluentd__/$fluentdVer/g" \
           -e "s/__kibana__/$kibanaVer/g" \
           -e "s/__alpine__/$alpineVer/g" \
           -e "s/__prom_chart__/$promChartVer/g" \
           -e "s/__traefik_chart__/$traefikChartVer/g" \
           -e "s/__harbor__/$harborVer/g" \
           -e "s/^ENABLE_MIRROR_REGISTRY.*$/ENABLE_MIRROR_REGISTRY: $registryMirror/g" \
           -e "s/__metrics__/$metricsVer/g" "clusters/ai/config.yml"
}

function main() {
  BASE=$(grep -E 'BASE' ./ai.config|cut -d'=' -f2)
  new_cluster
  ansible-playbook -i "clusters/ai/hosts" -e "@clusters/ai/config.yml" "playbooks/200.cluster-migration.yml" || return 1
}

main
