#!/bin/bash

# This Bash script installs a PowerDNS master/slave server including PDNSManager on your serevr

# Vars
VERSION="0.0.1"
SETUPTOKEN=$(md5sum<<<$RANDOM | awk '{print $1}')
TEMP_PATH="/tmp"
REQUIRED_OS="buster"
TEMP_DIR="$TEMP_PATH/PDNS_Manager_Setup-$SETUPTOKEN/$VERSION"
IP_ADDR=$(/sbin/ip -o -4 addr list eth0 | awk '{print $4}' | cut -d/ -f1)

# Download URLs
PDNSM_APACHE_CONF=""

# DynVars
DESIRED_HOSTNAME=""
AXFR_IPS=""
SQL_PW=""
MASTER_SLAVE_OPTION=""
MASTER_SERVER=""
PDNS_DB_PW=""

# Colors
BLUE="\033[0;36m"
RED="\033[0;31m"
YELLOW="\033[0;33m"
GREEN="\033[0;32m"
PLAIN="\033[0m"

# Functions

show_spinner() {
  spin='-\|/'

    i=0
    while kill -0 $1 2>/dev/null
    do
    i=$(( (i+1) %4 ))
    printf "\r\e[93m[ \e[36m${spin:$i:1} \e[93m] \e[93mPlease wait...\e[39m"
    sleep .1
    done
}

print_error() {
  echo -e "${RED} $1"
}

createSetupDir() {
  mkdir -p $TEMP_DIR
}

deleteSetupFiles() {
  rm -R $TEMP_DIR
}

replaceString() {
  sed -i "s/$1/$2/" $3
}

initScript() {

  clear
  echo -e "${BLUE}Thank you for chosing this script to install your nameservers! ${PLAIN}"
  echo -e "${BLUE}Before we can start, we need to install some required scripts. ${PLAIN}"
  echo ""

  apt-get update > /dev/null &
  show_spinner $!

  apt-get install -y apt lsb-release ca-certificates apt-transport-https wget curl nano sudo git zip unzip neofetch gnupg2 gnupg gnupg1 > /dev/null &
  show_spinner $!
}

welcome() {
  clear
  echo -e "${BLUE}PDNS-Setup - Kleine-Vorholt.NET - v${VERSION} ${PLAIN}"
  echo ""
  echo -e "${YELLOW}Welcome to the Kleine-Vorholt.NET PDNS_Manager_Setup! ${PLAIN}"
  echo -e "${YELLOW}This wizard will install PowerDNS with SQL-Backend & PDNSManager on your server! ${PLAIN}"
  echo ""
  echo -e "${YELLOW}Before we can start you need to tell us some information about your situation ${PLAIN}"
  echo ""

  read -p "Please type in the hostname for this nameserver: [${HOSTNAME}] " DESIRED_HOSTNAME
  if [[ $DESIRED_HOSTNAME == "" ]]; then
    DESIRED_HOSTNAME=$HOSTNAME
  fi

  read -p "Do you want to install a master or slave server? [master] " MASTER_SLAVE_OPTION
  if [[ $MASTER_SLAVE_OPTION == "" ]]; then
    MASTER_SLAVE_OPTION="master"
  fi
  if [[ $MASTER_SLAVE_OPTION == "master" ]]; then
    read -p "Please type in the IP's that are allowed to request zones via AXFR. [127.0.0.1, 0.0.0.0] " AXFR_IPS
    if [[ $AXFR_IPS == "" ]]; then
      AXFR_IPS="127.0.0.1, 0.0.0.0"
    fi
  elif [[ $MASTER_SLAVE_OPTION == "slave" ]]; then
    read -p "Please type in the IP-Address of your MASTER Server. (IP without subnet) [192.168.1.14] " MASTER_SERVER
    if [[ $MASTER_SERVER == "" ]]; then
      MASTER_SERVER="192.168.1.14"
    fi
  else
    print_error "Wrong server type selected! '${MASTER_SLAVE_OPTION}' isn't a valid option! ${PLAIN}"
    exit 1
  fi

  TMP_PW=$(md5sum<<<$RANDOM | awk '{print $1}')
  read -s -p "Please type in a strong password for your database administrative user 'dbadmin'. [${TMP_PW}] " SQL_PW
  if [[ $SQL_PW == "" ]]; then
    SQL_PW=$TMP_PW
  fi
  echo ""
  TMP_PW=$(md5sum<<<$RANDOM | awk '{print $1}')
  read -s -p "Please type in a strong password for the pdns database. [${TMP_PW}] " PDNS_DB_PW
  if [[ $PDNS_DB_PW == "" ]]; then
    PDNS_DB_PW=$TMP_PW
  fi

  echo "${DESIRED_HOSTNAME}"
}


osCheck() {
  clear
  echo -e "${BLUE}Checking OS compatibility... ${PLAIN}"
  sleep 3 &
  show_spinner $!
  if [[ $(lsb_release -sc) == $REQUIRED_OS ]]; then
    echo -e "${GREEN}Your OS is compatible! ${PLAIN}"
  else
    clear
    print_error "Your OS is not compatible! Please upgrade to ${REQUIRED_OS}"
    exit 1
  fi
}

setupDependencies() {
  clear
  echo -e "${BLUE}Setting up dependencies... ${PLAIN}"
  echo ""

  apt-get install -y mariadb-server mariadb-client apache2 php7.3 php7.3-cli php7.3-common php7.3-mysql php7.3-xml php7.3-apcu php7.3-json php7.3-curl php7.3-mbstring > /dev/null &
  show_spinner $!

  a2enmod ssl > /dev/null &
  show_spinner $!

  a2enmod rewrite > /dev/null &
  show_spinner $!
}

initDB() {
  echo -e "${BLUE}Setting up database structure..."

  # SuperUser
  printf "CREATE USER 'dbadmin'@'localhost' IDENTIFIED BY '$SQL_PW'; " >> $TEMP_DIR/superuserSQL.sql
  printf "GRANT ALL PRIVILEGES ON *.* TO 'dbadmin'@'localhost' WITH GRANT OPTION; " >> $TEMP_DIR/superuserSQL.sql
  printf "FLUSH PRIVILEGES; " >> $TEMP_DIR/superuserSQL.sql

  #PDNS DB
  printf "CREATE DATABASE pdns; " >> $TEMP_DIR/pdnsDBSQL.sql
  printf "CREATE USER 'pdns'@'localhost' IDENTIFIED BY '$PDNS_DB_PW'; " >> $TEMP_DIR/pdnsDBSQL.sql
  printf "GRANT SELECT, INSERT, UPDATE, DELETE, CREATE, INDEX, DROP, ALTER, CREATE TEMPORARY TABLES, LOCK TABLES ON pdns.* TO 'pdns'@'localhost'; " >> $TEMP_DIR/pdnsDBSQL.sql

  mysql -q < $TEMP_DIR/superuserSQL.sql
  mysql -q < $TEMP_DIR/pdnsDBSQL.sql
}

setupVHostConfigs() {
  echo -e "${BLUE}Setting up apache2 vHosts..."

  mkdir -p "/var/www/html/nodomain"

  wget -q -N "https://cdn.kleine-vorholt.eu/scripts/pdns_manager/resources/pdnsmanager.conf" -P $TEMP_DIR > /dev/null &
  show_spinner $!

  wget -q -N "https://cdn.kleine-vorholt.eu/scripts/pdns_manager/resources/nodomain.conf" -P $TEMP_DIR > /dev/null &
  show_spinner $!

  mv $TEMP_DIR/pdnsmanager.conf /etc/apache2/sites-available/pdnsmanager.conf
  mv $TEMP_DIR/nodomain.conf /etc/apache2/sites-available/nodomain.conf
  replaceString "hostname.example.com" "${DESIRED_HOSTNAME}" "/etc/apache2/sites-available/pdnsmanager.conf"

  wget -q -N "https://cdn.kleine-vorholt.eu/scripts/pdns_manager/resources/ports.conf" -P $TEMP_DIR > /dev/null &
  show_spinner $!
  mv $TEMP_DIR/ports.conf /etc/apache2/ports.conf

  a2dissite 000-default
  a2ensite pdnsmanager
  a2ensite nodomain

  service apache2 restart
}

configureSQLConnectionPDNS() {
  echo ""
  echo -e "${BLUE}Setting up PowerDNS database connection... ${PLAIN}"
  wget -q -N "https://cdn.kleine-vorholt.eu/scripts/pdns_manager/resources/pdns.local.gmysql.conf" -P $TEMP_DIR > /dev/null &
  show_spinner $!

  rm /etc/powerdns/pdns.d/*
  mv $TEMP_DIR/pdns.local.gmysql.conf /etc/powerdns/pdns.d/pdns.local.gmysql.conf
  replaceString "DBNAME" "pdns" "/etc/powerdns/pdns.d/pdns.local.gmysql.conf"
  replaceString "DBUSER" "pdns" "/etc/powerdns/pdns.d/pdns.local.gmysql.conf"
  replaceString "DBPASS" "${PDNS_DB_PW}" "/etc/powerdns/pdns.d/pdns.local.gmysql.conf"
}

setupMaster() {
  echo ""
  echo -e "${BLUE}Setting up PowerDNS master server configuration... ${PLAIN}"
  wget -q -N "https://cdn.kleine-vorholt.eu/scripts/pdns_manager/resources/pdns_master.conf" -P $TEMP_DIR > /dev/null &
  show_spinner $!

  mv /etc/powerdns/pdns.conf /etc/powerdns/pdns.conf.orig
  mv $TEMP_DIR/pdns_master.conf /etc/powerdns/pdns.conf
  replaceString "AXFRIPS" "${AXFR_IPS}" "/etc/powerdns/pdns.conf"
  replaceString "MYIP" "${IP_ADDR}" "/etc/powerdns/pdns.conf"
  replaceString "RANDOMAPIKEY" "${SETUPTOKEN}" "/etc/powerdns/pdns.conf"
  replaceString "RANDOMWEBSERVERPASS" "${SETUPTOKEN}" "/etc/powerdns/pdns.conf"
}

setupSlave() {
  echo ""
  echo -e "${BLUE}Setting up PowerDNS slave server configuration... ${PLAIN}"
  wget -q -N "https://cdn.kleine-vorholt.eu/scripts/pdns_manager/resources/pdns_slave.conf" -P $TEMP_DIR > /dev/null &
  show_spinner $!

  mv /etc/powerdns/pdns.conf /etc/powerdns/pdns.conf.orig
  mv $TEMP_DIR/pdns_slave.conf /etc/powerdns/pdns.conf
  replaceString "MASTERIP" "${MASTER_SERVER}" "/etc/powerdns/pdns.conf"

  #SUPERMASTER
  printf "INSERT INTO pdns.supermasters (ip, nameserver, account) VALUES ('${MASTERIP}', '${DESIRED_HOSTNAME}', ''); " >> $TEMP_DIR/pdnsSupermasterSQL.sql
  mysql -q < $TEMP_DIR/pdnsSupermasterSQL.sql

}

setupGeneral() {
  hostnamectl set-hostname $DESIRED_HOSTNAME
  initDB
  mkdir -p "/etc/ssl/web"

  # Certificate upload
  clear
  echo -e "${YELLOW}Please upload your SSL/TLS Files for PDNSManager to '/etc/ssl/web'. ${PLAIN}"
  echo -e "${YELLOW}The following files are required: ${PLAIN}"
  echo ""
  echo -e "${BLUE}- certificate.crt (Certificate for your hostname) ${PLAIN}"
  echo -e "${BLUE}- private.key     (Matching Key File for your Certificate) ${PLAIN}"
  echo -e "${BLUE}- ca-cert.crt     (Issuer/Intermediate Certificate of your hostname Certificate) ${PLAIN}"
  echo ""
  echo -e "${RED}Please be sure that all files are named exactly like the filenames displayed above! ${PLAIN}"
  echo ""
  read -p "Please press RETURN key when all files are uploaded." ABCDEF
  echo ""

  # Apache vHostConfig Setup
  setupVHostConfigs

  # PDNS-Manager
  wget -q -N "https://cdn.kleine-vorholt.eu/scripts/pdns_manager/resources/pdnsmanager-2.1.0.tar.gz" -P $TEMP_DIR > /dev/null &
  show_spinner $!
  tar xfvz $TEMP_DIR/pdnsmanager-2.1.0.tar.gz -C $TEMP_DIR > /dev/null &
  show_spinner $!
  mv $TEMP_DIR/pdnsmanager-2.1.0/frontend /var/www/html/frontend &
  show_spinner $!
  mv "$TEMP_DIR/pdnsmanager-2.1.0/backend" /var/www/html/backend &
  show_spinner $!
  chown www-data:www-data -R /var/www

  clear
  echo -e "${YELLOW}The PDNSManager Panel is now set up. ${PLAIN}"
  echo -e "${YELLOW}Please visit '${BLUE}https://${DESIRED_HOSTNAME}:6445/setup${YELLOW}' to configure the PDNS database. ${PLAIN}"
  echo ""
  echo -e "${YELLOW}Please use the following credentials to set up the database connection:${PLAIN}"
  echo ""
  echo -e "${BLUE}Host:       ${GREEN}127.0.0.1  ${PLAIN}"
  echo -e "${BLUE}Port:       ${GREEN}3306  ${PLAIN}"
  echo -e "${BLUE}User:       ${GREEN}pdns  ${PLAIN}"
  echo -e "${BLUE}Password:   ${GREEN}${PDNS_DB_PW}  ${PLAIN}"
  echo -e "${BLUE}Database:   ${GREEN}pdns  ${PLAIN}"

  echo ""
  read -p "After setting up PDNSManager press RETURN to continue." FEDCBA
  echo ""

  # General pdns installation
  clear
  echo -e "${YELLOW}INFORMATION: The Setup is now going to install the PowerDNS software package. ${PLAIN}"
  echo -e "${YELLOW}If you're asked to set up a default database for PowerDNS answer with no! This setup will create it automatically. ${PLAIN}"
  echo ""
  read -p "I've read the information above and will answer with 'no' if asked. Pres RETURN to continue" XYZ
  echo ""

  echo -e "${BLUE}Downloading & Installing PowerDNS server... ${PLAIN}"
  apt-get install -y pdns-server pdns-backend-mysql > /dev/null &
  show_spinner $!

  service pdns stop

  # Configuration File for PowerDNS to connect to MySQL
  configureSQLConnectionPDNS

  # Configure slave or master
  if [[ $MASTER_SLAVE_OPTION == "master" ]]; then
    setupMaster
  else
    setupSlave
  fi

  echo ""
  echo -e "${BLUE}Starting PowerDNS server...${PLAIN}"
  service pdns start

  echo ""
  echo -e "${BLUE}Restarting Web- & Nameserver...${PLAIN}"
  service apache2 restart && service pdns restart
}

setupEnd() {
  clear
  echo -e "${GREEN}Thanks for using our PowerDNS installer! :) ${PLAIN}"
	echo -e "\e[1;30mMore information: https://kleine-vorholt.net/ ${PLAIN}"
	echo ""
	echo -e "${YELLOW}Your PDNSManager is now live! : '${BLUE}https://${DESIRED_HOSTNAME}:6445${YELLOW}' ${PLAIN}"
	echo -e "${YELLOW}We recommend to also install phpMyAdmin via our installer to easily manage your databases ${PLAIN}"
  echo -e "${YELLOW}You can download the phpMyAdmin Installer here : '${BLUE}https://cdn.kleine-vorholt.eu/scripts/lamp/deb10/install${YELLOW}' ${PLAIN}"
}


# Init & Welcome
initScript
osCheck
createSetupDir
welcome

# Setups
setupDependencies
setupGeneral

# End of setup
deleteSetupFiles
setupEnd
