#!/usr/bin/env bash
#
# Скрипт установки linux-агента для Vulns.io VM
#

# Лог файл
LOG_FILE=/tmp/deploy-linuxsc.txt

# Временный файл с инсталлятором
FILE_TMP=agent-installer_$$.sh

# IP адрес сервера OnPremise
SERVER_IP=192.168.100.100

# Ключ для доступа к API
# Находится на сервере OnPremise в файле /opt/vulns.io/onpremise/config/main/credentials.ini
API_KEY="sadfghkj12312qwe"

# accountid - имя аккаунта в базе OnPremise
# По умолчанию accountid="0" - суперпользователь
accountid="0"

# userid - имя пользователя в базе OnPremise
# По умолчанию userid="0" - суперпользователь
userid="0"

# Имена сервисов агента для проверки их работоспособности
agent_service_name="vulns.io-agent-linux"
updater_service_name="vulns.io-agent-updater-linux"

# Параметр 'DELETE_ASSET_IF_INSTALL_FAIL' определяет поведение скрипта в случае если службы агента не запустились.
#  Значение 1 - указывает, что в случае не удачного запуска службы (по любой причине) удаляем установленный агент и очищаем из базы данных OnPremise asset и agent
#  Значение 0 - не предпринимаем никаких действий по удалению агента
DELETE_ASSET_IF_INSTALL_FAIL=1

# Разрешено ли выводить информацию о действиях скрипта на экран или в лог-файл
LOG_TO_SCREEN=1
LOG_TO_FILE=1

# коды выхода из скрипта
# =0  - Агент установлен и запущен в системе корректно
# =4  - Не найдена команда curl для работы с API OnPremise
# =8  - Пользователь не входит в группу 'root', необходимого для создания служб агентов в системе и их запуска
# =16 - Вызов справки по аргументам запуска скрипта
# =32 - Ошибка доступа к API OnPremise
# =64 - Ошибка скачивания инсталятора агента с сервера OnPremise


out_data_log()
{
# Вывод информации о работе скрипта на экран или в лог-файл в зависимости от переменных LOG_TO_SCREEN и LOG_TO_FILE
if  [ $LOG_TO_SCREEN -eq 1 ]; then
  echo $1
fi
if  [ $LOG_TO_FILE -eq 1 ]; then
  echo $1 >> $LOG_FILE
fi
}


init()
{
# Проверка существования curl. Необходимо для доступа к API OnPremise через протокол https.

if ! command -v curl >/dev/null; then
  out_data_log "Attention: You may need to install curl for the deploy script!"
  exit 4
fi

# Проверка суперправ у пользователя запустившего скрипт
if groups | grep -q "\broot\b"; then
  out_data_log "The corrent user is in group 'root'. Continuing the work of the script"
else
  out_data_log "Attention - the user is not in the 'root' group!"
  exit 8
fi

if [[ -n "$1" ]]; then
    echo " "
    echo "Требуется указать корректный аргумент вызова скрипта"
    echo "Команды запуска скрипта:"
    echo $(basename $0)"  [ -h | --help ]"
    echo $'\t'"где '--help или -h '"$'\t'" - вызов этой справки по командам"
    exit 16
fi

# Получаем текущий IP-адрес машины
IP_ADR=$(hostname --all-ip-addresses | awk '{print $1}')
out_data_log "Current IP="$IP_ADR
}


check_response_api()
{
# Проверка ответа от API и результата выполнения curl

#  если после вызова curl получаем код ошибки больше 0, то сообщаем об ошибки доступности API
if [ $1 -ne 0 ]; then
 if [ $1 -eq 22 ]; then
  out_data_log "Request failure. API OnPremise not available, response code >= 400"
 else
  out_data_log "CURL: Error code = "$1
 fi
 RETURN_VAL="error"
else
 RETURN_VAL="ok"
fi
}


get_installer()
{
# Отправка запроса на скачивание установщика и получение его url
local osType="linux"

GET_URL=$(curl -X GET -k "https://$SERVER_IP/integration/v1/agents/download/installer/url?osType=$osType&accountId=$accountid&userId=$userid" -H "Content-Type: application/json" -H "x-api-key: $API_KEY" --compressed -s)

check_response_api $?

if [ "$RETURN_VAL" == "error" ]; then
  out_data_log "Error send request to API OnPremise, server IP "$SERVER_IP
# Если после первого обращения к API сервер был не доступен, то прекращаяем выполнения скрипта, считая, что проблемы с сетевым доступом или сервером OnPremise
  exit 32
fi

url_id=$(echo $GET_URL | sed -e "s/^.*url\"\:\"//g" | sed -e "s/\".*$//g")
agentid=$(echo $GET_URL | sed -e "s/^.*agentId\"\:\"//g" | sed -e "s/\".*$//g")
assetid=$(echo $GET_URL | sed -e "s/^.*assetId\"\:\"//g" | sed -e "s/\".*$//g")
}


delete_asset()
{
# Удаление asset'а

# assetId - получить из ответа полученного при создании агента

ASSET=$(curl -X DELETE -k "https://$SERVER_IP/integration/v1/assets/$assetid" -H "Content-Type: application/json" -H "x-api-key: $API_KEY" --compressed -s)

check_response_api $?

if [ "$RETURN_VAL" == "error" ]; then
  out_data_log "Error deleting asset '$assetid' data in database OnPremise, server IP $SERVER_IP"
else
  out_data_log "Asset deleted correctly."
fi

}


delete_agent()
{
# Удаление agent'а

# agentId - получить из ответа полученного при создании агента

AGENT=$(curl -X DELETE -k "https://$SERVER_IP/integration/v1/agents/$agentid" -H "Content-Type: application/json" -H "x-api-key: $API_KEY" --compressed -s)

check_response_api $?

if [ "$RETURN_VAL" == "error" ]; then
  out_data_log "Error deleting agent '$agentid' data in database OnPremise, server IP $SERVER_IP"
else
  out_data_log "Agent deleted correctly."
fi
}


deploy_agent()
{
# Скачивание и запуск установки Linux-установщика

out_data_log "---- Download and deploy agent installer ----"
# Скачиваем файл, игнорируя самоподписанный SSL сертификат сервера (-k)

# Вариант #1 - скачиваем файл и сразу его запускаем
#curl -k -s $url_id | bash

# Вариант #2 - скачиваем файл, выдаем разрешение на запуск и запускаем исталлятор
# В этом случае можно обработать ответ от сервера и вывести необходимую информацию на экран/лог
curl -k -s $url_id -o ./$FILE_TMP
check_response_api $?
if [ "$RETURN_VAL" == "error" ]; then
  out_data_log "Error downloading agent installer script from server IP $SERVER_IP"
# Не смогли скачать агента, прекращаем работу скрипта
  exit 64
else
  out_data_log "Agent installer correctly downloaded."
fi
chmod +x ./$FILE_TMP
./$FILE_TMP

echo "------------ Deploy agent finish ------------"
}


check_agent()
{
# Проверка, что хотя бы одна из служб агента запущена
if systemctl -q is-active $agent_service_name == 'active'; then
  out_data_log "Service $agent_service_name still running."
  AGENT_INSTALLED=1
else
  if systemctl -q is-active $updater_service_name == 'active'; then
   out_data_log "Service $updater_service_name still running."
   AGENT_INSTALLED=1
   else

     # Не нашли запущенную службу агента (vulns.io-agent-linux) или апдейтера (vulns.io-agent-updater-linux)
     AGENT_INSTALLED=0

     out_data_log "Linux-agent installation failed with an error, agent not installed"

     # В зависимости от параметра 'DELETE_ASSET_IF_INSTALL_FAIL' удаляем или нет установленный агент и (не)очищаем из базы данных OnPremise asset и agent
     if [ $DELETE_ASSET_IF_INSTALL_FAIL -eq 0 ]; then
      out_data_log "Set internal variable 'DELETE_ASSET_IF_INSTALL_FAIL=0'"
     else
     # Удаляем агента с помощью uninstaller'а и удаляем asset и agent в бд OnPremise
       if [ -f /opt/vulns.io/agent-linux/agent_uninstall.sh ]; then
         out_data_log "Run - Uninstall agent script"
         /opt/vulns.io/agent-linux/agent_uninstall.sh
       fi

# - fix on удаляем забытые символьные ссылки (для поддержки старых версий деинсталляторов агентов)
       if [ -L /usr/lib/systemd/system/vulns.io-agent-linux.service ]; then
        rm -f /usr/lib/systemd/system/vulns.io-agent-linux.service
         out_data_log "FIX: Удалили файл /usr/lib/systemd/system/vulns.io-agent-linux.service"
       fi
       if [ -L /usr/lib/systemd/system/vulns.io-agent-updater-linux.service ]; then
        rm -f /usr/lib/systemd/system/vulns.io-agent-updater-linux.service
        out_data_log "FIX: Удалили файл /usr/lib/systemd/system/vulns.io-agent-updater-linux.service"
       fi
# - fix off

       out_data_log "Deleting data on OnPremise"

       delete_asset

       delete_agent

       # Удаляем скачанный файл инсталятора linux-агента
       rm -f ./$FILE_TMP
     fi
  fi
fi
if [ $AGENT_INSTALLED -eq 1 ]; then
  out_data_log "Linux agent installation completed correctly"
fi
}


# --------- MAIN ---------

out_data_log "-- Start deploy linux-agent at $(date +"%Y-%m-%d %T") ---"

init $1

get_installer

out_data_log "agentid='$agentid'"
out_data_log "assetid='$assetid'"

deploy_agent

WAIT_TIME=5
out_data_log "Wait $WAIT_TIME second before check linux-agent"
sleep $WAIT_TIME

check_agent

out_data_log "-- End deploy linux-agent. Total script running time $SECONDS seconds ---"
