#!/bin/bash
print_red () {
    echo -e "\033[91m"$1"\033[0m"
}
print_yellow () {
    echo -e "\033[93m"$1"\033[0m"
}
write_ka_cfg ()
{
cat <<EOF > /etc/keepalived/keepalived.conf
vrrp_script check_wnam {
 script "/home/wnam/check_wnam.sh"
 interval 10
 fall 2
 rise 2
}
vrrp_instance wnam_instance {
 interface $ip_dev
track_interface {
 $ip_dev
 }
state $state
 virtual_router_id 50
 priority $priority
 preempt
unicast_src_ip $src_ip
 unicast_peer {
 $peer_ip
 }
virtual_ipaddress {
 $virt_ip dev $ip_dev
 }
track_script {
 check_wnam
 }
notify /home/wnam/keepalived.state.sh
}
EOF
}
valid_ip()
{
    local  ip=$1
    local  stat=1

    if [[ $ip =~ ^[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}$ ]]; then
        OIFS=$IFS
        IFS='.'
        ip=($ip)
        IFS=$OIFS
        [[ ${ip[0]} -le 255 && ${ip[1]} -le 255 \
            && ${ip[2]} -le 255 && ${ip[3]} -le 255 ]]
        stat=$?
    fi
    return $stat
}
ka_cfg=true
while true; do
    IFS=$'\n' read -r -d '' master_ip slave_ip cluster_ip  < <(dialog	--stdout \
        --title "Настройка кластера" \
        --backtitle "Настройка параметров сервера" \
        --ok-label "Да" \
        --form "Параметры" 15 70 0 \
        "IP-адрес главного узла кластера (MASTER):"      1 1     ""      1 44 16 0 \
        "IP-адрес резервного узла кластера (SLAVE):" 2 1	  ""      2 44 16 0 \
        "Кластерный IP-адрес:"      3 1	    ""      3 44 16 0 \
        )
    if [ -z $cluster_ip ]; then
        dialog  --backtitle "Настройка параметров сервера" \
            --title "Настройка кластера" \
            --infobox  "Кластерный IP не указан.\nСлужба keepalived не будет настроена." 5 41
        cluster_ip="240.240.240.240"
        ka_cfg=false
    fi
    if valid_ip $master_ip && valid_ip $slave_ip && valid_ip $cluster_ip; then
        ping $cluster_ip -c1 > /dev/null 2>&1
        if [ $? -ne 0 ]; then
            virt_ip=$cluster_ip
            break
        else
            if (dialog  --backtitle "Настройка параметров сервера" \
                        --yes-label "Продолжить" \
                        --defaultno \
                        --yesno "Кластерный IP адрес уже используется в сети.\nЕсли он уже был настроен ранее на другом узле кластера, можно продолжать настройку." 10 60) then
                virt_ip=$cluster_ip
                break
            else
                exit
            fi
            #exit
        fi
    else
        dialog  --backtitle "Настройка параметров сервера" \
                --title "Настройка кластера" \
                --colors \
                --msgbox  "\n\Zb\Z1Введены некорректные данные\Zn" 7 35
    fi
done
ips=($(hostname -I))
ok=false
role=""
for ip in "${ips[@]}"
do
    #echo $ip
    if [ $ip == $master_ip ]; then
        state="MASTER"
        priority=100
        src_ip=$master_ip
        peer_ip=$slave_ip
        node_id=1
        ok=true
        role="master"
        break
    elif [ $ip == $slave_ip ]; then
        state="BACKUP"
        priority=50
        src_ip=$slave_ip
        peer_ip=$master_ip
        node_id=2
        ok=true
        break
    fi
done
if [ ! $ok ]; then
    dialog  --backtitle "Настройка параметров сервера" \
            --title "Настройка кластера" \
            --colors \
            --msgbox  "\n\Zb\Z1IP-адрес не найден в системе\Zn" 7 35
    exit
fi
ping $peer_ip -c1 > /dev/null 2>&1
if [ $? -ne 0 ]; then
    dialog  --backtitle "Настройка параметров сервера" \
        --title "Настройка кластера" \
        --colors \
        --msgbox  "\n\Zb\Z1Второй узел кластера недоступен\Zn" 7 35
    exit
fi
ip_dev=$(ip -br -4 a sh | grep $src_ip | awk '{print $1}')
if $ka_cfg; then
if [[ -z $(which keepalived) ]]; then
    dialog  --backtitle "Настройка параметров сервера" \
        --title "Настройка кластера" \
        --colors \
        --infobox  "\n\Zb\Z3Устанавливается keepalived\Zn" 5 33
    apt update
    apt -y install keepalived
fi
if [ -f /etc/keepalived/keepalived.conf ]; then
    cp /etc/keepalived/keepalived.conf /etc/keepalived/keepalived.conf.bak
fi
write_ka_cfg
if [ ! -f /home/wnam/check_wnam.sh ]; then
    cat <<EOF > /home/wnam/check_wnam.sh
#!/bin/bash
# Check if wnam is running, return 1 if not.
# Used by keepalived to initiate a failover in case WNAM is down
WNAM_STATUS=\$(/bin/ps ax | grep -w wnam.war | grep -w java)
if [ "\$WNAM_STATUS" != "" ]
then
 exit 0
else
 logger "WNAM is NOT running. Setting keepalived state to FAULT."
 exit 1
fi
EOF
chmod u+x /home/wnam/check_wnam.sh
fi
if [ ! -f /home/wnam/keepalived.state.sh ]; then
cat <<EOF > /home/wnam/keepalived.state.sh
#!/bin/bash
TYPE=\$1
NAME=\$2
STATE=\$3
echo \$STATE > /var/run/keepalived.state
#if [ $STATE == "MASTER" ]; then
#    /sbin/ip route delete NET/MASK #Эта строка нужна если WNAM и NAS находятся в одной подсети. Здесь указать нужную подсеть.
#    /sbin/ip route add NAS_IP dev IF src CLUSTER_IP #если WNAM и NAS в одной подсети
#    /sbin/ip route add NAS_IP via GW src CLUSTER_IP #если WNAM и NAS в разных подсетях
#fi
EOF
touch /var/run/keepalived.state
chmod 644 /var/run/keepalived.state
chmod u+x /home/wnam/keepalived.state.sh
fi
systemctl restart keepalived
systemctl is-active --quiet keepalived || dialog  --backtitle "Настройка параметров сервера" \
        --title "Настройка кластера" \
        --colors \
        --infobox  "\n\Zb\Z1Служба keepalived не запустилась\Zn" 5 33
fi
mkdir tmp
cd tmp
if [ ! -d /opt/kafka ]; then
    dialog  --backtitle "Настройка параметров сервера" \
        --title "Настройка кластера" \
        --colors \
        --infobox  "\n\Zb\Z3Устанавливается kafka\Zn" 5 33
    wget https://downloads.apache.org/kafka/3.5.2/kafka_2.13-3.5.2.tgz
    tar xzf kafka_2.13-3.5.2.tgz
    mv kafka_2.13-3.5.2/ /opt/kafka
    cd ..
    rm -rf tmp
    chown -R wnam:wnam /opt/kafka
    cat <<EOF > /lib/systemd/system/kafka.service
[Unit]
Requires=network.target remote-fs.target
After=network.target remote-fs.target

[Service]
Type=simple
User=wnam
ExecStart=/opt/kafka/bin/kafka-server-start.sh /opt/kafka/config/kraft/server.properties
ExecStop=/opt/kafka/bin/kafka-server-stop.sh
TimeoutSec=30
Restart=always
RestartSec=20s

[Install]
WantedBy=multi-user.target
EOF
fi
mv /opt/kafka/config/kraft/server.properties /opt/kafka/config/kraft/server.properties.bak
cat <<EOF > /opt/kafka/config/kraft/server.properties
process.roles=broker,controller
node.id=$node_id
controller.quorum.voters=1@$master_ip:9093,2@$slave_ip:9093
listeners=PLAINTEXT://$src_ip:9092,CONTROLLER://$src_ip:9093
inter.broker.listener.name=PLAINTEXT
advertised.listeners=PLAINTEXT://$src_ip:9092
controller.listener.names=CONTROLLER
listener.security.protocol.map=CONTROLLER:PLAINTEXT,PLAINTEXT:PLAINTEXT,SSL:SSL,SASL_PLAINTEXT:SASL_PLAINTEXT,SASL_SSL:SASL_SSL
num.network.threads=3
num.io.threads=8
socket.send.buffer.bytes=102400
socket.receive.buffer.bytes=102400
socket.request.max.bytes=104857600
log.dirs=/opt/kafka/kraft-combined-logs
num.partitions=1
num.recovery.threads.per.data.dir=1
offsets.topic.replication.factor=2
transaction.state.log.replication.factor=2
transaction.state.log.min.isr=1
# Параметры влияющие на потребление дискового пространства, а также на объем и время хранимых данных 
# Количество часов хранения файла журнала перед его удалением (в часах), по умолчанию 168
log.retention.hours=72
# Политика хранения журналов, основанная на размере. Сегменты удаляются из журнала до тех пор, пока оставшиеся сегменты не опустятся ниже log.retention.bytes.
# Функционирует независимо от log.retention.hours. Значение по умолчанию -1
log.retention.bytes=1073741824
# Максимальный размер файла сегмента журнала. Когда этот размер будет достигнут, будет создан новый сегмент журнала. По умолчанию 1073741824
log.segment.bytes=268435456
# Интервал, с которым проверяются сегменты журнала на предмет возможности их удаления в соответствии с политиками хранения
log.retention.check.interval.ms=300000
# При первоначальной регистрации в кворуме контроллера указывается количество миллисекунд, которое необходимо подождать, прежде чем объявить о сбое и выйти из процесса посредника.
initial.broker.registration.timeout.ms = 60000
EOF
cd /opt/kafka
/opt/kafka/bin/kafka-storage.sh format -t YlorudlrR4qn5YNMcgX4zg -c /opt/kafka/config/kraft/server.properties
chown -R wnam:wnam /opt/kafka
sed -r -i 's/(INFO|TRACE|DEBUG)/WARN/g' /opt/kafka/config/log4j.properties
systemctl daemon-reload
systemctl enable kafka
systemctl start kafka
#systemctl is-active --quiet kafka || print_red "Служба Kafka не запустилась"
systemctl is-active --quiet kafka || dialog  --backtitle "Настройка параметров сервера" \
        --title "Настройка кластера" \
        --colors \
        --infobox  "\n\Zb\Z1Служба Kafka не запустилась\Zn" 5 33
mv /home/wnam/application.yaml /home/wnam/application.yaml.bak
cat <<EOF > /home/wnam/application.yaml
server:
  forward-headers-strategy: native
  tomcat:
    remoteip:
      protocol-header: "X-Forwarded-Proto"
      remote-ip-header: "X-Forwarded-For"
    basedir: .
    accesslog.enabled: true
  port: 8080
  address: 0.0.0.0

spring:
  application:
    name: WNAM
  mvc:
    view:
      prefix: /WEB-INF/jsp/
      suffix: .jsp
  data:
    mongodb:
      uri: mongodb://127.0.0.1:27017/wnam_db
  kafka:
    bootstrap-servers: $master_ip:9092,$slave_ip:9092

netams:
 wnam:
  cluster:
    # optional, default false. Использовать kafka
    kafka_enabled: true
    # optional default false, отвечает за синхронизацию данных, между разными кластерами wnam, если true синхронизируются все коллекции, если false только конфигурационные параметры
    full_sync: true
    # optional, default 1 количество реплик (серверов) в кластере kafka
    replicas: 2
    # optional, default true. Пытаться выбрать лидера в kafka при падении брокеров kafka
    unclean_election: true
    # optional, default empty.Если master, то все задачи выполняются на этом сервере,
    role: $role
    # optional, default 'true'. Использовать локальный кэш. Может быть true или false, отключать кэш следует только в конфигурации когда нет кафки и больше одного сервера wnam
    use_cache: true
    # optional, default false. Показывает кнопку для принудительного запуска синхронизации одного узла кластера с другого
    show_sync: false
EOF
systemctl restart wnam
systemctl is-active --quiet wnam || dialog  --backtitle "Настройка параметров сервера" \
        --title "Настройка кластера" \
        --colors \
        --infobox  "\n\Zb\Z1Служба WNAM не запустилась\Zn" 5 33
