#!/usr/bin/bash
#
# Check whether login to slice is possible
# Copyright (C) 2016-2024 by Thomas Dreibholz
#
# 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, either version 3 of the License, or
# (at your option) any later version.
#
# 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/>.
#
# Contact: dreibh@simula.no

SLICE=srl_test
KEY=~/.ssh/test2

disabledIntro="\x1b[37m"
unreachableIntro="\x1b[34m"
keyChangedIntro="\x1b[36m"
goodIntro="\x1b[32m"
badIntro="\x1b[31m"
normalMode="\x1b[0m"

connectTimeout=15
sigkillTimeout=60
sigintTimeout=55
sshOptions="-4 -oVerifyHostKeyDNS=yes -oHostKeyAlgorithms=rsa-sha2-512 -oStrictHostKeyChecking=no -oPasswordAuthentication=no -oConnectTimeout=$connectTimeout"


function check-node ()
{
   local nodeName="$1"

   if ping -4 -q -c3 -W2 $nodeName >/dev/null 2>&1 ; then
      if ping -6 -q -c3 -W2 $nodeName >/dev/null 2>&1 ; then

         env LANG=C timeout --signal=INT --kill-after=${sigkillTimeout}s ${sigintTimeout} ssh $sshOptions -i $KEY $SLICE@$nodeName '
            if [ ! -e /etc/yum.repos.d/nornet.repo ] ; then
               echo "WARNING: NO-NORNET-REPO"
            fi
            domainName=`hostname -d`
            if ! sudo ping -q -c5 -i0.3 tunnelbox.${domainName} >/dev/null 2>&1 ; then
               echo "FAILED: PING4-TUNNELBOX"
            fi
            if ! sudo ping6 -q -c5 -i0.3 tunnelbox.${domainName} >/dev/null 2>&1 ; then
               echo "FAILED: PING6-TUNNELBOX"
            fi
            echo "Node is UP"
            echo "`cat /etc/fedora-release | sed -e "s/^\(.*\) release \([0-9]*\) (\(.*\))$/\1 \2/g"`: `uname -r`, `uptime`"
         ' >$nodeName.log 2>&1

         headline="`grep -v "^Warning: Permanently" $nodeName.log | head -n1 | tr --delete '\n\r'`"
         if [ "$headline" = "Node is UP" ] ; then
            printf "$goodIntro%s\tOK\t%-30s\t\"%s\"$normalMode\n" \
               "$site" "$nodeName" \
               "`tail -n1 $nodeName.log | tr --delete '\n\r' | sed -e "s/^[ \t]*//g"`"
         elif [[ "$headline" =~ ^(@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@|Warning: the RSA host key for ) ]] ; then
            printf "$keyChangedIntro%s\tKEY\t%-30s\t\"%s\"$normalMode\n" \
               "$site" "$nodeName" "Key changed -> run script again! ($headline)"
            ./Clear-SSH-Node-Key $nodeName >/dev/null
         else
            printf "$badIntro%s\tBAD\t%-30s\t\"%s\"$normalMode\n" \
               "$site" "$nodeName" \
               "$headline"
         fi

      else
         printf "$unreachableIntro%s\tNET6\t%-30s$normalMode\n" \
            "$site" "$nodeName"
      fi
   else
      printf "$unreachableIntro%s\tNET\t%-30s$normalMode\n" \
         "$site" "$nodeName"
   fi
}


program="$0"
if [ $# -ge 1 ] ; then
   SLICE="$1"
   shift
fi
if [ $# -ge 1 ] ; then
   KEY="$1"
   shift
fi

if [ ! -e $KEY ] ; then
   echo >&2 "ERROR: SSH private key $KEY not found!"
   exit 1
fi


nodeList=""
while [ $# -gt 0 ] ; do
   if [ "$1" = "-n" ] ; then
      unreachableIntro=""
      goodIntro=""
      badIntro=""
      normalMode=""
   elif [[ "$1" =~ ^-.*$ ]] ; then
      echo >&2 "Usage: $program [slice] [SSH_private_key] [-n] [node ...]"
      exit 1
   else
      nodeList="$nodeList $1"
   fi
   shift
done

if [ "$nodeList" = "" ] ; then ./Get-Slice-Nodes "$SLICE" ; else echo "$nodeList" | xargs -n1 ; fi | (
   while read node status ; do
      site=`echo "$node" | sed -e "s/^[a-z0-9]*\.//g"`
      if [ "$status" != "disabled" ] ; then
         check-node "$node" &
      else
         printf "$disabledIntro%s\tN/A\t%-30s$normalMode\n" \
            "$site" "$node"
      fi
   done
   wait
) | sort -k2,2r -k1,1
