#!/bin/sh

################################################################################
# Copyright (c) 2020-2022 Hitachi Vantara, Inc.
#
# All rights reserved.  This software may not be copied, disclosed,
# transferred, or used except in accordance with a license granted
# by Hitachi Vantara, Inc. This software embodies proprietary
# information and trade secrets of Hitachi Vantara, Inc.
#
# This script gathers configuration information for an HCI cluster.
# Very handy for when trying to understand how things are all set up.
# Originally written by Chris Kiessling, Summer, 2020.
################################################################################

SCRIPT_VERSION="1.7 2022-04-01"

WATCHDOGSERVICE="watchdog-service"
DOCKERCOMMAND="docker exec ${WATCHDOGSERVICE}"

function printusagestring {
   >&2 echo
   >&2 echo "Usage: $0 [ { -a | -s | -m | -w } ] [-t]"
   >&2 echo "       If -a is used, AdminApp information is collected."
   >&2 echo "       If -w is used, WorkflowApp information is collected."
   >&2 echo "       If -s is used, SearchApp information is collected. NOT YET WORKING."
   >&2 echo "       If -m is used, MonitorApp information is collected."
   >&2 echo "       If none of the above options are used, all information is collected."
   >&2 echo
   >&2 echo "       If -t is used, script will tar up results into a single compressed tar file."
}

GETALL=1
GETADMIN=0
GETSEARCH=0
GETMONITOR=0
GETWORKFLOW=0
while getopts asmwtv name
do
   case $name in
      a) GETALL=0; GETADMIN=1;;
      s) GETALL=0; GETSEARCH=1;;
      m) GETALL=0; GETMONITOR=1;;
      w) GETALL=0; GETWORKFLOW=1;;
      t) TARACTION=TRUE;;
      v) echo $0 - Version $SCRIPT_VERSION
         exit;;
      *) printusagestring
         exit;;
   esac
done
shift $((OPTIND -1))

echo

# Before we do anything, let's just check to see if systemctl thinks HCI service is installed and running.
systemctl status HCI > /dev/null 2>&1
if [ $? != 0 ]
then
   echo "Error: HCI is either not installed or not running on this host.  Exiting."
   exit
fi

# Prompt for username & password:
echo -n "Enter username (CR for 'admin'): "
read USERNAME
[ -z "$USERNAME" ] && USERNAME="admin"

echo -n "Enter password for '${USERNAME}' user: "
read -s USERPASS
[ -z "$USERPASS" ] && USERPASS="start123"

echo;echo -n "Enter realm for '${USERNAME}' user (CR for 'local'): "
read REALM
[ -z "$REALM" ] && REALM="local"
echo

CREDS="-r ${REALM} -u ${USERNAME} -p ${USERPASS}"

# This sets the variable INSTALLDIR according to the installdir in this docker container:
eval $(docker inspect ${WATCHDOGSERVICE} | grep INSTALLDIR | awk -F\" '{print $2}')

if [ -z "${INSTALLDIR}" ]
then
   echo "ERROR: Unable to determine INSTALLDIR.  Exiting."
   exit
fi

# Test username and password - dont go any further if they are wrong.
TMPFILE=$(mktemp)
${DOCKERCOMMAND} ${INSTALLDIR}/cli/admin/admincli ${CREDS} -c getSetup > /dev/null 2> ${TMPFILE}
if [ -s ${TMPFILE} ]
then
   cat ${TMPFILE}
   rm ${TMPFILE}
   exit
fi
rm $TMPFILE

# OK - Got here, so it's OK to go ahead and make directory structure:

# Make a directory to put everything - use date
OUTPUTDIR=./HCIcollection_$(date "+%Y%m%d-%H%M")
FILTER="grep -v modelVersion"

if [ -d ${OUTPUTDIR} ]
then
   mv ${OUTPUTDIR} ${OUTPUTDIR}_OLD_${RANDOM}
fi
mkdir ${OUTPUTDIR}

# Collect generic information into the Info diectory:
INFODIR=${OUTPUTDIR}/info
mkdir ${INFODIR}
hostname                      > ${INFODIR}/hostname
hostname -I                   > ${INFODIR}/hostname-I
uname -a                      > ${INFODIR}/uname
docker info                   > ${INFODIR}/docker_info
docker ps                     > ${INFODIR}/docker_ps
docker image ls               > ${INFODIR}/docker_image_ls
df -h                         > ${INFODIR}/df-h
timedatectl status            > ${INFODIR}/timedatactl_status
journalctl --list-boots       > ${INFODIR}/journalctl_listboots
journalctl -u HCI             > ${INFODIR}/journalctl_hci
nmcli connection show         > ${INFODIR}/networkconnections
echo "Run on " $(/bin/date)   > ${INFODIR}/rundate
echo "${INSTALLDIR}"          > ${INFODIR}/installdir
cp ${INSTALLDIR}/log/com.hds.ensemble.plugins.service.watchdog/environment.host ${INFODIR}/environment.host
systemctl status firewalld    > ${INFODIR}/firewalld_status

# If firewalld is running, we will grab some firewall zone settings:
STATUS="$(systemctl is-active firewalld)"
if [ "${STATUS}" = "active" ]; then
   FIREWALLDIR=${INFODIR}/firewall
   mkdir ${FIREWALLDIR}
   firewall-cmd --get-default-zone      > ${FIREWALLDIR}/defaultzone
   firewall-cmd --get-active-zones      > ${FIREWALLDIR}/activeZones
   ipset list                           > ${FIREWALLDIR}/ipset-list
   for z in $(firewall-cmd --get-zones)
   do
      firewall-cmd --zone $z --list-all > ${FIREWALLDIR}/zone_${z}
   done
fi

function getSpecificInfo {
   DESCRIPTORS=$1
   CLICMD=$2
   CLIGETCOMMAND=$3

   echo "   ${DESCRIPTORS}..."
   TABLE=$(mktemp)
   SUBDIR=${APPDIR}/${DESCRIPTORS}
   mkdir $SUBDIR
   ${CLIBIN} ${CREDS} -c ${CLICMD} | egrep '(^    "name|^    "uuid)' | awk -F: '{print $2}' | sed 'N;s/\n/ /' > $TABLE
   exec < $TABLE; while read -r inline
   do
       NAME=$(echo $inline | awk -F\, '{print $1}' | sed -e 's/"//g' | sed -e 's/ /_/g')
       UUID=$(echo $inline | awk -F\, '{print $2}')
       echo "      ${NAME}..."
       ${CLIBIN} ${CREDS} -c ${CLIGETCOMMAND} --uuid ${UUID} | ${FILTER} > $SUBDIR/${NAME}
   done
   rm $TABLE
}

echo

###############################################################################
if [ ${GETWORKFLOW} -eq 1 ] || [ ${GETALL} -eq 1 ]
then
   CLIBIN="${DOCKERCOMMAND} ${INSTALLDIR}/cli/workflow/workflowcli"
   APPDIR=${OUTPUTDIR}/workflowApp

   # Check to see if workflowApp is set up - if not, there's nothing to collect here.
   TMPFILE=$(mktemp)
   ${CLIBIN} ${CREDS} -c getSetup > /dev/null 2> ${TMPFILE}
   if [ -s ${TMPFILE} ]
   then
      echo
      echo "Not collecting workflow information because Workflow Designer App is not set up."
   else
      echo
      echo Collecting WorkflowApp information...
      mkdir ${APPDIR}

      getSpecificInfo Workflows         listWorkflows   getWorkflow
      getSpecificInfo DataConnectors    listDataSources getDataSource
      getSpecificInfo Pipelines         listPipelines   getPipeline
      getSpecificInfo Indexes           listIndexes     getIndex
      getSpecificInfo IndexShards       listIndexes     getIndexClusterState
      getSpecificInfo IndexStatistics   listIndexes     getIndexStatistics
   
      echo "   task information"
      ${CLIBIN} ${CREDS} -c listTasks | ${FILTER} > ${APPDIR}/tasks.json
   
      echo "   setup information..."
      ${CLIBIN} ${CREDS} -c getSetup | ${FILTER} > ${APPDIR}/setup.json
   
      echo "   alert information..."
      ${CLIBIN} ${CREDS} -c listAlerts | ${FILTER} > ${APPDIR}/alerts.json
   
      echo "   contentClass information..."
      ${CLIBIN} ${CREDS} -c listContentClasses | ${FILTER} > ${APPDIR}/contentclasses.json
   fi
fi
   
###############################################################################

if [ ${GETADMIN} -eq 1 ] || [ ${GETALL} -eq 1 ]
then
   CLIBIN="${DOCKERCOMMAND} ${INSTALLDIR}/cli/admin/admincli"
   APPDIR=${OUTPUTDIR}/adminApp
   mkdir ${APPDIR}

   echo
   echo Collecting AdminApp information.

   echo "  about alerts...";             ${CLIBIN} ${CREDS} -c listAlerts            | ${FILTER} > ${APPDIR}/alerts.json
   echo "  about instances...";          ${CLIBIN} ${CREDS} -c listInstances         | ${FILTER} > ${APPDIR}/instances.json
   echo "  about licenses...";           ${CLIBIN} ${CREDS} -c listLicenses          | ${FILTER} > ${APPDIR}/licenses.json
   echo "  about groups...";             ${CLIBIN} ${CREDS} -c listGroups            | ${FILTER} > ${APPDIR}/groups.json
   echo "  about identity providers..."; ${CLIBIN} ${CREDS} -c listIdentityProviders | ${FILTER} > ${APPDIR}/identityProviders.json
   echo "  about permissions...";        ${CLIBIN} ${CREDS} -c listPermissions       | ${FILTER} > ${APPDIR}/permissions.json
   echo "  about roles...";              ${CLIBIN} ${CREDS} -c listRoles             | ${FILTER} > ${APPDIR}/roles.json
   echo "  about update history...";     ${CLIBIN} ${CREDS} -c getUpdateHistory      | ${FILTER} > ${APPDIR}/updateHistory.json
   echo "  about update status...";      ${CLIBIN} ${CREDS} -c getUpdateStatus       | ${FILTER} > ${APPDIR}/updateStatus.json
   echo "  about certificates...";       ${CLIBIN} ${CREDS} -c listCertificates      | ${FILTER} > ${APPDIR}/certificates.json
   echo "  about jobs...";               ${CLIBIN} ${CREDS} -c listJobs              | ${FILTER} > ${APPDIR}/jobs.json
   echo "  about job status...";         ${CLIBIN} ${CREDS} -c getAllJobStatus       | ${FILTER} > ${APPDIR}/jobstatus.json
   echo "  about services...";           ${CLIBIN} ${CREDS} -c queryServices --sqrm-requested-details  metrics,config,status,instances,serviceinstances | ${FILTER} > ${APPDIR}/services.json
   echo "  about notifications...";      ${CLIBIN} ${CREDS} -c listNotificationRules | ${FILTER} > ${APPDIR}/notifications.json
   echo "  about setup...";              ${CLIBIN} ${CREDS} -c getSetup              | ${FILTER} > ${APPDIR}/setup.json
   echo "  about system setup...";       ${CLIBIN} ${CREDS} -c getSystemSetup        | ${FILTER} > ${APPDIR}/system_setup.json
   echo "  about plugins...";            ls -l ${INSTALLDIR}/plugins > ${APPDIR}/plugins.txt

   # Collect the full event log
   echo "  collecting the event log..."

   # Create tmp file to contain the following awk script to convert epoch times to UTC:
   TIMECONVERTAWKFILE=$(mktemp)
   cat << EOF > ${TIMECONVERTAWKFILE}
/"time":/ {print "      \"time\":", strftime("%F %H:%M:%S",substr(\$2,1,10),1), "UTC"}
!/"time":/ {print \$0}
EOF
   EVENTSBODY=$(mktemp)
   echo '{"sortFields":[{"sortField":"time","sortOrder":"DESC"}],"count":10000,"offset":0}' > ${EVENTSBODY}
   docker cp ${EVENTSBODY} ${WATCHDOGSERVICE}:${EVENTSBODY}
   ${CLIBIN} ${CREDS} -c queryEvents --event-query-request-model ${EVENTSBODY} | ${FILTER} | awk -f ${TIMECONVERTAWKFILE} > ${APPDIR}/eventlog.json
   rm ${EVENTSBODY} ${TIMECONVERTAWKFILE}
   ${DOCKERCOMMAND} rm ${EVENTSBODY}
fi


###############################################################################

if [ ${GETMONITOR} -eq 1 ] || [ ${GETALL} -eq 1 ]
then
   CLIBIN="${DOCKERCOMMAND} ${INSTALLDIR}/cli/monitor/monitorcli"
   APPDIR=${OUTPUTDIR}/monitorApp

   # Check to see if monitor is set up - if not, there's nothing to collect here.
   TMPFILE=$(mktemp)
   ${CLIBIN} ${CREDS} -c getSetup > /dev/null 2> ${TMPFILE}
   if [ -s ${TMPFILE} ]
   then
      echo
      echo "Not collecting monitor information because monitor (HCM) is not set up."
   else
      echo
      echo Collecting MonitorApp information.
      mkdir ${APPDIR}

      echo "  about status...";                ${CLIBIN} ${CREDS} -c getStatus                | ${FILTER} > ${APPDIR}/Status.json
      echo "  about system setup...";          ${CLIBIN} ${CREDS} -c getSystemSetup           | ${FILTER} > ${APPDIR}/SystemSetup.json
      echo "  about clusterInfo...";           ${CLIBIN} ${CREDS} -c getClusterInfo           | ${FILTER} > ${APPDIR}/ClusterInfo.json
      echo "  about settings...";              ${CLIBIN} ${CREDS} -c getSettings              | ${FILTER} > ${APPDIR}/Settings.json
      echo "  about setup...";                 ${CLIBIN} ${CREDS} -c getSetup                 | ${FILTER} > ${APPDIR}/Setup.json
      echo "  about alerts...";                ${CLIBIN} ${CREDS} -c listAlerts               | ${FILTER} > ${APPDIR}/Alerts.json
      echo "  about connector plugins...";     ${CLIBIN} ${CREDS} -c listConnectorPlugins     | ${FILTER} > ${APPDIR}/ConnectorPlugins.json
      echo "  about dashboards...";            ${CLIBIN} ${CREDS} -c listDashboards           | ${FILTER} > ${APPDIR}/Dashboards.json
      echo "  about data sources...";          ${CLIBIN} ${CREDS} -c listDataSources          | ${FILTER} > ${APPDIR}/DataSources.json
      echo "  about forcast dashboards...";    ${CLIBIN} ${CREDS} -c listForecastDashboards   | ${FILTER} > ${APPDIR}/ForecastDashboards.json
      echo "  about historical sources...";    ${CLIBIN} ${CREDS} -c listHistoricalSources    | ${FILTER} > ${APPDIR}/HistoricalSources.json
      echo "  about monitored history...";     ${CLIBIN} ${CREDS} -c listMonitoredHistory     | ${FILTER} > ${APPDIR}/MonitoredHistory.json
      echo "  about moniroted queues...";      ${CLIBIN} ${CREDS} -c listMonitoredQueries     | ${FILTER} > ${APPDIR}/MonitoredQueries.json
      echo "  about sender plugins...";        ${CLIBIN} ${CREDS} -c listSenderPlugins        | ${FILTER} > ${APPDIR}/SenderPlugins.json
      echo "  about senders...";               ${CLIBIN} ${CREDS} -c listSenders              | ${FILTER} > ${APPDIR}/Senders.json
      echo "  about signal sources...";        ${CLIBIN} ${CREDS} -c listSignalSources        | ${FILTER} > ${APPDIR}/SignalSources.json
      echo "  about signal source plugins..."; ${CLIBIN} ${CREDS} -c listSignalSourcePlugins  | ${FILTER} > ${APPDIR}/SignalSourcePlugins.json
      echo "  about visualization plugins..."; ${CLIBIN} ${CREDS} -c listVisualizationPlugins | ${FILTER} > ${APPDIR}/VisualizationPlugins.json

      # This stuff requires some additional logic to 'get' each type of thing.
      # ${CLIBIN} ${CREDS} -c getDashboard              | ${FILTER} > ${APPDIR}/Dashboard.json
      # ${CLIBIN} ${CREDS} -c getDataSource             | ${FILTER} > ${APPDIR}/DataSource.json
      # ${CLIBIN} ${CREDS} -c getForecastDashboard      | ${FILTER} > ${APPDIR}/ForecastDashboard.json
      # ${CLIBIN} ${CREDS} -c getHistoricalSource       | ${FILTER} > ${APPDIR}/HistoricalSource.json
      # ${CLIBIN} ${CREDS} -c getMonitoredQuery         | ${FILTER} > ${APPDIR}/MonitoredQuery.json
      # ${CLIBIN} ${CREDS} -c getRemoteCertificate      | ${FILTER} > ${APPDIR}/RemoteCertificate.json
      # ${CLIBIN} ${CREDS} -c getSender                 | ${FILTER} > ${APPDIR}/Sender.json
      # ${CLIBIN} ${CREDS} -c getSignalSource           | ${FILTER} > ${APPDIR}/SignalSource.json
   fi
   rm ${TMPFILE}
fi

###############################################################################
# # CK: Still not sure this is helpful to gather using this script.  Leave this part in for now....
# 
# if [ ${GETSEARCH} -eq 1 ] || [ ${GETALL} -eq 1 ]
# then
#    CLIBIN=" ${DOCKERCOMMAND} ${INSTALLDIR}/cli/search/searchcli"
#    APPDIR=${OUTPUTDIR}/searchApp
#    mkdir ${APPDIR}
# 
#    echo Collecting SearchApp information...
#    echo "  about Queries...";   ${CLIBIN} ${CREDS} -c listMonitoredQueries  | ${FILTER} > ${APPDIR}/monitoredqueries.json
#    echo "  about History...";   ${CLIBIN} ${CREDS} -c listMonitoredHistory  | ${FILTER} > ${APPDIR}/monitoredhistory.json
#    # Add this in:  for each query found, run a 'getMonitoredQuery'.
# fi


echo
if [ -z "${TARACTION}" ]
then
   echo Output is in ${OUTPUTDIR}
else
   echo; echo "Creating compressed tar file..."
   tar czf ${OUTPUTDIR}.tgz ${OUTPUTDIR}
   rm -rf ${OUTPUTDIR}
   echo Output is in ${OUTPUTDIR}.tgz
fi

echo Done.