#!/bin/bash
# утилитный скрипт контроля портов
# применялся для разработки методов контроля портов отдельных приложений
# Тренировки с awk
#
# AVP 2020


red=`tput setaf 1`
green=`tput setaf 2`
reset=`tput sgr0`

# Прервать установку при ошибках
set -e

# Контроль открытого порта для определённой службы в режиме TCP (+ контроль LISTEN)
# Пример вызова функции: check_port_service_tcp "8080" "nginx" "nginx" result_var
# Пример вызова функции: check_port_service_tcp "8080" "java" "tomcat" result_var
# $1 - номер порта (строкой);
# $2 - название сервиса (java - для всех java приложений);
# $3 - описание сервиса, например, 'tomcat' или 'Captive Portal' для Java приложения;
# $4 - В результат будет помещена строка: "0" - это OK (порт открыт) или "1" - это ошибка (порта нет)
function check_port_service_tcp() {
    local __resultvar="$4"
    local myresult='0'
    local port=":$1"
    local service="$2"
    local service_descr="$3"
    local variable=`sudo netstat -pna | awk '{if ($1 ~ /tcp/ && $4 ~ "'"$port"'" && $6 ~ /LISTEN/ && $7 ~ "'"$service"'") print "passed"}'`
    if [[ $variable =~ "passed" ]]; then
        echo "${green}Checking tcp port '$1' for application '$2' ($service_descr) - passed${reset}"
        myresult='0'
    else
        echo "${red}Checking tcp port '$1' for application '$2' ($service_descr) - error${reset}"
        myresult='1'
    fi
    eval ${__resultvar}="'$myresult'"
}

# Контроль открытого порта для определённой службы в режиме UDP (нет LISTEN)
# Пример вызова функции: check_port_service_udp "8080" "nginx" "nginx" result_var
# Пример вызова функции: check_port_service_udp "8080" "java" "tomcat" result_var
# $1 - номер порта (строкой);
# $2 - название сервиса (java - для всех java приложений);
# $3 - описание сервиса, например, 'tomcat' или 'Captive Portal' для Java приложения;
# $4 - В результат будет помещена строка: "0" - это OK (порт открыт) или "1" - это ошибка (порта нет)
function check_port_service_udp() {
    local __resultvar="$4"
    local myresult=0
    local port=":$1"
    local service="$2"
    local service_descr="$3"
    local variable=`sudo netstat -pna | awk '{if ($1 ~ /udp/ && $4 ~ "'"$port"'" && $6 ~ "'"$service"'") print "passed"}'`
    if [[ $variable =~ "passed" ]]; then
        echo "${green}Checking udp port '$1' for application '$2' ($service_descr) - passed${reset}"
        myresult="0"
    else
        echo "${red}Checking udp port '$1' for application '$2' ($service_descr) - error${reset}"
        myresult="1"
    fi
    eval ${__resultvar}="'$myresult'"
}

# Функция для финальной проверка всех портов однохостовой инсталляции
# Считает количество фатальных ошибок (не все порты критичные)
# Если количество фатальных ошибок больше нуля, то после отчёта скрипт прервётся и выйдет с "-1"
function main_ports_test() {
    local FATAL=0
    echo ""
    echo "Start TCP/UDP port checking for all services.."

    # == databases ==
    check_port_service_tcp "3306" "mysqld" "Server MySQL" var
    if [[ "$var" != "0" ]]; then
        FATAL=$((FATAL+1))
    fi

    check_port_service_tcp "27017" "mongo" "MongoDB server" var
    if [[ "$var" != "0" ]]; then
        FATAL=$((FATAL+1))
    fi

    # == EMS ==
    check_port_service_tcp "9310" "java" "EMS-server Applet API " var
    if [[ "$var" != "0" ]]; then
        FATAL=$((FATAL+1))
    fi

    check_port_service_udp "162" "java" "EMS server SNMP API" var
    if [[ "$var" != "0" ]]; then
        FATAL=$((FATAL+1))
    fi

    # == tomcat ==
    check_port_service_tcp "8081" "java" "tomcat (LK B2B, NBI, EMS applet)" var
    if [[ "$var" != "0" ]]; then
        FATAL=$((FATAL+1))
    fi

    # == nginx ==
    check_port_service_tcp "8080" "nginx" "Nginx proxy server" var
    if [[ "$var" != "0" ]]; then
        FATAL=$((FATAL+1))
    fi

    # == Portal, Portal Constructor, NGW==
    check_port_service_tcp "9000" "java" "Captive Portal, Portal Group" var
    if [[ "$var" != "0" ]]; then
        FATAL=$((FATAL+1))
    fi

    check_port_service_tcp "9001" "java" "Portal Constructor, Portal Group" var
    if [[ "$var" != "0" ]]; then
        FATAL=$((FATAL+1))
    fi

    check_port_service_tcp "8040" "java" "eltex-notification-gw, Portal Group" var
    if [[ "$var" != "0" ]]; then
        FATAL=$((FATAL+1))
    fi

    check_port_service_tcp "8090" "java" "eltex-apb, Portal Group" var
    if [[ "$var" != "0" ]]; then
        FATAL=$((FATAL+1))
    fi

    check_port_service_tcp "9099" "java" "eltex-logging-service, Portal Group" var
    if [[ "$var" != "0" ]]; then
        FATAL=$((FATAL+1))
    fi

    check_port_service_tcp "9099" "java" "eltex-mercury service, Portal Group" var
    if [[ "$var" != "0" ]]; then
        FATAL=$((FATAL+1))
    fi

    # == PCRF ==
    check_port_service_tcp "7070" "java" "PCRF monitoring API" var
    check_port_service_tcp "7080" "java" "PCRF RADIUS API" var
    if [[ "$var" != "0" ]]; then
        FATAL=$((FATAL+1))
    fi
    check_port_service_tcp "5701" "java" "PCRF Hazelcast API" var
    check_port_service_udp "1813" "java" "PCRF, RADIUS accounting API" var
    if [[ "$var" != "0" ]]; then
        FATAL=$((FATAL+1))
    fi

    # == RADIUS, Auth Service ==
    check_port_service_udp "1812" "eltex-radius" "RADIUS, auth API" var
    if [[ "$var" != "0" ]]; then
        FATAL=$((FATAL+1))
    fi

    check_port_service_udp "21812" "eltex-radius" "Eltex Auth Service, auth API" var
    if [[ "$var" != "0" ]]; then
        FATAL=$((FATAL+1))
    fi
    check_port_service_udp "21813" "eltex-radius" "Eltex Auth Service, accounting API" var

    # == Other ==
    check_port_service_udp "514" "syslog" "Linux syslog server" var
    check_port_service_udp "69" "tftp" "Linux TFTP server" var

    echo ""
    # Финальный контроль фатальных ошибок
    if [ $FATAL != 0 ]; then
        echo "${red}Found $FATAL errors, script aborted!${reset}"
        exit -1
    else
        echo "${green}> Main core ports are tested successfully!${reset}"
    fi
    echo ""
}

# Функция для контроля портов работы ядра в режиме OTT
function ott_ports_test() {
    local FATAL=0
    echo ""
    echo "Start TCP/UDP port checking for OTT services.."

    check_port_service_tcp "8088" "java" "eltex-ott-mac-checker, OTT" var
    if [[ "$var" != "0" ]]; then
        FATAL=$((FATAL+1))
    fi

    check_port_service_tcp "8098" "java" "eltex-paul, password generator, OTT" var
    if [[ "$var" != "0" ]]; then
        FATAL=$((FATAL+1))
    fi

    check_port_service_tcp "8043" "java" "eltex-wifi-sa, service activator HTTPS API, OTT" var
    if [[ "$var" != "0" ]]; then
        FATAL=$((FATAL+1))
    fi

    echo ""
    # Финальный контроль фатальных ошибок
    if [ $FATAL != 0 ]; then
        echo "${red}Found $FATAL errors, script aborted!${reset}"
        exit -1
    else
        echo "${green}> OTT ports are tested successfully!${reset}"
    fi
    echo ""
}

# Функция для контроля портов работы ядра в режиме Clickhouse
function clickhouse_ports_test() {
    local FATAL=0
    echo ""
    echo "Start TCP/UDP port checking for Clickhouse database and services.."

    # == Clickhouse ==
    check_port_service_tcp "9003" "clickhouse" "Clickhouse client API" var
    if [[ "$var" != "0" ]]; then
        FATAL=$((FATAL+1))
    fi

    check_port_service_tcp "9009" "clickhouse" "Clickhouse inter serever API" var
    if [[ "$var" != "0" ]]; then
        FATAL=$((FATAL+1))
    fi

    check_port_service_tcp "8123" "clickhouse" "Clickhouse HTTP API" var
    if [[ "$var" != "0" ]]; then
        FATAL=$((FATAL+1))
    fi

    check_port_service_tcp "9070" "eltex-bonnie" "Bonnie GRPC API, Clickhouse" var
    if [[ "$var" != "0" ]]; then
        FATAL=$((FATAL+1))
    fi

    echo ""
    # Финальный контроль фатальных ошибок
    if [ $FATAL != 0 ]; then
        echo "${red}Found $FATAL errors, script aborted!${reset}"
        exit -1
    else
        echo "${green}> Clickhouse ports are tested successfully!${reset}"
    fi
    echo ""
}

main_ports_test
#ott_ports_test
#clickhouse_ports_test

exit 0
