#!/bin/bash

# Скрипт помогает установить пакеты EMS на один сервер
# Предварительно устанавливает Java, mysql-server, curl, libcurl и прочие необходимые пакеты из зависимостей
# Затем последовательно устанавливает все нужные пакеты комплекса:
#
# eltex-ems-db             : Разворачивает схему в БД MySQL для EMS
# eltex-ems                : Серверная и клиентская часть СУ EMS
# eltex-oui-list           : Пакет с информацией соответствия "device MAC : VendorName"

# Версия: EMS 3.36
# Целевая ОС: voronezh (astra linux 1.7.4)
# Автор: Абаренов ВП
# ООО Предприятие Элтекс
# Новосибирск, 2022

# Модификаторы запуска скрипта:
# --update-eltex-packages    : пропустить установку системных пакетов. только установка пакетов из репозитория eltex

# Ответы для автоматической установки
# Измените при необходимости

# Имя пользователя администратора MySQL
export ANSWER_SOFTWLC_MYSQL_USER=root
# Пароль администратора MySQL
export ANSWER_SOFTWLC_MYSQL_PASSWORD=root
# Имя пользователя администратора SoftWLC
export ANSWER_AUTH_SERVICE_ADMIN_USER=admin
# Пароль администратора SoftWLC
export ANSWER_AUTH_SERVICE_ADMIN_PASSWORD=password
# Пароль служебного пользователя SoftWLC (softwlc_service)
export ANSWER_SOFTWLC_SERVICE_USER_PASSWORD=softwlc
# Корневой домен
export ANSWER_SOFTWLC_ROOT_DOMAIN=root
# Язык EMS по умолчанию: 1 - русский, 2 - английский
export ANSWER_EMS_LANG=1
# Максимальное количество ОЗУ, выделяемое EMS (в МБ)
export ANSWER_EMS_MAX_HEAP=1024
# Код создаваемого тарифа
export ANSWER_RADIUS_TARIFF_CODE=default
# Генерировать ли сертификат для сервера RADIUS
export ANSWER_NBI_MAKE_SERVER_CERTIFICATE=1
# Срок действия серверного сертификата RADIUS
export ANSWER_NBI_SERVER_CERTIFICATE_PERIOD=3650
# Пароль от закрытого ключа серверного сертификата RADIUS
export ANSWER_NBI_SERVER_CERTIFICATE_KEY=1234

# Не рекомендуется редактировать
export ANSWER_SOFTWLC_LOCAL=1
export ANSWER_EMS_REPLACE_CONF=1
export ANSWER_EMS_ACCESS_TYPE_DOMAIN=1

# Настройка автоматического ответа на интерактивные вопросы
export DEBIAN_FRONTEND="noninteractive"

red=$(tput setaf 1)
green=$(tput setaf 2)
reset=$(tput sgr 0)

# Public Eltex production repo
ELTEX_PUBLIC_REPO="http://archive.eltex-co.ru/wireless"
# Private (internal) repo
ELTEX_PRIVATE_REPO="http://lab3-repo.eltex.loc:2088"
# Переменная, которая является рабочей. Внутри скрипта работа идёт с ней в зависимости от параметров вызова скрипта
ELTEX_REPO=${ELTEX_PUBLIC_REPO}
ASTRA_REPO="https://download.astralinux.ru/astra/stable/"

ASTRA_VERSION="astra-1.7"
EMS_DISTRIBUTION="softwlc-1.32-common"
SWLC_VERSION="softwlc-1.32"
SWLC_DEPENDENCIES="$SWLC_VERSION-dependencies"
# Наименование дистрибуции пакетов для определенных ОС
REPO_GPG_KEY_ADDR="$ELTEX_REPO/repo.gpg.key"
REPO_GPG_KEY_SYS_ADDR="/etc/apt/keyrings/eltex.gpg"

# переменная для пропуска установки пакетов linux, java и т.д. (т.е. только установка/обновление Eltex-пакетов из репо)
SKIP_LINUX_DEB=0

# Вендор JVM
JAVA_VENDOR="temurin"
EMS_PACKET_NAME="eltex-ems"

# Пользователь в СУБД MySQL для доступа к схемам
EMS_USER="javauser"
EMS_PASSWORD="javapassword"

# Список поддерживаемых кодовых имён операционных систем
LINUX_CODENAMES="
  1.7_x86-64
  "

# Список поддерживаемых дистрибуторов операционных систем
LINUX_DISTRIBUTORS="
  astralinux
  "

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

# PRESET FUNCTIONS SECTION START
function preset_versions() {
  # Нужен id для установки таких сервисов как mysql, nginx.
  # Astra Linux основан на Debian
  DEBIAN_DISTRIBUTOR_ID="debian"
  case "$DISTRIB_CODENAME" in
  "1.7_x86-64")
    DEBIAN_DISTRIB_CODENAME="buster"
    LIBSSL_PACKET_NAME="libssl1.1"
    LIBCURL_PACKET_NAME="libcurl4"
    ;;
  *)
    echo "Unknown Linux distribution. Script aborted! [Stage preset_versions]"
    exit 1
    ;;
  esac
}
# PRESET FUNCTIONS SECTION END

# REPO FUNCTIONS SECTION START
# Метод удаляет файл с Элтекс репо, т.к. при недоступности репо скрипт не
# может выполнить ни одну из функций
clean_repo() {
  # удалить старый репозиторий (ems, softwlc, astra, mysql), если он есть
  if [[ -f "/etc/apt/sources.list.d/eltex.list" ]]; then
    rm /etc/apt/sources.list.d/eltex.list
  fi

  if [[ -f "/etc/apt/sources.list.d/astra.list" ]]; then
    rm /etc/apt/sources.list.d/astra.list
  fi

  if [[ -f "/etc/apt/sources.list.d/java.list" ]]; then
    rm /etc/apt/sources.list.d/java.list
  fi

  if [[ -f "/etc/apt/sources.list.d/adoptium.list" ]]; then
        rm /etc/apt/sources.list.d/adoptium.list
  fi
}

add_repo() {
  echo "deb $ASTRA_REPO$DISTRIB_CODENAME/repository-base $DISTRIB_CODENAME  main contrib non-free" >>/etc/apt/sources.list.d/astra.list
  echo "deb $ASTRA_REPO$DISTRIB_CODENAME/repository-extended $DISTRIB_CODENAME  main contrib non-free" >>/etc/apt/sources.list.d/astra.list

  # репозитории Eltex
  echo "deb [arch=amd64] $ELTEX_REPO $EMS_DISTRIBUTION main" >>/etc/apt/sources.list.d/eltex.list
  echo "deb [arch=amd64] $ELTEX_REPO $SWLC_VERSION-$ASTRA_VERSION main" >>/etc/apt/sources.list.d/eltex.list
  echo "deb [arch=amd64] $ELTEX_REPO $SWLC_DEPENDENCIES-$ASTRA_VERSION main" >>/etc/apt/sources.list.d/eltex.list
  wget -O - ${REPO_GPG_KEY_ADDR} | apt-key add -
  # репозиторий для Temurin OpenJDK
  echo "deb https://packages.adoptium.net/artifactory/deb $DEBIAN_DISTRIB_CODENAME main" >>/etc/apt/sources.list.d/adoptium.list
  wget -qO - https://packages.adoptium.net/artifactory/api/gpg/key/public | gpg --dearmor | tee /etc/apt/trusted.gpg.d/adoptium.gpg > /dev/null
}
update_repo_related_vars() {
  REPO_GPG_KEY_ADDR="${ELTEX_REPO}/repo.gpg.key"
}
# REPO FUNCTIONS SECTION STOP

# CHECK FUNCTIONS SECTION START
# Контроль открытого порта
# Вызов функции: check_port "8080" result_var
# В результат будет помещён 0 - OK(порт открыт) или 1 - Ошибка (порта нет)
function check_port() {
  local __resultvar=$2
  local myresult='0'
  if [[ $(netstat -pna | grep ":$1") ]]; then
    echo "${green}Check port '$1' - passed${reset}"
    myresult='0'
  else
    echo "${red}Check port '$1' - error${reset}"
    myresult='1'
  fi
  eval ${__resultvar}="'$myresult'"
}

# Метод для проверки валидности имени дистрибутива.
# Скрипт не будет устанавливать софт на неизвестный дистрибутив Linux
function check_codename_and_platform() {
  # проверить разрядность системы и отказаться работать, если не x64
  local DISTRIB_PLATFORM=$(/bin/uname -m)
  echo "Platform : $DISTRIB_PLATFORM"

  if [[ ${DISTRIB_PLATFORM} != "x86_64" ]]; then
    echo "${red}Platform is not 'x86_64', script aborted!${reset}"
    exit 1
  fi

  # Проверить, что наименование дистрибутора Linux находится в списке известных
  local FOUND=0
  for distr in ${LINUX_DISTRIBUTORS}; do
    if [[ $1 == "$distr" ]]; then
      FOUND=1
      break
    fi
  done

  if [[ $FOUND == 0 ]]; then
    echo "${red}Unsupported Linux Distributor '$1', script aborted.${reset}"
    exit 1
  fi

  # Проверить, что кодовое имя дистрибутива находится в списке известных
  FOUND=0
  for distr in ${LINUX_CODENAMES}; do
    if [[ $2 == "$distr" ]]; then
      FOUND=1
      break
    fi
  done

  if [[ $FOUND == 0 ]]; then
    echo "${red}Unsupported Linux Codename '$2', script aborted.${reset}"
    exit 1
  fi
}
# CHECK FUNCTIONS SECTION END

# MYSQL FUNCTIONS SECTION START
# Перезаписывает файловые лимиты для службы mysql
function replace_open_files_for_mysql() {
  local DIR="/etc/systemd/system/mysql.service.d"
  local FILE_OVERRIDE="$DIR/override.conf"
  if [ -f "$FILE_OVERRIDE" ]; then
    rm "$FILE_OVERRIDE"
  fi

  if [ ! -d "$DIR" ]; then
    mkdir -p "$DIR"
  fi

  echo "[Service]" >"$FILE_OVERRIDE"
  echo "LimitNOFILE=1617596" >>"$FILE_OVERRIDE"
  echo "LimitNOFILESoft=1617596" >>"$FILE_OVERRIDE"
  echo "File '$FILE_OVERRIDE' replaced with new configuration"

  systemctl daemon-reload
  restart mysql
}

# Полностью переписать конфиг для плагина syslog-ng-mod-sql
function syslog_sql_replace_config() {
  # Это оригинальный файл: /etc/syslog-ng/syslog-ng.conf
  # Нам нужно создать конфиг mysql с именем 10-mysql.conf, переопределить там шаблон сохранения SQL
  # А так же включить прием сообщений по TCP и UDP на порту 514

  # Удалим первоначальный файл
  local DIR="/etc/syslog-ng/conf.d"
  local FILE_OVERRIDE="$DIR/mysql.conf"
  if [ -f "$FILE_OVERRIDE" ]; then
    rm "$FILE_OVERRIDE"
  fi

  # Удалим целевой файл, если как-то его создавали ранее
  local FILE_OVERRIDE="$DIR/10-mysql.conf"
  if [ -f "$FILE_OVERRIDE" ]; then
    rm "$FILE_OVERRIDE"
  fi

  {
    echo "### Configuration file for syslog-ng-mod-sql"
    echo "### Changes are preserved"
    echo "source src_rem { udp(port(514));
            tcp(port(514)); };"
    echo "destination d_mysql {
            program(\"/usr/bin/mysql --user=$EMS_USER --password='$EMS_PASSWORD' Syslog < /var/log/mysql.pipe\");
            pipe (\"/var/log/mysql.pipe\"
            template(\"insert into SystemEvents (Message, Facility,FromHost, FromHostIp, Priority, DeviceReportedTime,
            ReceivedAt, InfoUnitID, SysLogTag) values ('\$MSGONLY', \$FACILITY_NUM, '\$HOST_FROM', INET_ATON('\$SOURCEIP'),
            \$PRI, '\$S_YEAR-\$S_MONTH-\$S_DAY \$S_HOUR:\$S_MIN:\$S_SEC', '\$R_YEAR-\$R_MONTH-\$R_DAY \$R_HOUR:\$R_MIN:\$R_SEC',
            1, '\$TAGS');\")
            template-escape(yes)); };"
    echo "log { source(src_rem); destination(d_mysql); };"
  } >>"$FILE_OVERRIDE"
}

# Функция проверяет установлена ли расширенная схема Syslog в базе данных (с партициями и новыми полями)
# Возвращает "0", если схема соответствует эталону;
# Возвращает "1", если схема не соoтветствует эталону;
function syslog_check_extended_database() {
  # Запомнить переменную "на входе", чтобы передать в неё значение "на выходе"
  local __resultvar=$1
  local myresult="0"

  local DB="Syslog"
  local TABLE="SystemEvents"
  local PART29="PARTITION \`p29\`"
  local myvar=""

  # Проверка наличия схемы
  myvar=$(mysql -u$ANSWER_SOFTWLC_MYSQL_USER -p$ANSWER_SOFTWLC_MYSQL_PASSWORD -se "SHOW DATABASES LIKE '$DB';")
  # echo "MySQL answer = "${myvar}
  if [[ ! $myvar == *${DB}* ]]; then
    echo "${red}Database '$DB' does not exists${reset}"
    myresult="1"
  else
    myresult="0"
  fi

  # Проверка наличия таблицы
  if [[ ! "$myresult" == "1" ]]; then
    myvar=$(mysql -D$DB -u$ANSWER_SOFTWLC_MYSQL_USER -p$ANSWER_SOFTWLC_MYSQL_PASSWORD -se "SHOW TABLES LIKE '$TABLE';")
    # echo "MySQL answer = "${myvar}
    if [[ ! $myvar == *${TABLE}* ]]; then
      echo "${red}Table '$TABLE' does not exists${reset}"
      myresult="1"
    else
      myresult="0"
    fi
  fi

  # Проверка наличия партиционирования в схеме - единственный положительный результат
  if [[ ! "$myresult" == "1" ]]; then
    myvar=$(mysql -D$DB -u$ANSWER_SOFTWLC_MYSQL_USER -p$ANSWER_SOFTWLC_MYSQL_PASSWORD -se "SHOW CREATE TABLE $TABLE;")
    # echo "MySQL answer = "${myvar}
    if [[ $myvar == *${PART29}* ]]; then
      myresult="0"
    else
      myresult="1"
    fi
  fi
  # Возвращаем результат
  if [[ "$__resultvar" ]]; then
    eval $__resultvar="'$myresult'"
  else
    echo "$myresult"
  fi
}

# Создаем расширенную схему Syslog, которую использует syslog-ng и показывает сервер и GUI eltex-ems
function syslog_create_extended_database() {

  mysql -u$ANSWER_SOFTWLC_MYSQL_USER -p$ANSWER_SOFTWLC_MYSQL_PASSWORD <<MY_QUERY
-- MySQL dump 10.13  Distrib 5.1.67, for debian-linux-gnu (i486)
--
-- Host: localhost    Database: Syslog
-- ------------------------------------------------------
-- Server version       5.1.67-0ubuntu0.10.04.1

/*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */;
/*!40101 SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS */;
/*!40101 SET @OLD_COLLATION_CONNECTION=@@COLLATION_CONNECTION */;
/*!40101 SET NAMES utf8 */;
/*!40103 SET @OLD_TIME_ZONE=@@TIME_ZONE */;
/*!40103 SET TIME_ZONE='+00:00' */;
/*!40014 SET @OLD_UNIQUE_CHECKS=@@UNIQUE_CHECKS, UNIQUE_CHECKS=0 */;
/*!40014 SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0 */;
/*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='NO_AUTO_VALUE_ON_ZERO' */;
/*!40111 SET @OLD_SQL_NOTES=@@SQL_NOTES, SQL_NOTES=0 */;

--
-- Current Database: Syslog
--

drop database if exists Syslog;

CREATE DATABASE /*!32312 IF NOT EXISTS*/ Syslog DEFAULT CHARACTER SET utf8;

USE Syslog;

-- DROP TABLE IF EXISTS SystemEvents;
/*!40101 SET @saved_cs_client     = @@character_set_client */;
/*!40101 SET character_set_client = utf8 */;
-- DROP TABLE IF EXISTS SystemEvents;
/*!40101 SET @saved_cs_client     = @@character_set_client */;
/*!40101 SET character_set_client = utf8 */;
CREATE TABLE SystemEvents (
  ID bigint(20) unsigned NOT NULL AUTO_INCREMENT,
  CustomerID bigint(20) DEFAULT NULL,
  ReceivedAt datetime NOT NULL DEFAULT '1971-01-01 00:00:01',
  DeviceReportedTime datetime DEFAULT NULL,
  Facility smallint(6) DEFAULT NULL,
  Priority smallint(6) DEFAULT NULL,
  FromHost varchar(60) DEFAULT NULL,
  Message text,
  InfoUnitID int(11) DEFAULT NULL,
  SysLogTag varchar(60) DEFAULT NULL,
  FromHostIp INT UNSIGNED,
  PRIMARY KEY (ID,ReceivedAt,FromHostIp)
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8
/*!50100 PARTITION BY RANGE ( DAYOFMONTH(ReceivedAt))
SUBPARTITION BY HASH(FromHostIp) SUBPARTITIONS 33
(PARTITION p1 VALUES LESS THAN (2),
 PARTITION p2 VALUES LESS THAN (3),
 PARTITION p3 VALUES LESS THAN (4),
 PARTITION p4 VALUES LESS THAN (5),
 PARTITION p5 VALUES LESS THAN (6),
 PARTITION p6 VALUES LESS THAN (7),
 PARTITION p7 VALUES LESS THAN (8),
 PARTITION p8 VALUES LESS THAN (9),
 PARTITION p9 VALUES LESS THAN (10),
 PARTITION p10 VALUES LESS THAN (11),
 PARTITION p11 VALUES LESS THAN (12),
 PARTITION p12 VALUES LESS THAN (13),
 PARTITION p13 VALUES LESS THAN (14),
 PARTITION p14 VALUES LESS THAN (15),
 PARTITION p15 VALUES LESS THAN (16),
 PARTITION p16 VALUES LESS THAN (17),
 PARTITION p17 VALUES LESS THAN (18),
 PARTITION p18 VALUES LESS THAN (19),
 PARTITION p19 VALUES LESS THAN (20),
 PARTITION p20 VALUES LESS THAN (21),
 PARTITION p21 VALUES LESS THAN (22),
 PARTITION p22 VALUES LESS THAN (23),
 PARTITION p23 VALUES LESS THAN (24),
 PARTITION p24 VALUES LESS THAN (25),
 PARTITION p25 VALUES LESS THAN (26),
 PARTITION p26 VALUES LESS THAN (27),
 PARTITION p27 VALUES LESS THAN (28),
 PARTITION p28 VALUES LESS THAN (29),
 PARTITION p29 VALUES LESS THAN (30),
 PARTITION p30 VALUES LESS THAN (31),
 PARTITION p31 VALUES LESS THAN MAXVALUE) */;
/*!40101 SET character_set_client = @saved_cs_client */;


-- DROP TABLE IF EXISTS SystemEventsProperties;
/*!40101 SET @saved_cs_client     = @@character_set_client */;
/*!40101 SET character_set_client = utf8 */;
CREATE TABLE SystemEventsProperties (
  ID bigint(20) unsigned NOT NULL AUTO_INCREMENT,
  SystemEventID bigint(20) DEFAULT NULL,
  ParamName varchar(255) DEFAULT NULL,
  ParamValue text,
  PRIMARY KEY (ID)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
/*!40101 SET character_set_client = @saved_cs_client */;
/*!40103 SET TIME_ZONE=@OLD_TIME_ZONE */;

/*!40101 SET SQL_MODE=@OLD_SQL_MODE */;
/*!40014 SET FOREIGN_KEY_CHECKS=@OLD_FOREIGN_KEY_CHECKS */;
/*!40014 SET UNIQUE_CHECKS=@OLD_UNIQUE_CHECKS */;
/*!40101 SET CHARACTER_SET_CLIENT=@OLD_CHARACTER_SET_CLIENT */;
/*!40101 SET CHARACTER_SET_RESULTS=@OLD_CHARACTER_SET_RESULTS */;
/*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */;
/*!40111 SET SQL_NOTES=@OLD_SQL_NOTES */;
MY_QUERY
}

# Выполняет GRANT на заданной БД
# $1 - БД
# $2 - привелегия (ALL, FILE, etc.)
# $3 - пользователь
# $4 - пароль
# $5 - таблица
grant() {
  if [[ -z $5 ]]; then
    grant_advanced "$1" "$2" "$3" "$4" "*"
  else
    grant_advanced $1 $2 $3 $4 $5
  fi
}

grant_advanced() {
  local database="$1"
  local privilege="$2"
  local user="$3"
  local password="$4"
  local table="$5"

  sql_exec "GRANT ${privilege} ON ${database}.${table} TO '${user}'@'localhost' IDENTIFIED BY '${password}'"
  sql_exec "GRANT ${privilege} ON ${database}.${table} TO '${user}'@'127.0.0.1' IDENTIFIED BY '${password}'"
  if [ "${REMOTE}" = 1 ]; then
    sql_exec "GRANT ${privilege} ON ${database}.${table} TO '${user}'@'%' IDENTIFIED BY '${password}'"
  fi
}

# Выполняет $1 как SQL-запрос
sql_exec() {
  mysql -u$ANSWER_SOFTWLC_MYSQL_USER -p$ANSWER_SOFTWLC_MYSQL_PASSWORD -e "$1" >/dev/null
  return $?
}

# Инсталлирует MariaDB в зависимости от версии операционной системы
function install_mariadb() {
    if dpkg-query -f '${Status}\n' --show "mariadb-client" | grep '^install' &>/dev/null; then
        return 0
    fi

    local MYSQL_DUMP_NAME="mysqldump.sql"

    FOUND_MYSQL=0
    if dpkg-query -f '${Status}\n' --show "mysql-client" | grep '^install' &>/dev/null; then
      FOUND_MYSQL=1
    fi

    if [[ ${FOUND_MYSQL} == 1 ]]; then
      create_new_root_for_mariadb
#      Update user authentication plugin
      local mysql_command="UPDATE mysql.user SET plugin='unix_socket' WHERE User='$ANSWER_SOFTWLC_MYSQL_USER'"
      mysql -u$ANSWER_SOFTWLC_MYSQL_USER -p$ANSWER_SOFTWLC_MYSQL_PASSWORD -e "$mysql_command"

      mysql_command="SELECT GROUP_CONCAT(SCHEMA_NAME SEPARATOR ' ') FROM information_schema.SCHEMATA WHERE SCHEMA_NAME NOT IN ('mysql','information_schema','performance_schema','sys');"
      local databases=$(mysql -u$ANSWER_SOFTWLC_MYSQL_USER -p$ANSWER_SOFTWLC_MYSQL_PASSWORD -N -e "$mysql_command")

      echo "Export dump"
      mysqldump -u$ANSWER_SOFTWLC_MYSQL_USER --routines=true --triggers=true --databases $databases > $MYSQL_DUMP_NAME
      echo "Stop mysql"
      systemctl stop mysql.service
    fi

    apt-get install -y daemon
    apt-mark hold eltex-radius-db
    aptitude install -y mariadb-server mariadb-client
    apt-mark unhold eltex-radius-db


    disable_ssl_mariadb

    if [[ ${FOUND_MYSQL} == 1 ]]; then
      mysql_upgrade -u${ANSWER_SOFTWLC_MYSQL_USER} -p${ANSWER_SOFTWLC_MYSQL_PASSWORD} --upgrade-system-tables
      mysql -u$ANSWER_SOFTWLC_MYSQL_USER -p$ANSWER_SOFTWLC_MYSQL_PASSWORD < $MYSQL_DUMP_NAME
    fi
}

function create_new_root_for_mariadb() {
    mysql -u${ANSWER_SOFTWLC_MYSQL_USER} -p${ANSWER_SOFTWLC_MYSQL_PASSWORD} -e "CREATE USER IF NOT EXISTS '${ANSWER_SOFTWLC_MYSQL_USER}'@'127.0.0.1' IDENTIFIED BY '${ANSWER_SOFTWLC_MYSQL_PASSWORD}'"
    mysql -u${ANSWER_SOFTWLC_MYSQL_USER} -p${ANSWER_SOFTWLC_MYSQL_PASSWORD} -e "GRANT ALL ON *.* TO '${ANSWER_SOFTWLC_MYSQL_USER}'@'127.0.0.1' WITH GRANT OPTION"
    mysql -u${ANSWER_SOFTWLC_MYSQL_USER} -p${ANSWER_SOFTWLC_MYSQL_PASSWORD} -e "GRANT PROXY ON ''@'%' TO '${ANSWER_SOFTWLC_MYSQL_USER}'@'127.0.0.1' WITH GRANT OPTION"
}

function disable_ssl_mariadb() {
  # прописать принудительно выключение ssl сервиса mysql/mariadb для всех целевых ОС
    MARIADB_CFG_FILE=/etc/mysql/mariadb.conf.d/50-server.cnf
    if [[ ! -f "$MARIADB_CFG_FILE" ]]; then
      echo "${red}File not exists '$MARIADB_CFG_FILE'${reset}"
    else
      # Если файл есть, то проверить что в конфиге ssl ещё не выключен
      if [[ ! $(egrep "^[^#;]" $MARIADB_CFG_FILE | egrep "ssl=0") ]]; then
        sed -i "$(( $(grep -n "Security Features" /etc/mysql/mariadb.conf.d/50-server.cnf | cut -d: -f1) + 2)) i\ssl=0" $MARIADB_CFG_FILE
        echo "Modified file '$MARIADB_CFG_FILE', restarting service mariadb"
      fi
      systemctl restart mysql.service
    fi
}

# Метод для полной инсталляции syslog-ng-mod-sql, с заменой конфигов, модификацией баз,
# выдачей GRANT и всем остальным.
function full_installation_syslog_mysql() {
  install syslog-ng-mod-sql

  # Пересоздать схему 'Syslog' в базе данных (в случае необходимости)
  res="0"
  syslog_check_extended_database res
  if [[ "$res" == "1" ]]; then
    echo "${red}Invalid database 'Syslog', need update ${reset}"
    syslog_create_extended_database
    echo "${green}Database 'Syslog' updated ${reset}"
  else
    echo "${green}Table 'SystemEvents' is valid (contains parts)${reset}"
  fi

  # После пересоздания БД лучше ещё раз её проверить, чтобы убедиться, что всё в базе согласно ожиданий
  syslog_check_extended_database res
  if [[ "$res" == "1" ]]; then
    echo "${red}Invalid database 'Syslog', update failed, script aborted!${reset}"
    exit 1
  fi

  # Выдать права (гранты) на вновь созданную схему для пользователя в СУБД, с которым работает продукт EMS
  grant "Syslog" ALL "$EMS_USER" "$EMS_PASSWORD"

  # После установки syslog-ng/syslog-ng-mod-sql нужно провести его кастомную конфигурацию.
  # Включить приём данных из сети по UDP и TCP
  # Настроить, чтобы сетевой трафик сохранялся в mysql и не сохранялся в локальные файлы
  syslog_sql_replace_config

  # Рестарт службы для применения всех новых конфигов
  restart syslog-ng

  # Отправляем лог, чтобы создался fifo-file и не было спама об его отсутствии
  logger --server 127.0.0.1 "hello logger"
}
# MYSQL FUNCTIONS SECTION END

# PACKAGE/SERVICE FUNCTIONS SECTION START
install() {
  apt-get --yes install "$@"
}

stop() {
  # add '|| true' - to ignore error
  service "$@" stop || true
}

restart() {
  service "$@" restart
}

start() {
  service "$@" start || true
}

reload() {
  service "$@" reload || true
}

update() {
  apt-get -y update || true
}
# PACKAGE/SERVICE FUNCTIONS SECTION END

# TEMURIN OPENJDK FUNCTIONS SECTION START
function install_temurin_openjdk() {
  case "$DISTRIB_CODENAME" in
  "1.7_x86-64")
    # провести инсталляцию пакета temurin openjdk
    install temurin-17-jdk

    # прописать в системе использование только что установленного пакета
    update-alternatives --set java /usr/lib/jvm/temurin-17-jdk-amd64/bin/java
    ;;
  *)
    echo "Unknown Linux distribution. Script aborted! [Stage install_temurin_openjdk]"
    exit 1
    ;;
  esac
}


# TOMCAT FUNCTIONS SECTION START
function delete_tomcat() {
  names="tomcat8 tomcat9"
  set +e
  # если найден tomcat - удалить, оставив backup конфиураци
  for name in $names; do
    # Сохраняем конфигурацию прошлой версии tomcat
    local current_dir="$(pwd)"
    cd /etc/$name
    # Сохранение бэкапа конфигурации во временную директорию
    tar -czpf ~/tomcat-backup.tar.gz .
    # Сносим старый tomcat
    systemctl stop $name
    systemctl disable $name
    apt-get purge -y $name
    rm -rf /etc/systemd/system/$name.service.d
    systemctl unmask $name.service
    systemctl daemon-reload
    systemctl reset-failed
    cd "${current_dir}"
  done

  set -e
}

function change_ems_port() {
    sed -i 's/port: [0-9]*/port: 8080/' "/usr/lib/eltex-ems/conf/application.yml"
    sed -i 's/EMS_WEB_PORT=[0-9]*/EMS_WEB_PORT=8080/' "/usr/lib/eltex-ems/scripts/check_ems_srv.sh"
}

function disable_excess_services_on_ems() {
    mysql -u$ANSWER_SOFTWLC_MYSQL_USER -p$ANSWER_SOFTWLC_MYSQL_PASSWORD -e "INSERT INTO eltex_ems.PARAMS(param1,param2,value) VALUES('softwlc.nbi', 'nbi.enabled', 'false') \
    ON DUPLICATE KEY UPDATE param1='softwlc.nbi', param2='nbi.enabled', value='false';"
    mysql -u$ANSWER_SOFTWLC_MYSQL_USER -p$ANSWER_SOFTWLC_MYSQL_PASSWORD -e "INSERT INTO eltex_ems.PARAMS(param1,param2,value) VALUES('pcrf', 'pcrf.enabled', 'false') \
    ON DUPLICATE KEY UPDATE param1='pcrf', param2='pcrf.enabled', value='false';"
}

# Выставить режим пропуска инсталляции системных пакетов
if [[ ! -z "$1" ]]; then
  for i in "$@"; do
    if [[ ${i} == "--public" ]]; then
      ELTEX_REPO=${ELTEX_PUBLIC_REPO}
      break
    fi

    if [[ ${i} == "--private" ]]; then
      ELTEX_REPO=${ELTEX_PRIVATE_REPO}
      break
    fi
  done
fi

if [[ $(id -u) -ne 0 ]]; then
  echo "${red}This script can only be run as root${reset}"
  exit 1
fi

#проверить разрядность системы и отказаться работать, если не x64
DISTRIB_PLATFORM=$(/bin/uname -m)
echo "Platform : $DISTRIB_PLATFORM"

if [[ ${DISTRIB_PLATFORM} != "x86_64" ]]; then
  echo "${red}Platform is not 'x86_64', script aborted!${reset}"
  exit 1
fi

# Узнать наименование дистрибутора (debian/ubuntu/astra-linux) и записать lowercase
tmp_str=$(lsb_release -is)
DISTRIBUTOR_ID="${tmp_str,,}"

# узнать кодовое имя дистрибутива и записать lowercase
tmp_str=$(lsb_release -cs)
DISTRIB_CODENAME="${tmp_str,,}"

check_codename_and_platform ${DISTRIBUTOR_ID} ${DISTRIB_CODENAME}

echo "${green}OS distributer ID: $DISTRIBUTOR_ID${reset}"
echo "${green}OS distrib code name: $DISTRIB_CODENAME${reset}"
echo "${green}Repository: $ELTEX_REPO ${reset}"
echo "${green}Java vendor: $JAVA_VENDOR${reset}"

preset_versions

# Выставить режим пропуска инсталляции системных пакетов
if [[ ! -z "$1" ]]; then
  for i in "$@"; do
    if [[ ${i} == "--update-eltex-packages" ]]; then
      SKIP_LINUX_DEB=1
      echo "${green}Skipping installation of system packages${reset}"
      break
    fi
  done
fi

# вывести в консоль репозиторий после проверки флага --public
echo "${green}Repository: $ELTEX_REPO ${reset}"

clean_repo

# Добавление репозиториев и их ключей перед установкой
update_repo_related_vars
add_repo
# Установка mariadb
install_mariadb

check_java_version() {
  # Ищем temurin openjdk в системе. Если нашли - ставим ее по умолчанию
  if dpkg -s temurin-17-jdk >/dev/null 2>&1; then
    update-alternatives --set java /usr/lib/jvm/temurin-17-jdk-amd64/bin/java
    return 0
  else
    return 1 # Требуется установить Java актуальной версии
  fi
}

# Режим "пропустить инсталляцию системных пакетов"
if [[ ! ${SKIP_LINUX_DEB} == "1" ]]; then

  # установить (обновить) программу работы с репозиторием add-apt-repository (т.к. в некоторых системах она не присутствует)
  install software-properties-common

  # обновить репозиторий
  update

  # провести инсталляцию пакета temurin openjdk
  install_temurin_openjdk

  # установить прочие пакеты, которые прописаны в зависимостях пакета eltex-ems
  install expect psmisc ntp tftp-hpa tftpd-hpa snmpd syslog-ng snmp curl fping vsftpd lockfile-progs

  # инсталляция библиотеки зависит от версии ОС (либа нужна для eltex-airtune)
  install $LIBSSL_PACKET_NAME

  # некоторые новые дистрибутивы (desktop) могут не содержать net-tools:netstat
  install net-tools

  # Установка библиотеки libcurl, которая очень нужна некоторым сервисам, например eltex-radius, причём индекс
  # зависит от операционной системы
  install $LIBCURL_PACKET_NAME

  # переписываем лимиты для сервиса mysql, иначе rsyslog-mysql с пагинацией не работает на U16+
  replace_open_files_for_mysql

  # syslog-ng-mod-sql устанавливается только после окончания установки mysql-server
  # иначе попытка его конфигурирования провалится
  full_installation_syslog_mysql

else

  update
  # Если java версия != актуальная -> устанавливаем актуальную версию java
  if ! check_java_version; then
      install_temurin_openjdk
  fi
fi

# Удалить томкат, если он есть. EMS в нем больше не нуждается
delete_tomcat


PACKAGES="eltex-ems-db
          eltex-oui-list
          eltex-ems"

# Последовательная установка пакетов
for package in ${PACKAGES}; do
  echo
  echo "*"
  echo "* Installing $package ..."
  echo "*"
  echo
  install ${package}
done

echo "Start services.."


# Меняем порт ems c 8087 на 8080
change_ems_port

# Отключаем pcrf и nbi (только для одиночной инсталляции)
disable_excess_services_on_ems

# Перезапустить сервисы

# EMS через стоп и старт, т.к. с рестаротом проблемы на определённых ОС (trusty)
stop ${EMS_PACKET_NAME}
start ${EMS_PACKET_NAME}

# проверить открытые порты
echo "Waiting 10 seconds.."
sleep 10

echo "Check Tomcat port.."
check_port "8080" check_port_result

echo "Check EMS port (60 seconds for retry).."
CHECK_COUNT=60
PORT_9310_PASSED="1"
for i in $(seq 1 ${CHECK_COUNT}); do
  check_port "9310" check_port_result
  if [[ "$check_port_result" != "0" ]]; then
    sleep 1
  else
    PORT_9310_PASSED="0"
    break
  fi
done

#Если все циклы проверки прошли, а порт 9310 так и не открылся, значит беда, выходим отсюда
if [[ "$PORT_9310_PASSED" != "0" ]]; then
  echo "${red}Packet eltex-ems out of service (port 9310 not opened)${reset}"
  exit 2
fi

echo "Check EMS internal NBI"
if [[ $(curl "localhost:8080/northbound/getVersion") ]]; then
  echo "${green}Check NBI on 'localhost' - passed${reset}"
else
  echo "${red}Check NBI on 'localhost' - error${reset}"
  exit 2
fi

# Всё
echo "Installation of Eltex SoftWLC finished"
echo "URLs of SoftWLC components:
Eltex.EMS GUI: http://localhost:8080/ems/jws
    login: admin
    password: <empty>"

exit 0
