#!/bin/bash
# -----------------------------------------------------------------------------
# tech_card-mgr            
#                                      
# July 2015, Rahul Mathur 
#                
# Copyright (c) 2015-2016, 2019-2021 by cisco Systems, Inc.
# All rights reserved.
#------------------------------------------------------------------------------
# This script contains all the CLI commands to be captured. The worker routine
# "display" of this script does the exection of the commands using the "show_cmd"
# binary present in the /opt/cisco/calvados/bin
#
# Load the script provided by show-tech infra, which provides worker functions
#
source /opt/cisco/calvados/script/show_tech_main_fragment

#
# Parse the arguments to the script - card type and interface filter are the 
# only support options currently.  No need to use the default parser function,
# as this has been done by caller.
#
__cardtype="unspecified"
trace_only="0"
show_only="0"
host_ip="0"

get_host_ip host_ip

while [ "$#" -gt "0" ]; do
    case "$1" in
        -T) trace_only="1"; shift 1;;
        -S) show_only="1"; shift 1;;
        -t) __cardtype="$2"; shift 2;;
        -f) media_path="$2"; shift 2;;
        *) last_arg=$1; echo LAST $last_arg; shift;;
    esac
done
if [ "$__cardtype" == "unspecified" ]; then
    __cardtype=`/opt/cisco/calvados/script/node_type`
fi

nodename=$(uname -n | cut -d ":"  -f2)

PLATFORM_OUTPUT="/tmp/show_platform.output"
declare -a fc_list
declare -a lc_list
declare -a cc_list

function platform_type_get {
    PLATFORM="$(cat /proc/cmdline|awk -F"platform=" '{print $2}'|cut -d' ' -f1)"
}

#Generate DCP list specific to whitebox
generate_lc_list() {
    /opt/cisco/calvados/bin/show_cmd "terminal length 0; show platform" > $PLATFORM_OUTPUT
    let lc_list_cnt=0
    for loc in $(grep "/0 .*OPERATIONAL" $PLATFORM_OUTPUT | awk '{ print $1}'); do
        lc_list[$lc_list_cnt]=$loc
        lc_list_cnt=$((lc_list_cnt+1))
    done
}

#Generate DCF list specific to whitebox
generate_fc_list() {
    /opt/cisco/calvados/bin/show_cmd "terminal length 0; show platform" > $PLATFORM_OUTPUT
    let fc_list_cnt=0
    for loc in $(grep "/FC0 .*OPERATIONAL" $PLATFORM_OUTPUT | awk '{ print $1}'); do
            fc_list[$fc_list_cnt]=$loc
            fc_list_cnt=$((fc_list_cnt+1))
    done
}

#Generate DCC list specific to whitebox
generate_cc_list() {
    /opt/cisco/calvados/bin/show_cmd "terminal length 0; show platform" > $PLATFORM_OUTPUT
    let cc_list_cnt=0
    for loc in $(grep "/CB0 .*OPERATIONAL" $PLATFORM_OUTPUT | awk '{ print $1}'); do
            cc_list[$cc_list_cnt]=$loc
            cc_list_cnt=$((cc_list_cnt+1))
    done
}

ddc_eobc_sfp_dump () {

if [[ "$PLATFORM" == "iosxrwbd" ]]; then
   generate_cc_list
   generate_fc_list
   generate_lc_list

   for lc in "${!lc_list[@]}"; do
       echo "LC : $lc card : ${lc_list[$lc]}"
       lc_offset1="/2/0"
       lc_offset2="/2/1"
       lc_ce_port1="${lc_list[$lc]}$lc_offset1"
       lc_ce_port2="${lc_list[$lc]}$lc_offset2"
       echo "++++++ show controller eobc sfp location ${lc_list[$lc]} $lc_ce_port1 ++++++"
       /opt/cisco/calvados/bin/show_cmd "terminal length 0; show controller eobc sfp location ${lc_list[$lc]} $lc_ce_port1"
       echo "------ show controller eobc sfp location ${lc_list[$lc]} $lc_ce_port1 ------"
       echo "++++++ show controller eobc sfp location ${lc_list[$lc]} $lc_ce_port2 ++++++"
       /opt/cisco/calvados/bin/show_cmd "terminal length 0; show controller eobc sfp location ${lc_list[$lc]} $lc_ce_port2"
       echo "------ show controller eobc sfp location ${lc_list[$lc]} $lc_ce_port2 ------"
   done

   for fc in "${!fc_list[@]}"; do
       fc_offset1="/2/0"
       fc_offset2="/2/1"
       fc_ce_port1="${fc_list[$fc]}$fc_offset1"
       fc_ce_port2="${fc_list[$fc]}$fc_offset2"
       echo "++++++ show controller eobc sfp location ${fc_list[$fc]} $fc_ce_port1 ++++++"
       /opt/cisco/calvados/bin/show_cmd "terminal length 0; show controller eobc sfp location ${fc_list[$fc]} $fc_ce_port1"
       echo "------ show controller eobc sfp location ${fc_list[$fc]} $fc_ce_port1 ------"
       echo "++++++ show controller eobc sfp location ${fc_list[$fc]} $fc_ce_port2 ++++++"
       /opt/cisco/calvados/bin/show_cmd "terminal length 0; show controller eobc sfp location ${fc_list[$fc]} $fc_ce_port2"
       echo "------ show controller eobc sfp location ${fc_list[$fc]} $fc_ce_port2 ------"
   done

   for cc in "${cc_list[@]}"; do
       CC_RACK=$(echo "$cc"| cut -c1-2)
       cc_offset1="/2/0/1"
       cc_offset2="/3/0/1"
       cc_ce_port1="$CC_RACK$cc_offset1"
       cc_ce_port2="$CC_RACK$cc_offset2"
       echo "++++++ show controller eobc sfp location $cc $cc_ce_port1 ++++++"
       /opt/cisco/calvados/bin/show_cmd "terminal length 0; show controller eobc sfp location $cc $cc_ce_port1"
       echo "------ show controller eobc sfp location $cc $cc_ce_port1 ------"
       echo "++++++ show controller eobc sfp location $cc $cc_ce_port2 ++++++"
       /opt/cisco/calvados/bin/show_cmd "terminal length 0; show controller eobc sfp location $cc $cc_ce_port2"
       echo "------ show controller eobc sfp location $cc $cc_ce_port2 ------"
   done

fi

}


# List of commands to be run.  East set must finish with a pair of empty 
# strings.  Note that it is important to use single quotes rather than double 
# quotes for the strings containing your commands.
#
# For all of these the __ksh variable is the process that will actually be 
# spawned, the _exec variable is just a string that is printed in the output to
# describe it. 
#

###############################################################################
# Show commands that run on all RP or LC                                      #
###############################################################################

#
# misc show RPLC
#
all_show_exec[1]='top card_mgr'
all_show__ksh[1]='top -p $(pgrep -d, card_mgr) -b -H -n 1'
all_show_exec[2]='show version'
all_show__ksh[2]='cat /etc/show_version.txt'
all_show_exec[3]='run /usr/bin/show_wb_platform_log'
all_show__ksh[3]='/usr/bin/show_wb_platform_log'


#
# Show commands
#
sys_show_exec[1]='show platform'
sys_show__ksh[1]='/opt/cisco/calvados/bin/show_cmd "terminal length 0; show platform"'

sys_show_exec[2]='show platform detail'
sys_show__ksh[2]='/opt/cisco/calvados/bin/show_cmd "terminal length 0; show platform detail"'

sys_show_exec[3]='show inventory all'
sys_show__ksh[3]='/opt/cisco/calvados/bin/show_cmd "terminal length 0; show inventory all"'

sys_show_exec[4]='show processes card_mgr location all '
sys_show__ksh[4]='/opt/cisco/calvados/bin/show_cmd "terminal length 0; show processes threadname | inc card_mgr"'

sys_show_exec[5]='show controller card-mgr inventory summary'
sys_show__ksh[5]='/opt/cisco/calvados/bin/show_cmd "terminal length 0; show controller card-mgr inventory summary"'

sys_show_exec[6]='show controller card-mgr inventory detail'
sys_show__ksh[6]='/opt/cisco/calvados/bin/show_cmd "terminal length 0; show controller card-mgr inventory detail"'

sys_show_exec[7]='show controller card-mgr notif-history brief location'
sys_show__ksh[7]='/opt/cisco/calvados/bin/show_cmd "terminal length 0; show controller card-mgr notif-history brief location"'

sys_show_exec[8]='show controller card-mgr notif-history detail location'
sys_show__ksh[8]='/opt/cisco/calvados/bin/show_cmd "terminal length 0; show controller card-mgr notif-history detail location"'
 
sys_show_exec[9]='show controller card-mgr oir-history rack 0'
sys_show__ksh[9]='/opt/cisco/calvados/bin/show_cmd "terminal length 0; show controller card-mgr oir-history rack 0"'

sys_show_exec[10]='show controller card-mgr event-history brief location'
sys_show__ksh[10]='/opt/cisco/calvados/bin/show_cmd "terminal length 0; show controller card-mgr event-history brief location"'

sys_show_exec[11]='show controller card-mgr event-history detail location'
sys_show__ksh[11]='/opt/cisco/calvados/bin/show_cmd "terminal length 0; show controller card-mgr event-history detail location"'

sys_show_exec[12]='show controller card-mgr iofpga register cpu location */* group'
sys_show__ksh[12]='/opt/cisco/calvados/bin/show_cmd "terminal length 0; show controller card-mgr iofpga register cpu location */* group"'

sys_show_exec[13]='show controller card-mgr iofpga flash info location'
sys_show__ksh[13]='/opt/cisco/calvados/bin/show_cmd "terminal length 0; show controller card-mgr iofpga flash info location"'

sys_show_exec[14]='show controller card-mgr iofpga flash status location'
sys_show__ksh[14]='/opt/cisco/calvados/bin/show_cmd "terminal length 0; show controller card-mgr iofpga flash status location"'

sys_show_exec[15]='show controller card-mgr bootloader flash info location'
sys_show__ksh[15]='/opt/cisco/calvados/bin/show_cmd "terminal length 0; show controller card-mgr bootloader flash info location"'

sys_show_exec[16]='show controller card-mgr bootloader flash status location'
sys_show__ksh[16]='/opt/cisco/calvados/bin/show_cmd "terminal length 0; show controller card-mgr bootloader flash status location"'

sys_show_exec[17]='show processes wb_card_mgr location all '
sys_show__ksh[17]='/opt/cisco/calvados/bin/show_cmd "terminal length 0; show processes threadname | inc wb_card_mgr"'

sys_show_exec[18]='show chassis'
sys_show__ksh[18]='/opt/cisco/calvados/bin/show_cmd "terminal length 0; show chassis"'

sys_show_exec[19]='show controller onie location '
sys_show__ksh[19]='/opt/cisco/calvados/bin/show_cmd "terminal length 0; show controller onie location"'

sys_show_exec[20]='show controller eobc location '
sys_show__ksh[20]='/opt/cisco/calvados/bin/show_cmd "terminal length 0; show controller eobc location "'

# The display() function is the one that does all the work - called by us as 
# this is a worker script.
#
display() {
    print_main_heading "General card-mgr tech-support info"

    platform_type_get

    if [ "$__cardtype" = "SYS" ]; then
        if [ "$trace_only" = "0" ]; then
                exec_commands sys_show
        fi
        ddc_eobc_sfp_dump
    else
        exec_commands all_show
        exec_commands rplc_trace

        print_main_heading "Gather sysadmin and host os logs"

        # Gather sysadmin logs, etc.
        echo NODENAME $nodename
        echo MEDIA_PATH $media_path
        filepath=$media_path/${nodename}_sysadmin
        mkdir $filepath; RCmkdir=$?
        if [ $RCmkdir -ne 0 ]; then
            echo "Failed to mkdir $filepath, no logs collected" >> $CMDLOG
        else
            #   start of sysadmin /var/log collection 
            ln -s /var/log/messages $filepath/messages
            ln -s /var/log/install $filepath/install
            ln -s /var/log/bootlogs $filepath/bootlogs
            ln -s /var/log/libvirt $filepath/libvirt
            
            # include all /var/log/*.* files
            N=`ls -1d /var/log/*.* 2>/dev/null 1| wc -l`
            if [ $N -ne 0 ]; then
                for name in /var/log/*.*
                do
                    targname=`basename $name`
                    ln -s $name $filepath/$targname
                done
            fi

            # include /var/log/old* files
            N=`ls -1d /var/log/old* 2>/dev/null 1| wc -l`
            if [ $N -ne 0 ]; then
                for name in /var/log/old*
                do
                    targname=`basename $name`
                    ln -s $name $filepath/$targname
                done
            fi
 
            #   end of sysadmin /var/log collection

            # include /tmp/log/log_platform_*.tgz files
            # generated by /usr/bin/show_wb_platform_log
            N=`ls -1d /tmp/log/log_platform_*.tgz 2>/dev/null 1| wc -l`
            if [ $N -ne 0 ]; then
                for name in /tmp/log/log_platform_*.tgz 
                do
                    targname=`basename $name`
                    ln -s $name $filepath/$targname
                done
            fi

            # include /misc/disk1/cpu_error[0,1,2]_intr.log files
            # generated by /usr/bin/show_wb_platform_log
            N=`ls -1d /misc/disk1/cpu_error*.log 2>/dev/null 1| wc -l`
            if [ $N -ne 0 ]; then
                for name in /misc/disk1/cpu_error*.log
                do
                    targname=`basename $name`
                    ln -s $name $filepath/$targname
                done
            fi
        fi

        # Gather hostOS logs

        if [[ "$VIRT_METHOD" == "lxc" ]]; then
            echo "CMD: ssh -o UserKnownHostsFile=/dev/null -o LogLevel=quiet -o StrictHostKeychecking=no $host_ip sh /usr/bin/showtech_host_script.sh -t $__cardtype -f $media_path -n $nodename"
            host_file=`ssh -o UserKnownHostsFile=/dev/null -o LogLevel=quiet -o StrictHostKeychecking=no $host_ip "sh /usr/bin/showtech_host_script.sh -t $__cardtype -f $media_path -n $nodename"`
        else
            echo "CMD: ssh -o UserKnownHostsFile=/dev/null -o LogLevel=quiet -o StrictHostKeychecking=no $host_ip sh /opt/cisco/hostos/script/host_showtech_gatherer.sh -t $__cardtype -f $media_path -n $nodename"
            host_file=`ssh -o UserKnownHostsFile=/dev/null -o LogLevel=quiet -o StrictHostKeychecking=no $host_ip "sh /opt/cisco/hostos/script/host_showtech_gatherer.sh -t $__cardtype -f $media_path -n $nodename"`
        fi
        echo RETURN VALUE $host_file
        if [ -n "$host_file" ]; then
            scp -q -r -o StrictHostKeychecking=no -o LogLevel=quiet $host_ip:$host_file $host_file
        fi
        if [[ "$VIRT_METHOD" == "lxc" ]]; then
            ssh -o UserKnownHostsFile=/dev/null -o LogLevel=quiet -o StrictHostKeychecking=no $host_ip "sh /usr/bin/showtech_host_script.sh -f $media_path -n $nodename -c"
        else
            ssh -o UserKnownHostsFile=/dev/null -o LogLevel=quiet -o StrictHostKeychecking=no $host_ip "sh /opt/cisco/hostos/script/host_showtech_gatherer.sh -t $__cardtype -f $media_path -n $nodename -c"
        fi

        ( cd $media_path
        tar --dereference -czf ${nodename}_sysadmin.tgz ${nodename}_sysadmin 1>/dev/null 2>&1
        rm -rf ${nodename}_sysadmin
        echo $filepath.tgz
        )

        # show tech infra does not copy ${nodename}_host.tgz or
        # ${nodename}_sysadmin.tgz of remote nodes
        # tar both files to ${nodename}.tgz so show tech will copy remote host info
        # from remote nodes
        ( cd $media_path
        if [ -n "${nodename}_host.tgz" ]; then
            tar --dereference -czf ${nodename}.tgz ${nodename}_host.tgz \
                ${nodename}_sysadmin.tgz 1>/dev/null 2>&1
            rm -rf ${nodename}_host.tgz ${nodename}_sysadmin.tgz
        fi
        )

        # This will remove the directory we accumlated into
        # media_path + ${nodename}_sysadmin
        #
        rm -fr $filepath

        print_main_heading "pstack info for card-mgr"
        PROC_NAME=card_mgr;
        PID=`pidof $PROC_NAME`;
        if [ -n "$PID" ]; then
            pstack $PID;
        else
            echo "Cannot find $PROC_NAME process to run pstack";
        fi
    fi
    
    print_main_heading "General card-mgr tech-support info complete"
}

display
