#!/bin/bash

LOG_FILE='./es_backup.log'

_color_red=$(TERM=xterm-256color tput setaf 1)
_color_normal=$(TERM=xterm-256color tput sgr0)
_color_blue=$(TERM=xterm-256color tput setaf 4)
_color_green=$(TERM=xterm-256color tput setaf 2)
_color_yellow=$(TERM=xterm-256color tput setaf 3)

function log_important()
{
    local ts=$(date -Iseconds)
    # to log file
    echo -e "$ts [IMPORTANT] $@" >> $LOG_FILE
    # to console (stderr)
    >&2 echo -e "${_color_yellow}$ts [IMPORTANT] $@${_color_normal}"
    return 0
}

function log_info()
{
    local ts=$(date -Iseconds)
    # to log file
    echo -e "$ts [INFO] $@" >> $LOG_FILE
    # to console (stderr)
    >&2 echo -e "$ts [INFO] $@"
    return 0
}

function log_error()
{
    local ts=$(date -Iseconds)
    # to log file
    echo -e "$ts [ERROR] $@" >> $LOG_FILE
    # to console (stderr)
    >&2 echo -e "${_color_red}$ts [ERROR] $@${_color_normal}"
    return 0
}

function log_debug()
{
    local ts=$(date -Iseconds)
    if [ $_DEBUG -eq 1 ]; then
        # to log file
        echo -e "$ts [DEBUG] $@" >> $LOG_FILE
        # to console (stderr)
        >&2 echo -e "$ts [DEBUG] $@"
    fi
    return 0
}

function check_middleware_proxy(){
    if ! /usr/sbin/ss -lnpt | grep 30003 &> /dev/null;then
        log_error "middleware proxy需要开启，通过proxy访问容器ES实例，请在compose中调整 replicas为1 ..."
        exit 1000
    fi
    log_info "middleware proxy已开启, 监听端口30003"
}

function check_es_status(){
    if check_middleware_proxy;then
        if curl -s $ES_URL/_cat/health | grep green &> /dev/null;then
            log_info "Elasticsearch status is green, check OK ..."
        elif curl -s $ES_URL/_cat/health | grep red &> /dev/null;then
            log_info "Elasticsearch status check is red, 不能进行快照 ..."
            exit 1001
        elif curl -s $ES_URL/_cat/health | grep yellow &> /dev/null;then
            if [ $DEPLOY_MODE == "single" ];then
                ## 单机状态ES 因有一个副本配置，不能进行分配到其他节点，故只有50% 的分片活跃，也就是主分片数量
                local result=$(curl -s $ES_URL/_cat/health | awk '$NF != "50.0%" {print $0}')
                if [ ! -z "$result" ];then
                    log_important "Elasticsearch 单机部署模式，状态异常，请进行检查，result: $result ..."
                fi
                log_info "Elasticsearch status yellow, check OK ..."
            fi
        fi
    fi
}

function create_snapshot_warehouse(){
    if [ $(curl -sIL -w "%{http_code}\n" -o /dev/null --location --request GET "$ES_URL/_snapshot/macrowing") != 200 ];then
    	log_info "Elasticsearch snapshots warehouse macrowing not exist, create it ... "
        curl -L -X POST $ES_URL/_snapshot/macrowing -H 'Content-Type: application/json' -d '
        {
            "type": "fs",
            "settings": {
                "location": "edoc2_backup"
            }
        }
        '
    fi
}

function check_local_snapshot_status(){
    log_info "check_local_snapshot_status ..."
    snapshot_json=$(curl -s ${ES_URL}/_snapshot/macrowing/_all)
    len=$(echo ${snapshot_json}|jq '.snapshots|length')
    end=$(($len-2))     ## 本地保留一个
    if [ "${len}" != 0 ];then
        for index in $(seq 0 ${end})
        do
           if [ "$(echo ${snapshot_json} | jq '.snapshots[0].state' | sed 's/"//g')" == "SUCCESS" ];then
                snapshot=$(echo ${snapshot_json} | jq ".snapshots[${index}].snapshot" | sed 's/"//g')
                log_info "clean history snapshot: $snapshot ..."
                curl --location --request DELETE ${ES_URL}/_snapshot/macrowing/$snapshot
           else
                log_error "Elasticsearch has unfinished snapshot!!"
                exit 2000
           fi
        done
    fi
}

# function create_snapshot(){
#     log_info "create_snapshot ..."
#     create_snapshot_warehouse ${ES_URL}
#     curl -sL -X PUT "${ES_URL}/_snapshot/macrowing/${1}?wait_for_completion=true" &> /dev/null
#     if [ $(curl -sL -X GET "${ES_URL}/_snapshot/macrowing/${1}" | jq .snapshots[0].state | sed 's/"//g') == "SUCCESS" ];then
#         log_info "macrowing snapshots ${1} is SUCCESS.."
#     else
#         log_error "macrowing snapshot ${1} is failed"
#         exit 2001
#     fi
# }

function create_snapshot(){
    log_info "create_snapshot ..."
    create_snapshot_warehouse ${ES_URL}
    curl -sL -X PUT "${ES_URL}/_snapshot/macrowing/${1}" &> /dev/null
    while true; do
        state=$(curl -sL -X GET "${ES_URL}/_snapshot/macrowing/${1}" | jq .snapshots[0].state | sed 's/"//g')
        if [ "$state" == "IN_PROGRESS" ];then
            log_info "macrowing snapshots ${1} is IN_PROGRESS.."
            sleep 10
            continue
        elif [ "$state" == "SUCCESS" ];then
            log_info "macrowing snapshots ${1} is SUCCESS.."
            break
        else
            log_info "macrowing snapshots ${1} is $state.."
            exit 2001
        fi
    done
}

function rsync_snapshot_to_backup_server(){
    rsync -avzP --delete ${LOCAL_BACKUP_DIR} edoc2_backup@${REMOTE_BACKUP_SERVER}::es/ --password-file=/etc/rsync_client.password &>/dev/null
    #rsync -avzP --delete ${LOCAL_BACKUP_DIR} root@${REMOTE_BACKUP_SERVER}:${REMOTE_BACKUP_DIR} &> /dev/null
    if [ $? -eq 0 ];then
        log_info "ES rsync backup success."
    else
        log_error "ES rsync backup failed."
    fi
}

# 定时脚本执行的ip
# LOCAL_IP=__LOCAL_IP__
LOCAL_IP=192.168.251.185
# 容器映射到 宿主机的 备份目录( 单机模式配置 )
LOCAL_BACKUP_DIR=__LOCAL_BACKUP_DIR__
# 单机进行快照的异机备份ip( 单机模式配置 )
REMOTE_BACKUP_SERVER=__REMOTE_BACKUP_SERVER__
# ES的部署模式 single 或 cluster,
# DEPLOY_MODE=__DEPLOY_MODE__
DEPLOY_MODE=cluster
###############################################################
# 为 cluster 时需要把宿主机的 es 数据backup目录挂载到 NFS共享存储 #
###############################################################

ES_URL=http://$LOCAL_IP:30003
# ES_URL=http://192.168.251.41:30003
SNAPSHOT_NAME=snapshot_all_indices_$(date +'%Y%m%d%H%M%S')

function main(){
    check_es_status
    if [ "$DEPLOY_MODE"x == "single"x ];then
        create_snapshot $SNAPSHOT_NAME
        rsync_snapshot_to_backup_server
        check_local_snapshot_status
    elif [ "$DEPLOY_MODE"x == "cluster"x ];then
        create_snapshot $SNAPSHOT_NAME
    fi
}

main
