#!/bin/bash

SVER='1.0.45'

##############################################################################
#  setup-sca - SCA Appliance Setup Tool
#  Copyright (C) 2014-2022 SUSE LLC
#
# Description:  Sets up a standard local host configuration of the SCA 
#               appliance
# Modified:     2022 Jun 29
#
##############################################################################
#
#  This program is free software; you can redistribute it and/or modify
#  it under the terms of the GNU General Public License as published by
#  the Free Software Foundation; version 2 of the License.
#
#  This program is distributed in the hope that it will be useful,
#  but WITHOUT ANY WARRANTY; without even the implied warranty of
#  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
#  GNU General Public License for more details.
#
#  You should have received a copy of the GNU General Public License
#  along with this program; if not, see <http://www.gnu.org/licenses/>.
#
#  Authors/Contributors:
#     Jason Record (jason.record@suse.com)
#
##############################################################################
CURRENT_SCRIPT=$(basename $0)
CURRENT_ARGS="$*"
CRON_COMBINED="/usr/share/doc/packages/sca-appliance-broker/combined.cron"
PHP_VERSION=''
WEB_MODULE=0
SERVER=$(hostname -f &>/dev/null)
[[ -z "$SERVER" ]] && SERVER=$HOSTNAME
ARCH_PREFIX='scc_'

title() {
	echo "####################################################################"
	echo "# SCA Appliance Setup Tool v$SVER"
	echo "####################################################################"
	echo
}

showHelp() {
	[[ -n "$1" ]] && { echo "$1"; echo; }
	echo "Usage: $CURRENT_SCRIPT [OPTIONS] Run the following command from each server you want analyzed:

 supportconfig -U 'ftp://${SERVER}/upload/'

 To view the analysis reports, goto the URL:

 https://${SERVER}/
"
	echo
	echo 'Description:'
	echo '  Configures the MySQL administration and report database used by'
	echo '  the Supportconfig Analysis Tools.'
	echo
	echo 'Options:'
	echo '  -h Show this screen and exit'
	echo '  -a Disable activating services'
	echo '  -b Disable Apache and MySQL daemon checks'
	echo '  -c <str> Company name'
	echo '  -d <str> Company email domain'
	echo '  -p <str> MySQL root password'
	echo '  -w <str> Web user password'
	echo "  -e <email> Admin email address (Default: local root user)"
	echo "  -s <server_name> Override the server hostname"
	echo "  -f Change to FTP archive source file:///srv/ftp/upload (Default: $ARCHIVE_LOCATION)"
	echo '  -y Confirms the deletion of a pre-existing database and users'
	echo
}

showUsage() {
	echo
	echo "SCA Appliance Server Configuration Complete"
	echo
	echo "To analyze supportconfigs:"
	echo " 1. Login as root on the SUSE server to be analyzed"
	if (( FTP_INSTALL ))
	then
		echo " 2. Run a supportconfig and upload the ${ARCH_PREFIX}<supportconfig_file>.tbz"
		echo "    to the appliance."
		echo " 3. Examples include:"
		echo
		echo "    supportconfig -U \"ftp://${SERVER}/upload/\""
		echo "    supportconfig -U \"scp://${SERVER}/srv/ftp/upload/\""
		echo "    ftp -u \"${SERVER}:/upload/${ARCH_PREFIX}<supportconfig_file>.tbz\" /path/to/local/${ARCH_PREFIX}<supportconfig_file>.tbz"
	else
		echo " 2. Run a supportconfig and upload the ${ARCH_PREFIX}<supportconfig_file>.tbz"
		echo "    to the appliance."
		echo " 3. Examples include:"
		echo
		echo "    supportconfig -U \"scp://${SERVER}/tmp\""
		echo "    scp /path/to/local/${ARCH_PREFIX}<supportconfig_file>.tbz ${SERVER}:/tmp"
	fi
	echo
	echo "To view the analysis reports, goto the URL:"
	echo
	echo " http://${SERVER}/sca/"
	echo
	echo "To check the status of the SCA Appliance Server, run:"
	echo
	echo " scadb"
	echo " See also: scadb help"
	echo
}

checkWebModule() {
	printf "$FMT2" "Web Module"
	if zypper lr 2>/dev/null | egrep -i "web-scripting-module|module-web-scripting" &>/dev/null
	then
		echo 'Installed'
		WEB_MODULE=1
	else
		echo 'Not Installed'
		echo; echo "  Install the Web and Scripting Module repository"; echo
		echo "  Run: SUSEConnect --list-extensions"; echo
		FATAL_ERROR=1
	fi
}

getPHPVersion() {
	printf "$FMT2" "PHP Version"
	FOUND_VERSION=0
	CHECK_VERSIONS="php8 php7 php5"
	for PHP_VERSION in $CHECK_VERSIONS
	do
		if zypper se ${PHP_VERSION}-mysql &>/dev/null; then
			FOUND_VERSION=1
			break
		fi
	done
	if (( FOUND_VERSION )); then
			echo $PHP_VERSION
	else
			echo "ERROR"
			PHP_VERSION='_php_'
			FATAL_ERROR=1
	fi
}

serverAccess()
{
	printf "$FMT2" "Pinging $USE_HOSTNAME"
	if ping -c1 -w1 $USE_HOSTNAME &>/dev/null; then
		echo Done
	else
		USE_HOSTNAME='localhost'
		echo "Failed, using $USE_HOSTNAME"
		printf "$FMT2" "Pinging $USE_HOSTNAME"
		if ping -c1 -w1 $USE_HOSTNAME &>/dev/null; then
			echo Done
		else
			echo FAILED
			echo; echo "  Cannot ping $USE_HOSTNAME"
			echo "  Fix the network or use -s to override the server name"; echo
			FATAL_ERROR=1
		fi
	fi
}

packageCheck()
{
	if rpm -q sca-appliance-agent &>/dev/null; then
		printf "$FMT1" "SCA Agent Package" "Installed"
	else
		printf "$FMT1" "SCA Agent Package" "ERROR: Not Installed"
		echo; echo "  Run: zypper install sca-appliance-agent"; echo
		FATAL_ERROR=1
	fi
	if rpm -q sca-appliance-patdev &>/dev/null; then
		printf "$FMT1" "SDP Database Package" "Installed"
		INSTALL_SDP=1
	else
		printf "$FMT1" "SDP Database Package" "Not Installed"
		INSTALL_SDP=0
	fi

	printf "$FMT2" "Additional Required Packages"
	REQUIRED_PACKAGES="${PHP_VERSION}-bz2 ${PHP_VERSION}-mbstring ${PHP_VERSION}-mysql ${PHP_VERSION}-zip ${PHP_VERSION}-zlib apache2-mod_${PHP_VERSION}"
	MISSING_PACKAGES=''
	for PACKAGE in $REQUIRED_PACKAGES
	do
		if ! rpm -q $PACKAGE &>/dev/null; then
			MISSING_PACKAGES="$PACKAGE $MISSING_PACKAGES"
		fi
	done
	PHP_DIR="/var/lib/${PHP_VERSION}"
	SCA_OWNER="wwwrun"
	if [[ -d $PHP_DIR ]]; then
		chown $SCA_OWNER $PHP_DIR
	fi
	if [[ -n "$MISSING_PACKAGES" ]]; then
		echo 'ERROR'
		if (( $WEB_MODULE )); then
			printf "$FMT1" "  Missing required packages:" "$MISSING_PACKAGES"
			echo; echo "  Run: zypper install $MISSING_PACKAGES"; echo
		fi
		FATAL_ERROR=1
	else
		echo Installed
	fi
}

checkDaemons()
{
	printf "$FMT2" "Apache Server"
	if rpm -q systemd &>/dev/null; then
		if rpm -q apache2 &>/dev/null; then
			if systemctl --quiet is-enabled apache2.service &>/dev/null
			then
				if  systemctl --quiet is-active apache2.service &>/dev/null
				then
					RESTART_APACHE=0
					echo "Active"
					APACHECTL_BIN="/usr/sbin/apache2ctl"
					if [[ -x $APACHECTL_BIN ]]
					then
						PHP_MODULE=$($APACHECTL_BIN -M 2>/dev/null | grep -i 'php' | grep '_module')
						if [[ -z "$PHP_MODULE" ]]
						then
							echo
							echo "Apache PHP Module Not Loaded"
							RESTART_APACHE=1
						fi
					else
						echo
						echo "Apache PHP Module May Not Be Loaded"
						RESTART_APACHE=1
					fi
					if [[ -s /var/run/httpd.pid ]]
					then
						HTTPD_PID=$(cat /var/run/httpd.pid)
					else
						HTTPD_PID=$(ps -eaf | grep sbin/httpd | sort -nk3 | head -1 | awk '{print $2}')
					fi
					if [[ -n "$HTTPD_PID" ]]
					then
						LOADED=$(lsof -p $HTTPD_PID | grep 'mysqli.so')
						if [[ -z "$LOADED" ]]
						then
							echo
							echo "Apache MySQL Libraries Not Loaded"
							RESTART_APACHE=1
						fi
					fi
					if (( RESTART_APACHE )); then
						echo
						echo "  Run: systemctl restart apache2.service"
						echo
						FATAL_ERROR=1
					fi
				else
					if (( ACTIVATE_SERVICES )); then
						systemctl start apache2.service &>/dev/null
						echo "Started"
					else
						echo "ERROR: $SUB_STATE"
						echo; echo "  Run: systemctl start apache2.service"; echo
						FATAL_ERROR=1
					fi
				fi
			else
				if (( ACTIVATE_SERVICES )); then
					systemctl enable apache2.service &>/dev/null
					systemctl start apache2.service &>/dev/null
					echo "Activated"
				else
					echo "ERROR: Disabled"; echo
					echo "  Run: systemctl enable apache2.service"
					echo "  Run: systemctl start apache2.service"; echo
					FATAL_ERROR=1
				fi
			fi
		else
			echo "ERROR: Not Installed"
			echo; echo "  Run: zypper install apache2"; echo
			FATAL_ERROR=1
		fi
	else
		echo "ERROR: Missing SystemD"
		echo; echo "  Manual configuration required"; echo
		FATAL_ERROR=1
	fi

	printf "$FMT2" "MySQL Server"
	if rpm -q mariadb &>/dev/null; then
		if systemctl --quiet is-enabled mysql &>/dev/null
		then
			if systemctl --quiet is-active mysql &>/dev/null 
			then
				echo "Active"
				if [[ -z "$PASS_MYSQL_ROOT" ]]; then
					printf "%s" " Enter MySQL root password: "
					read -s PASS_MYSQL_ROOT
					echo
				else
					printf "$FMT1" "MySQL Root Password" "Set"
				fi
				DB_ROOT="-u root -p${PASS_MYSQL_ROOT}"
			else
				if (( ACTIVATE_SERVICES )); then
					systemctl start mysql.service &>/dev/null
					echo "Started"; echo
					echo "  Run: mysql_secure_installation"; echo
				else
					echo "ERROR: Not Active"
					echo "  Run: systemctl start mysql.service"
					echo "  Run: mysql_secure_installation"; echo
				fi
				FATAL_ERROR=1
			fi
		else
			if (( ACTIVATE_SERVICES )); then
				systemctl enable mysql.service &>/dev/null
				systemctl start mysql.service &>/dev/null
				echo "Activated"; echo
				echo "  Run: mysql_secure_installation"; echo
			else
				echo "ERROR: Disabled"; echo
				echo "  Run: systemctl enable mysql.service"
				echo "  Run: systemctl start mysql.service"
				echo "  Run: mysql_secure_installation"; echo
			fi
			FATAL_ERROR=1
		fi
	else
		echo "ERROR: Not Installed"
		echo; echo "  Run: zypper install mariadb"; echo
		FATAL_ERROR=1
	fi
}

phpCheck()
{
	printf "$FMT2" "PHP Apache Module"
	ACONF="/etc/sysconfig/apache2"
	if [[ -s $ACONF ]]
	then
		if grep '^APACHE_MODULES=' $ACONF | grep "${PHP_VERSION}" &>/dev/null
		then
			echo 'Installed'
		else
			BCONF="${ACONF}.orig_setup-sca"
			[[ -s $BCONF ]] || mv $ACONF $BCONF
			sed -e "s/^APACHE_MODULES=\"\(.*\)\"/APACHE_MODULES=\"\1 ${PHP_VERSION}\"/" $BCONF > $ACONF
			echo 'Configured'
		fi
	else
		echo "File Not Found"
		FATAL_ERROR=1
	fi
}

checkFTP()
{
	printf "$FMT2" "FTP Server"
	if rpm -q systemd &>/dev/null; then
		SERVICE_NAME='vsftpd.service'
		if rpm --quiet -q vsftpd &>/dev/null; then
			if systemctl --quiet is-enabled $SERVICE_NAME &>/dev/null
			then
				if systemctl --quiet is-active $SERVICE_NAME &>/dev/null
				then	
					CONFIG_FILE='/etc/vsftpd.conf'
					echo "Active"
					if [[ -s $CONFIG_FILE ]]
					then
						FTP_CONFIG=$(egrep -i "^write_enable=yes|^anon_upload_enable=yes|^anonymous_enable=yes|^anon_root=/srv/ftp$" $CONFIG_FILE | wc -l)
						if (( FTP_CONFIG != 4 ))
						then
							echo
							echo "Anonymous FTP Server not Configured"; echo
							echo "  Run: yast ftp-server"
							echo "       Select: Authentication, Enable Upload, Anonymous Can Upload, Finish, Yes"
							echo
							FATAL_ERROR=1
						fi
					fi
				else
					echo "ERROR: $SUB_STATE"
					echo; echo "  Run: systemctl start $SERVICE_NAME"; echo
					FATAL_ERROR=1
				fi
			else
				echo "ERROR: Disabled"; echo
				echo "  Run: systemctl enable $SERVICE_NAME"
				echo "  Run: systemctl start $SERVICE_NAME"; echo
				FATAL_ERROR=1
			fi
		else
			echo "ERROR: Not Installed"; echo
			echo "  Run: zypper install vsftpd"
			echo "  Run: systemctl enable $SERVICE_NAME"
			echo "  Run: systemctl start $SERVICE_NAME"
			echo "  Run: yast ftp-server"
			echo "       Select: Authentication, Enable Upload, Anonymous Can Upload, Finish, Yes"
			echo
			FATAL_ERROR=1
		fi
	else
		echo "ERROR: Missing SystemD"
		echo; echo "  Manual configuration required"; echo
		FATAL_ERROR=1
	fi
}

checkDatabaseAccess()
{
	printf "$FMT2" "MySQL Database Access"
	DATABASES=$(mysql $DB_ROOT -NB -e "show databases" 2>/dev/null)
	if [[ -n "$DATABASES" ]]; then
		(( INSTALL_SDP )) && INSTALL_SDP_CONFIRMED=1
		echo Confirmed
	else
		echo 'ERROR: Denied'
		echo "  Confirm MySQL database root password"
		echo "  Consider running: mysql_secure_installation"
		echo
		restartMsg
		echo
		exit 3
	fi
}

installSDP()
{
	printf "$FMT2" "SCA Pattern Database"
	if echo "$DATABASES" | grep SCAPatterns &>/dev/null; then
		echo "Already Installed"
	else
		TMP=$(mktemp /tmp/setup-sca-sdp-XXXXXXXXXXXXXXX)
		[[ -z "$EMAIL_DOMAIN" ]] && EMAIL_DOMAIN=$(echo $EMAIL_USER_SCA | awk -F\@ '{print $2}')
		/usr/sbin/setup-sdp -p $PASS_MYSQL_ROOT -d "$EMAIL_DOMAIN" -c "$COMPANY_NAME" &>$TMP
		ERR=$?
		if (( ERR > 0 )); then
			echo 'ERROR'
			cat $TMP
			FATAL_ERROR=1
		else
			echo 'Done'
			sleep 1
		fi
	fi
}

setupBroker()
{
	if [[ -z "$PASS_WEB_USER" ]]; then
		printf "$FMT1" "Web User Password" "Not Set"
		printf "%s" " Set Web User password: "
		read -s PASS_WEB_USER
		echo
	else
		printf "$FMT1" "Web User Password" "Set"
	fi

	printf "$FMT2" "SCA Broker Setup"
	TMP=$(mktemp /tmp/setup-sca-sdbroker-XXXXXXXXXXXXXXX)
	/usr/sbin/setup-sdbroker -p $PASS_MYSQL_ROOT -b sdbroker_password -e $EMAIL_USER_SCA -i $ARCHIVE_LOCATION -w $PASS_WEB_USER &>$TMP
	ERR=$?
	if (( ERR > 0 )); then
		echo ERROR
		cat $TMP
		cleanUp
		exit 1
	else
		echo Done
		sleep 1
	fi
}

setupAgent()
{
	printf "$FMT2" "SCA Agent Setup"
	TMP=$(mktemp /tmp/setup-sca-sdagent-XXXXXXXXXXXXXXX)
	/usr/sbin/setup-sdagent -h $USE_HOSTNAME -p $PASS_MYSQL_ROOT &>$TMP
	ERR=$?
	if (( ERR > 0 )); then
		echo ERROR
		cat $TMP
		cleanUp
		exit 1
	else
		echo Done
		sleep 1
	fi
}

configureAgent()
{
	printf "$FMT2" "SCA Agent Configuration"
	TMP=$(mktemp /tmp/setup-sca-sdagent-config-XXXXXXXXXXXXXXX)
	/usr/sbin/sdagent-config -h $USE_HOSTNAME -l $USE_HOSTNAME -p sdagent_password -e $EMAIL_USER_SCA -i $ARCHIVE_LOCATION &>$TMP
	ERR=$?
	if (( ERR > 0 )); then
		echo ERROR
		cat $TMP
		cleanUp
		exit 1
	else
		echo Done
		sleep 1
	fi
}

configureCron()
{
	crontab $CRON_COMBINED
	printf "$FMT1" "Install Cron Entries" "Done"
}

cleanUp()
{
	rm -f /tmp/setup-sca-*
	echo
}

restartMsg()
{
	echo "Correct the errors"
	echo "  Repeat: $CURRENT_SCRIPT $CURRENT_ARGS"
	echo
}

############################################################################
# variables
############################################################################
FMT1="%-30s %s\n"
FMT2="%-30s "
PASS_MYSQL_ROOT=''
PASS_WEB_USER=''
EMAIL_USER_SCA=''
EMAIL_DOMAIN=''
ARCHIVE_LOCATION='file:///tmp/'
CONFIRMED=''
USE_HOSTNAME=''
COMPANY_NAME=''
DAEMON_CHECK=1
FATAL_ERROR=0
INSTALL_SDP_CONFIRMED=0
FTP_INSTALL=0
ACTIVATE_SERVICES=1

############################################################################
# main
############################################################################
while getopts ':abc:d:hp:w:e:fys:' TMPOPT
do
	case $TMPOPT in
		\:) title; showHelp "ERROR: Missing Argument -$OPTARG"; exit 1 ;;
		\?) title; showHelp "ERROR: Invalid Option -$OPTARG"; exit 2 ;;
		h) title; showHelp; exit 0 ;;
		a) ACTIVATE_SERVICES=0 ;;
		b) DAEMON_CHECK=0 ;;
		c) COMPANY_NAME=$OPTARG ;;
		d) EMAIL_DOMAIN=$OPTARG ;;
		p) PASS_MYSQL_ROOT=$OPTARG ;;
		w) PASS_WEB_USER=$OPTARG ;;
		s) USE_HOSTNAME=$OPTARG ;;
		e) EMAIL_USER_SCA=$OPTARG ;;
		f) FTP_INSTALL=1; ARCHIVE_LOCATION="file:///srv/ftp/upload" ;;
		y) CONFIRMED='-y' ;;
	esac
done
[[ -z "$EMAIL_USER_SCA" ]] && EMAIL_USER_SCA="root"
[[ -z "$USE_HOSTNAME" ]] && USE_HOSTNAME=$HOSTNAME

############################################################################
title
serverAccess
checkWebModule
getPHPVersion
phpCheck
packageCheck
printf "$FMT1" "Archive Location" "$ARCHIVE_LOCATION"
printf "$FMT1" "Administrator Email" "$EMAIL_USER_SCA"
if (( DAEMON_CHECK )); then
	(( FTP_INSTALL )) && checkFTP
	checkDaemons
	checkDatabaseAccess
else
	(( FTP_INSTALL )) && printf "$FMT1" "FTP Server" "Not Checked"
	printf "$FMT1" "Apache Server" "Not Checked"
	printf "$FMT1" "MySQL Server" "Not Checked"
fi
(( FATAL_ERROR )) && { cleanUp; restartMsg; exit 2; }
(( INSTALL_SDP_CONFIRMED )) && installSDP
if echo "$DATABASES" | grep ServerDiagnostics &>/dev/null; then
	printf "$FMT1" "SCA Appliance Database" "Already Installed"
	showUsage
	FATAL_ERROR=1
fi
(( FATAL_ERROR )) && { cleanUp; exit 4; }
setupBroker
setupAgent
configureAgent
configureCron
showUsage
cleanUp


