[rancid] Unable to take backup of extreme switch

Chuck Anderson cra at fea.st
Thu Aug 24 21:03:55 UTC 2023


VSP7000 came originally from Nortel/Avaya.  I've never used VSP7000, but I've used Passport 8600 series from which it derives.  I dug into my archives and found pplogin and pprancid which I last used in 2012 or thereabouts.  I'll try attaching them here.  Perhaps they can provide some clues on how to get VSP7000 to work.

On Thu, Aug 24, 2023 at 01:42:58PM +0000, Zakir Hossain wrote:
> Hi,
> I think we are trying wrong login script (fnlogin) for extreme switch but (xlogin) doesn't work because it is for exos and the VSP 7400 switches whereas we're trying to back up of the following model switch:
> VSP Operating System Software Build 8.8.3.0
> Extreme Networks VOSS Command Line Interface
> 
> 
>  MD ZAKIR HOSSAIN | System Integrator & Security Analyst
>  +8801912509937 | zhossain at prival.ca<mailto:zhossain at prival.ca>
>  9955, rue de Châteauneuf, bureau 120, Brossard, Québec, J4Z 3V4
>  Québec 418 907-8356  | Ottawa 613 689-1539 | Toronto 416 645-5626
>  facebook.com/Prival-230867980323343<http://facebook.com/Prival-230867980323343>
>  linkedin.com/company/prival<http://linkedin.com/company/prival>
> From: Ugo Bellavance <ugob at lubik.ca<mailto:ugob at lubik.ca>>
> Sent: Thursday, August 24, 2023 6:50 AM
> To: Zakir Hossain <zhossain at prival.ca<mailto:zhossain at prival.ca>>
> Cc: rancid-discuss at www.shrubbery.net<mailto:rancid-discuss at www.shrubbery.net>; Randall Watt <RWatt at prival.ca<mailto:RWatt at prival.ca>>
> Subject: Re: [rancid] Unable to take backup of extreme switch
> 
> You don't often get email from ugob at lubik.ca<mailto:ugob at lubik.ca>. Learn why this is important<https://aka.ms/LearnAboutSenderIdentification>
> Did you try executing the corresponding login script (clogin for cisco devices, I don't know exactly for extreme)
> 
> On Tue, Aug 22, 2023 at 12:49 PM Zakir Hossain <zhossain at prival.ca<mailto:zhossain at prival.ca>> wrote:
> Hi,
> 
> While I am trying to take backup of extreme switch then I am facing below error message in debug mode:
> 
> 
> expect does "\r\n\r\rnEBER-SW-SIC4-VSP7400-ip-addess:1>" (spawn_id exp3) match glob pattern "[#\$] "? no
> expect: timed out
> 
>  Error: TIMEOUT reached
> 
> But we can login using rancid to the switch without any issue. So, would anyone please help me to resolve this issue?
-------------- next part --------------
#!/usr/bin/expect -f
#

set send_slow {1 .1}
proc send {ignore arg} {
    sleep .1
    exp_send -s -- $arg
}

set timeout -1
set prompt ":(3|5|6)(#|>) "
set password_file $env(HOME)/.cloginrc
set command [lindex $argv 0]

# Loads the password file.  Note that as this file is tcl, and that
# it is sourced, the user better know what to put in there, as it
# could install more than just password info...  I will assume however,
# that a "bad guy" could just as easy put such code in the clogin
# script, so I will leave .cloginrc as just an extention of that script
proc source_password_file { password_file } {
    global env
    if { ! [file exists $password_file] } {
	send_user "\nError: password file ($password_file) does not exist\n"
	exit 1
    }
    file stat $password_file fileinfo
    if { [expr ($fileinfo(mode) & 007)] != 0000 } {
	send_user "\nError: $password_file must not be world readable/writable\n"
	exit 1
    }
    if [ catch {source $password_file} reason ] {
	send_user "\nError: $reason\n"
	exit 1
    }
}
proc add {var args} { global int_$var ; lappend int_$var $args}
proc find {var router} {
    upvar int_$var list 
    if { [info exists list] } {
	foreach line $list {
	    if { [string match [lindex $line 0] $router ] } {
		return [lrange $line 1 end]
	    }     
	}       
    }     
    return {} 
}        
source_password_file $password_file

foreach router [lrange $argv 1 end] {
    set router [string tolower $router]
    set user [join [find user $router] ""]
    set cyphertype [find cyphertype $router]
    if { "$cyphertype" == "" } { set cyphertype "3des" }

    send_user "$router\n"

    set pswd [find password $router]
    if { [llength $pswd] == 0 } {
	send_user "\nError - no password for $router in $password_file.\n"
	continue
    }
    set passwd [join [lindex $pswd 0] ""]

    # Login
    spawn ssh -c $cyphertype -x -l $user $router

    expect {
	-re "(Connection refused|Secure connection \[^\n\r]+ refused|Connection closed by)" {
	    catch {close}; wait
		send_user "\nError: Connection Refused\n"; return 1
	} 
	eof {
	    send_user "\nError: Couldn't login\n"; wait; return 1
	}
	-nocase "unknown host\r" {
	    catch {close};
	    send_user "\nError: Unknown host\n"; wait; return 1
	}
	"Host is unreachable" {
	    catch {close};
	    send_user "\nError: Host Unreachable!\n"; wait; return 1
	}
	"No address associated with name" {
	    catch {close};
	    send_user "\nError: Unknown host\n"; wait; return 1
	}
	-re "(Host key not found |The authenticity of host .* be established).*\(yes\/no\)\?" {
	    send -- "yes\r"
	    send_user "\nHost $router added to the list of known hosts.\n"
	    exp_continue 
	}
	-re "HOST IDENTIFICATION HAS CHANGED.* \(yes\/no\)\?"   {
	    send -- "no\r"
	    send_user "\nError: The host key for $router has changed.  Update the SSH known_hosts file accordingly.\n"
	    return 1 
	}
	-re "Offending key for .* \(yes\/no\)\?"   {
	    send -- "no\r"
	    send_user "\nError: host key mismatch for $router.  Update the SSH known_hosts file accordingly.\n"
	    return 1 
	}
	" password: "	{
	    send -- "$passwd\r"
	}
	exp_continue
    }
    
    expect -re $prompt
    send -- "conf cli more false\r"
    expect -re $prompt

    if [ string match "*\;*" "$command" ] {
	set commands [split $command \;]
	set num_commands [llength $commands]
	for {set i 0} {$i < $num_commands} { incr i} {
	    send -- "[lindex $commands $i]\r"
	    expect -re $prompt
	}
    } else {
	send -- "$command\r"
	expect -re $prompt
    }

    # Logout
    send -- "logout\r"
    expect eof
}
-------------- next part --------------
#! /usr/bin/perl
##
## Rehacked brancid to deal with passport 8600
##
## Copyright (C) 1997-2004 by Terrapin Communications, Inc.
## All rights reserved.
##
## This software may be freely copied, modified and redistributed
## without fee for non-commerical purposes provided that this license
## remains intact and unmodified with any RANCID distribution.
##
## There is no warranty or other guarantee of fitness of this software.
## It is provided solely "as is".  The author(s) disclaim(s) all
## responsibility and liability with respect to this software's usage
## or its effect upon hardware, computer systems, other software, or
## anything else.
##
## Except where noted otherwise, rancid was written by and is maintained by
## Henry Kilmer, John Heasley, Andrew Partan, Pete Whiting, and Austin Schutz.
##
#
#  RANCID - Really Awesome New Cisco confIg Differ
#
# usage: rancid [-d] [-l] [-f filename | $host]
#
use Getopt::Std;
getopts('dfl');
$log = $opt_l;
$debug = $opt_d;
$file = $opt_f;
$host = $ARGV[0];
$clean_run = 0;
$found_end = 0;
$timeo = 90;			# blogin timeout in seconds

$debug = 0;

my(%filter_pwds);		# password filtering mode

# This routine is used to print out the router configuration
sub ProcessHistory {
    my($new_hist_tag,$new_command,$command_string, at string)=(@_);
    if((($new_hist_tag ne $hist_tag) || ($new_command ne $command))
       && defined %history) {
	print eval "$command \%history";
	undef %history;
    }
    if (($new_hist_tag) && ($new_command) && ($command_string)) {
	if ($history{$command_string}) {
	    $history{$command_string} = "$history{$command_string}@string";
	} else {
	    $history{$command_string} = "@string";
	}
    } elsif (($new_hist_tag) && ($new_command)) {
	$history{++$#history} = "@string";
    } else {
	print "@string";
    }
    $hist_tag = $new_hist_tag;
    $command = $new_command;
    1;
}

sub numerically { $a <=> $b; }

# This is a sort routing that will sort numerically on the
# keys of a hash as if it were a normal array.
sub keynsort {
    local(%lines)=@_;
    local($i) = 0;
    local(@sorted_lines);
    foreach $key (sort numerically keys(%lines)) {
	$sorted_lines[$i] = $lines{$key};
	$i++;
    }
    @sorted_lines;
}

# This is a sort routing that will sort on the
# keys of a hash as if it were a normal array.
sub keysort {
    local(%lines)=@_;
    local($i) = 0;
    local(@sorted_lines);
    foreach $key (sort keys(%lines)) {
	$sorted_lines[$i] = $lines{$key};
	$i++;
    }
    @sorted_lines;
}

# This is a sort routing that will sort on the
# values of a hash as if it were a normal array.
sub valsort{
    local(%lines)=@_;
    local($i) = 0;
    local(@sorted_lines);
    foreach $key (sort values %lines) {
	$sorted_lines[$i] = $key;
	$i++;
    }
    @sorted_lines;
}

# This is a numerical sort routing (ascending).
sub numsort {
    local(%lines)=@_;
    local($i) = 0;
    local(@sorted_lines);
    foreach $num (sort {$a <=> $b} keys %lines) {
	$sorted_lines[$i] = $lines{$num};
	$i++;
    }
    @sorted_lines;
}

# This is a sort routine that will sort on the
# ip address when the ip address is anywhere in
# the strings.
sub ipsort {
    local(%lines)=@_;
    local($i) = 0;
    local(@sorted_lines);
    foreach $addr (sort sortbyipaddr keys %lines) {
	$sorted_lines[$i] = $lines{$addr};
	$i++;
    }
    @sorted_lines;
}

# These two routines will sort based upon IP addresses
sub ipaddrval {
    my(@a) = ($_[0] =~ m#^(\d+)\.(\d+)\.(\d+)\.(\d+)$#);
    $a[3]+256*($a[2]+256*($a[1]+256*$a[0]));
}
sub sortbyipaddr {
    &ipaddrval($a) <=> &ipaddrval($b);
}

# This routine parses "show config"
sub ShowConfig {
    print STDERR "    In ShowConfig: $_" if ($debug);
    my $gotdata = 0;

    # strip out the first three lines to avoid the date/timestamp
    my $dummy = <INPUT>;
    my $dummy = <INPUT>;
    my $dummy = <INPUT>;

    while (<INPUT>) {
	tr/\015//d;
	$gotdata = 1 if $_ ne '';
	# print STDERR "Grokking $_" if ($debug);
#	last if (/^$prompt/);
#	next if (/^(\s*|\s*$cmd\s*)$/);
#	next if (/^Reading configuration information/);
#	next if (/^Can\'t find object or class named \"\-all\"\s*$/);
#	next if (/lock-address .*$/);
#	next if (/^\# *uptime +\d+\s*$/);
#	next if (/^Preparing to Display Configuration/);
#	if (/community label /) {
#	    if (defined($ENV{'NOCOMMSTR'})) {
#		$_ =~ s/community label .*$/community label <removed>/;
#	    }
#	}
	return(-1) if /(invalid command name)/;
	ProcessHistory("","","","$_");
	if (/^back/) {
	    print STDERR "Found back statement, finishing showconfig\n" if ($debug);
	    $found_end = 1;
	    return(0);
	}
    }
    # We should never get here
    return(-1);
}

# This routine parses "show sys info"
sub ShowSysInfo {
    print STDERR "    In ShowSysInfo: $_" if $debug;
    print STDERR "    prompt is \"$prompt\"\n" if $debug;

    while(<INPUT>){
	tr/\015//d;
	next if /SysUpTime/;
	next if (/Fan#\d: /);
	next if (/Temperature : \d/);
	next if (/Total Power (Available|Usage)/);

	if(/$prompt/){
	    print STDERR "Found prompt, finishing showsysinfo\n" if $debug;
	    return(0);
	}
	ProcessHistory("","","","# $_");
    }
    return(-1);
}

# This routine parses "show sys perf"
sub ShowSysPerf {
    print STDERR "    In ShowSysPerf: $_" if $debug;
    print STDERR "    prompt is \"$prompt\"\n" if $debug;

    while(<INPUT>){
	tr/\015//d;
	next if (/CpuUtil:/);
	next if (/SwitchFabricUtil:/);
	next if (/OtherSwitchFabricUtil:/);
	next if (/BufferUtil:/);
	next if (/DramUsed:/);
	next if (/DramFree:/);

	if(/$prompt/){
	    print STDERR "Found prompt, finishing showsysperf\n" if $debug;
	    return(0);
	}
	ProcessHistory("","","","# $_");
    }
    return(-1);
}

# This routine parses single command's that return no required info
sub RunCommand {
    print STDERR "    In RunCommand: $_" if ($debug);

    while (<INPUT>) {
	tr/\015//d;
	last if (/^$prompt/);
	next if (/^(\s*|\s*$cmd\s*)$/);
	# prompt may have changed
#	if (/\>/) {
#	    $prompt = ($_ =~ /^([^>]+>)/)[0];
#	    $prompt =~ s/([][])/\\$1/g;
#	    last;
#	}
    }
    return(0)
}

# dummy function
sub DoNothing {print STDOUT;}

sub FireForgetCommand {
    print STDERR "    In FireForgetCommand: $_" if ($debug);

    return(0);
}

# Main
%commands=(
	'show config'		=> "ShowConfig",
	'show sys info'		=> "ShowSysInfo",
	'show sys info card'    => "ShowSysInfo",
	'show sys perf'		=> "ShowSysPerf",
);
# keys() doesnt return things in the order entered and the order of the
# cmds is important (show version first and write term last). pita
@commands=(
	   "show sys info",
	   "show sys info card",
	   "show sys perf",
	   "show config",
);
$cisco_cmds=join(";", at commands);
$cmds_regexp=join("|", at commands);

open(OUTPUT,">$host.new") || die "Can't open $host.new for writing: $!\n";
select(OUTPUT);
# make OUTPUT unbuffered if debugging
if ($debug) { $| = 1; }

if ($file) {
    print STDERR "opening file $host\n" if ($debug);
    print STDOUT "opening file $host\n" if ($log);
    open(INPUT,"<$host") || die "open failed for $host: $!\n";
} else {
    print STDERR "executing pplogin \"$cisco_cmds\" $host\n" if ($debug);
    print STDOUT "executing pplogin \"$cisco_cmds\" $host\n" if ($log);
    if (defined($ENV{NOPIPE})) {
	system "pplogin  \"$cisco_cmds\" $host </dev/null > $host.raw 2>&1" || die "pplogin failed for $host: $!\n";
	open(INPUT, "< $host.raw") || die "pplogin failed for $host: $!\n";
    } else {
	open(INPUT,"pplogin  \"$cisco_cmds\" $host </dev/null |") || die "pplogin failed for $host: $!\n";
    }
}

# determine password filtering mode
if ($ENV{"FILTER_PWDS"} =~ /no/i) {
	$filter_pwds = 0;  
} elsif ($ENV{"FILTER_PWDS"} =~ /all/i) {
	$filter_pwds = 2;
} else {
	$filter_pwds = 1;
}

ProcessHistory("","","","# RANCID-CONTENT-TYPE: passport\n#\n");
TOP: while(<INPUT>) {
    tr/\015//d;
    if ( (/(>|#)\s?logout/) || $found_end ) {
	print STDERR "Found logout statement, ending\n" if ($debug);
	delete($commands{'logout'});
	$clean_run=1;
	last;
    }
    if (/^Error:/) {
	print STDOUT ("$host pplogin error: $_");
	print STDERR ("$host pplogin error: $_") if ($debug);
	$clean_run=0;
	last;
    }
    while (/(>|#)\s*($cmds_regexp)\s*$/) {
	$cmd = $2;
	print STDERR "Doing $cmd\n";
	if (!defined($prompt)) {
	    $prompt = ":(5|6)(#|>)";
	    print STDERR ("PROMPT MATCH: $prompt\n") if ($debug);
	}
	print STDERR ("HIT COMMAND:$_") if ($debug);
	if (! defined($commands{$cmd})) {
	    print STDERR "$host: found unexpected command - \"$cmd\"\n";
	    $clean_run = 0;
	    last TOP;
	}
	print STDERR "Calling \"$cmd\"\n" if ($debug);
	$rval = &{$commands{$cmd}};
	delete($commands{$cmd});
	if ($rval == -1) {
	    $clean_run = 0;
	    last TOP;
	}
    }
}
print STDOUT "Done $logincmd: $_\n" if ($log);
# Flush History
ProcessHistory("","","","");
# Cleanup
close(INPUT);
close(OUTPUT);

if (defined($ENV{NOPIPE})) {
    unlink("$host.raw") if (! $debug);
}

# check for completeness
if (scalar(%commands) || !$clean_run || !$found_end) {
    if (scalar(%commands)) {
	printf(STDOUT "$host: missed cmd(s): %s\n", join(',', keys(%commands)));
	printf(STDERR "$host: missed cmd(s): %s\n", join(',', keys(%commands))) if ($debug);
    }
    if (!$clean_run || !$found_end) {
	print STDOUT "$host: End of run not found\n";
	print STDERR "$host: End of run not found\n" if ($debug);
	system("/usr/bin/tail -1 $host.new");
    }
    unlink("$host.new") if (! $debug);
}


More information about the Rancid-discuss mailing list