#!/pkg/bin/ksh
# -----------------------------------------------------------------------------
# show_tech_fast_ether - Show tech-support fast script for ethernet
#
# October 2008, Simon Osborne
#
# Copyright (c) 2008-2012, 2014-2018 by cisco Systems, Inc.
# All rights reserved.
#------------------------------------------------------------------------------

#
# OVERVIEW OF ETHERNET SHOW TECH FAST
#
# 'show_tech_fast' script is executed by parser, being passed whatever script
# we want to run as an argument - in this case 'show_tech_fast_ether'.  The 
# end result is that the 'show_tech_fast_ether' script will be run on each and 
# every node in parallel - with arguments being setup to show which card type 
# it is being run on.
#
# The 'show_tech_fast_ether' script will then call the _common and _only 
# scripts on all cards, and the sub-script will take whatever action it needs 
# to based on card type.
#
# Regarding card type, "SYS" corresponds to the commands that should be run 
# once per-system (as this is run within LR, on the dLRSC), and "RP", "LC", 
# etc. correspond to any card of that type in the chassis.  We'll get both SYS
# and RP callbacks on the dLRSC. 
#
# - 'show_tech_fast_ether' is the main script for running parallel (aka. 
# fast) show tech ether.  This will only be run directly by show tech infra.
#
# - 'show_tech_fast_ether_common' is the script that will be called by both 
# 'show_tech_fast_ether' and any other subsystem that needs it (e.g. the fast 
# bundle show tech command)
#
# - 'show_tech_fast_ether_only' is the script that will be called only by 
# 'show_tech_fast_ether'
#
# As CFM and L2VPN have not yet migrated to the new infra, temporary 
# translations of their show tech functions are included in the ethernet 
# component.  These will be superceded by the proper versions, when these 
# arrive.
#

#
# Load the script provided by show-tech infra, which provides worker functions
#
. /pkg/bin/show_tech_main_fragment

#
# Parse the arguments to the script - in particular, to work out what node type
# we are running on and any interface filter.
#
# The args passed to this script seem to get easily mixed in with the show tech
# arguments, so make no assumption about ordering of arguments here - and pass
# anything unhandled over to showtech infra.
#
__cardtype="unspecified"
internal_if="unspecified"
external_if=""
arg_string=""
showtech_argv=""
showtech_argc="0"

while [ "$#" -gt "0" ]; do
    case "$1" in
        # Have ?? here to remove first two characters of variable
        -I*) internal_if="${1#??}"; shift 1;;
        -t) __cardtype="$2"; shift 2;;
        *) showtech_argv="$showtech_argv $1"; (( showtech_argc+=1 )); shift 1;;
    esac
done

#
# Call the showtech infra default parser - using set to recreate the $#, $@, 
# etc. - "--" is necessary so set doesn't try to interpret any of the 
# arguments we are passing through!
#
if [[ $showtech_argc -ne 0 ]]; then
    set -- $showtech_argv
    default_parser_function $@
fi

if [ "$internal_if" != "unspecified" ]; then
    external_if=`convert_interface_fmt '-e' $internal_if`
    arg_string="$arg_string -I $internal_if"
fi

if [ "$__filename" = "unspecified" ]; then
    echo "$0: output file not specified"
    exit
fi

if [ "$__cardtype" == "unspecified" ]; then
    __cardtype=`node_type`
fi

arg_string="$arg_string -t $__cardtype"

#
# 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. 
#
# [Would be far preferable for the __ksh variables to be generated from the 
# _exec variables to keep everything in step, but no support for that]
#

###############################################################################
# Show commands that run once per LR                                          #
###############################################################################
sys_exec[1]='show running-config'
sys__ksh[1]='nvgen -c -l 1 -t 1 -o 1'

# RP only, so use "location all"
sys_exec[2]='show redundancy location all'
sys__ksh[2]='redcon_show -n all'

sys_exec[3]='show logging'
sys__ksh[3]='show_logging'

sys_exec[4]='show interface summary'
sys__ksh[4]='show_interface -a -o 0x3'

# assumes "platform" is set for us by show_tech_main_fragment
if [ "$platform" = "panini" ]
then
    sys_exec[5]='show install active'
    sys__ksh[5]='sdr_instcmd show install active'
else
    sys_exec[5]='show install active summary'
    sys__ksh[5]='instcmd show install active summary'
fi

if [ "$platform" = "panini" ]
then
    sys_exec[6]='show install package all detail'
    sys__ksh[6]='sdr_instcmd show install package all detail'
else
    sys_exec[6]='show install package all detail'
    sys__ksh[6]='instcmd show install package all detail'
fi
  
sys_exec[7]='show configuration history'
sys__ksh[7]='cfgmgr_show_history -s -f -n 0x5dc -t all -b'

sys_exec[8]=''
sys__ksh[8]=''

###############################################################################
# Interface specific show commands that run once per LR                       #
# (ie. global commands or those only runnable on RP)                          #
###############################################################################

sys_intf_exec[1]='show interfaces $external_if'
sys_intf__ksh[1]='show_interface -i $internal_if'

sys_intf_exec[2]='show adjacency $external_if location all'
sys_intf__ksh[2]='aib_show_command -I $internal_if -A'

sys_intf_exec[3]=''
sys_intf__ksh[3]=''

###############################################################################
# Interface specific show commands that run from the RP, for all locations    #
###############################################################################

rp_intf_loc_exec[1]=''
rp_intf_loc__ksh[1]=''

###############################################################################
# Show commands that run on every RP                                          #
###############################################################################
rp_exec[1]='show controllers stats'
rp__ksh[1]='ethernet_show_controller -A -s stats'

rp_exec[2]=''
rp__ksh[2]=''

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

# assumes "platform" is set for us by show_tech_main_fragment
if [ "$platform" = "panini" ]
then
    rplc_exec[1]='show process blocked'
    rplc__ksh[1]='sh_proc_ng_blocked'
else
    rplc_exec[1]='show process blocked'
    rplc__ksh[1]='show_processes -b'
fi

# specify context 11 to display dumper context for last 10 crashes (not in CLI)
if [ "$platform" = "panini" ]
then
    rplc_exec[2]='show context'
    rplc__ksh[2]='corehelper_context -c 0xb'
else
    rplc_exec[2]='show context'
    rplc__ksh[2]='dumper_context -c 0xb'
fi

#
# Show Controllers Commands
#
rplc_exec[3]='show controllers oper'
rplc__ksh[3]='ethernet_show_controller -T -A -s oper'

rplc_exec[4]='show controllers bert'
rplc__ksh[4]='ethernet_show_controller -T -A -s bert'

rplc_exec[5]='show controllers control'
rplc__ksh[5]='ethernet_show_controller -T -A -s control'

rplc_exec[6]='show controllers mac'
rplc__ksh[6]='ethernet_show_controller -T -A -s mac'

rplc_exec[7]='show controllers internal'
rplc__ksh[7]='ethernet_show_controller -T -A -s internal'

rplc_exec[8]='show controllers phy'
rplc__ksh[8]='ethernet_show_controller -T -A -s phy'

rplc_exec[9]='show controllers xgxs'
rplc__ksh[9]='ethernet_show_controller -T -A -s xgxs'

rplc_exec[10]='show controllers regs'
rplc__ksh[10]='ethernet_show_controller -T -A -s regs'

rplc_exec[11]=''
rplc__ksh[11]=''

###############################################################################
# Interface specific show commands that run on all RP or LC                   #
###############################################################################
rplc_intf_exec[1]='show netio chains $external_if'
rplc_intf__ksh[1]='netio_show -C -N $internal_if'

rplc_intf_exec[2]=''
rplc_intf__ksh[2]=''

###############################################################################
# Run this after all other commands, to leave a time stamp after the last     #
# command we run - makes analysis easier!                                     #
###############################################################################
final_exec[1]='Last show tech ethernet command'
final__ksh[1]='echo Last show tech ethernet command'

final_exec[2]=''
final__ksh[2]=''

#
# The display() function is the one called by the show-tech infra to actually
# do the work of running the commands (it is run by show_tech_file_fragment, 
# called below).
#
# NOTE: our "sys" commands ideally want to be run once per LR.  But seems there
# is currently no way to detect this, so for now we duplicate the SYS handling
# on all RP cards - this means for each RP type node in an LR we'll duplicate 
# the information (not ideal, but better than losing data).
#
display() {
    print_main_heading "show tech-support ethernet"

    if [ "$__cardtype" == "SYS" ]; then
        exec_commands sys

        if [ "$internal_if" != "unspecified" ]; then
            exec_commands sys_intf
        fi
        
        #
        # Script to get all config events from cfgmgr history, and for each 
        # event show the details.
        #
        . /pkg/bin/show_tech_config_history
    else
        case "$__cardtype" in
        "RP")
            exec_commands rplc
            exec_commands rp
            
            if [ "$internal_if" != "unspecified" ]; then
                exec_commands rplc_intf
                exec_commands_rack_nodes rp_intf_loc
            fi
            ;;
        "LC")
            exec_commands rplc

            if [ "$internal_if" != "unspecified" ]; then
                exec_commands rplc_intf
            fi
            ;;
        esac
    fi
    
    #
    # Run the fast-compatible modules on all nodes, they can decide whether any
    # action is needed or not based on card type and interface filter.
    #
    run_module show_tech_fast_ether_common "$arg_string"
    
    #
    # Run the modules that aren't updated to fast support - run these 
    # on all card types - and these will only do anything on SYS call for now..
    #
    # These can be removed once the relevant teams provide scripts that we can
    # use.
    #
    if [[ -x `which show_tech_fast_ether_pd 2>/dev/null` ]]; then 
        run_module show_tech_fast_ether_pd "$arg_string" 
    else
        run_module show_tech_fast_ether_pd_ethernet "$arg_string" 
    fi 

    if [[ -x `which erp_show_tech 2>/dev/null` ]]; then 
        run_module erp_show_tech "$arg_string"
    fi

    if [[ -x `which show_tech_eth_intf 2>/dev/null` ]]; then
        run_module show_tech_eth_intf "$arg_string"
    fi

    exec_commands final

    #
    # Collect showtechs from neighbouring components
    #
    # @@@ Disable "show tech pfi" until CSCvf52492 is fixed.
    enable_techs "" /pkg/bin/show_tech_fast_ether_proto show_tech_fast_bundles
    set_max_depth 1
    
    print_main_heading "show tech-support ethernet complete"
}

#
# This function calls the display() function and sends the output to file if
# the file option has been set. 
#
. /pkg/bin/show_tech_file_fragment

