#!/bin/bash
#
# Script to pull Serial Number inventory of all hosts and PV storage Enclosures
#
# Revision History:
# 1.0   -   Initial release
# 1.1   -   Fixed issue with ssh racadm command
# 1.2   -   Sped up port test with 2 second timeout to speed up script	
#
#
#-------------- Functions ---------------------
#
# Check input provided - $1 TARGET
function input-check () {
# Copy all-systems to ALLSYS or generate ALLSYS from orchestration data
ALLSYS=`mktemp`
mongoexport --quiet --ssl --sslPEMKeyFile /etc/pki/nw/node/nodeadmin.pem --tlsInsecure --authenticationMechanism MONGODB-X509 --authenticationDatabase '$external' --db orchestration-server --collection host  | jq -r -c 'select(.thirdParty | not) | [ (.installedServices | sort | join("+")), .displayName, .hostname, ._id, .version.rawVersion] | @csv' | sed 's/\"//g' | sed 's/Packet/Network/g' | sort > "${ALLSYS}"
if [ -s ${ALLSYS} ];then
    echo "All-Systems...      [ OK ]"
else
    echo "Unable to create list from orchestration server host data, aborting..."
    exit 1
fi
DEVICES=`mktemp`
if [ ${1} == "ALL" ];then
    echo "Using List of all systems"
    cat ${ALLSYS} > "${DEVICES}"
elif [ "${1}" == "-h" ];then
        usage
else
    echo "Using grep of [ ${1} ] from all systems list"
    cat ${ALLSYS} | grep -i "${1}" > "${DEVICES}"
    if [ ! -s ${DEVICES} ];then
        writeLog "Error: ${1} does not exist in list of all systems, exiting..."
        exit 1
    fi
fi
}
#
# Usage statement
function usage () {
    echo " Usage:"
    echo ""
    echo "  ./genInventory [ hostname | -h ]"
    echo ""
    echo "   With no options, runs against all hosts."
    echo "   hostname : runs agains specific host(s), (grep from list of all systems)"
    echo "   -h : displays this statement"
    exit 0
}
#
# Get IP address of iDRAC using IPMITOOL - $1 HOSTNM
function get-ip () {
    IDRACIP=""
    IDRACIP="$(salt -G "nodename:${1}" cmd.run 'ipmitool lan print' 2>/dev/null | grep 'IP Address' | grep -v 'Static' | awk -F: '{print $2}' | xargs)"
    echo "${IDRACIP}"
}
#
# Check connection to IDRAC IP on port 443 or 22 - $1 DRACIP
function check-ip-port () {
    unset PORT
    if (timeout 2 nc -zv ${1} 443) 2>/dev/null;then
        PORT=443
    elif (timeout 2 nc -zv ${1} 22) 2>/dev/null;then
        PORT=22
    fi
    echo ${PORT}
}
#
# Check that connection can be made and get iDRAC name- $1 DRACIP - $2 DRACPORT (NOTE: for SSH connections strict host checking is disabled, to automatically add the IP to known_hosts file.)
function get-hostsn () {
    unset SVCTAG
    if [ ${2} -eq 443 ];then
        SVCTAG="$(racadm -r ${1} -u root -p ${DRACPW} getsvctag | sed 's/\r//g'| grep -v certificate | xargs)"
    else
        SVCTAG="$(sshpass -p ${DRACPW} ssh -n -q -o StrictHostkeyChecking=no ${1} racadm getsvctag | sed 's/\r//g')"
    fi
    echo "${SVCTAG}"
}
#
# Get specified data from iDRAC and return - $1 IDRACIP - $2 DRACPORT
function get-data () {
    unset ENCINFO ENCTYPE
    if [ ${2} -eq 443 ];then
        if [ -n "$(racadm -r ${1} -u root -p ${DRACPW} storage get enclosures | grep -v certificate | grep External| sed 's/\r//g' | xargs)" ];then
            ENCTYPE="$(racadm -r ${1} -u root -p ${DRACPW} storage get enclosures -o  | grep -v certificate | grep AssetName | awk -F= '{print $2}' | tail -1 | xargs)"
            if [ "${ENCTYPE}" == "MD1400" ];then
                ENCINFO="$(racadm -r ${1} -u root -p ${DRACPW} storage get enclosures -o  | grep -v certificate | grep  ServiceTag | awk -F= '{print $2}' | xargs)"
            else
                ENCTYPE="ESES"
                ENCINFO="DAC_Enclosures_no_Serial_Number"
            fi
        else
            ENCTYPE="NONE"
	    ENCINFO="No_Attached_PV_Storage"
        fi
    else
        if [ -n "$(sshpass -p ${DRACPW} ssh -n -q ${1} racadm storage get enclosures | grep External | xargs)" ];then
            ENCTYPE="$(sshpass -p ${DRACPW} ssh -n -q ${1} racadm storage get enclosures -o | grep AssetName | awk -F= '{print $2}' | tail -1 | xargs)"
            if [ "${ENCTYPE}" == "MD1400" ];then
                ENCINFO="$(sshpass -p ${DRACPW} ssh -n -q ${1} racadm storage get enclosures -o  | grep  ServiceTag | awk -F= '{print $2}' | xargs)"
            else
                ENCTYPE="ESES"
                ENCINFO="DAC_Enclosures_no_Serial_Number"
            fi
        else
            ENCTYPE="NONE"
            ENCINFO="No_Attached_PV_Storage"
        fi
    fi
    echo "${ENCTYPE} ${ENCINFO}"
}


#--------------------Main program start---------------------------
#
TODAY=$(date -I)
TARGET="ALL"
WORKDIR="/root/scripts/inventory"
if [ $# -eq 1 ];then
    TARGET="${1}"
fi
#
# check input
input-check ${TARGET}
# verify output directory
if [ ! -d ${WORKDIR} ];then
    mkdir ${WORKDIR}
fi
OUTFILE=${WORKDIR}/System-Inventory-${TARGET}-${TODAY}.csv
if [ -e ${OUTFILE} ];then
    cp /dev/null ${OUTFILE}
else
    touch ${OUTFILE}
fi
#
# get idrac password or use default
read -t 60 -s -p "Enter password for iDRAC root: " DRACPW
    if [ -z "${DRACPW}" ];then
        echo "";echo "No password entered using default"
        DRACPW="themaster01"
    fi
echo ""
#
# Iterate through devices and update settings
echo "Hostname,HostSN,Storge Type,Storage SN(s)" > "${OUTFILE}"
for HOSTNM in $(cat ${DEVICES} | awk -F, '{print $2}');do
    echo -n "Get iDRAC IP for ${HOSTNM}... "
    unset DRACIP
    read DRACIP < <(get-ip ${HOSTNM})
    if [ -z "${DRACIP}" ];then
        echo "[ FAILED ]"
        echo "${HOSTNM},FAILED,Unable_to_get_iDrac_IP,skipped" >> "${OUTFILE}"
        continue
    else
        echo -n "Testing connectivity (443/22) to ${DRACIP} ... "
        unset DRACPORT
        read DRACPORT < <(check-ip-port ${DRACIP})
        if [ ! -z "${DRACPORT}" ];then
            echo "[ ${DRACPORT} OK ]"
            echo -n "Testing RACADM access... "
            unset HOSTSN
            read HOSTSN < <(get-hostsn ${DRACIP} ${DRACPORT})
            if [ -z "${HOSTSN}" ];then
                echo "[ FAILED ]"
                echo "${HOSTNM},FAILED,Unable_to_connect_to_iDRAC,skipped" >> "${OUTFILE}"
                continue
            else
                echo "[ RACADM OK ]"
                echo -n "Get External PV Storage info... "
                unset PVTYP PVSN
                read PVTYP PVSN < <(get-data ${DRACIP} ${DRACPORT})
                if [ -z "${PVSN}" ];then
                    echo "[ FAILED ]"
                    echo "${HOSTNM},FAILED,Unable_to_get_Enclosure_Info,skipped" >> "${OUTFILE}"
                else
                    echo "[ PVSN OK ]"
                    echo "${HOSTNM},${HOSTSN},${PVTYP},${PVSN}" >> ${OUTFILE}
                fi
            fi
        else
            echo "[ FAILED ]"
            echo "${HOSTNM},FAILED,Unable_to_connect_to_iDRAC_on_port_443_or_22,skipped" >> "${OUTFILE}"
            continue
        fi
    fi
done
cat ${OUTFILE}
# Cleanup
rm -f "${DEVICES}"
rm -f "${ALLSYS}"
exit 0
