[rancid] Re: Problem with rancid-script

Lars Lystrup Christensen llc at dansketelecom.com
Fri Sep 15 19:35:21 UTC 2006


> -----Original Message-----
> From: john heasley [mailto:heas at shrubbery.net]
> Sent: 15. september 2006 20:29
> To: Lars Lystrup Christensen
> Cc: john heasley; rancid-discuss at shrubbery.net
> Subject: Re: [rancid] Problem with rancid-script
> 
> Fri, Sep 15, 2006 at 07:50:26AM +0200, Lars Lystrup Christensen:
> > > Thu, Sep 14, 2006 at 09:14:02PM +0200, Lars Lystrup Christensen:
> > > > I have a problem with a rancid parsing script I've created. The
> > script
> > > is for the Motorola Expedience system.
> > >
> > > what is that?
> > >
> > Motorola Expedience system, formerly known as Nextnet Wireless
> > Expedience system, is a WiMAX like system for wireless access.
> 
> UI similar to the BSR?

BSR? I'm not quite sure what you mean...

> 
> > > > The problem is that it seems that rancid is not collecting my
> > configs.
> > > When I run the script manually (./expedrancid -d hostIP) I get an
> > output
> > > in the form of hostIP.new, but when I run the script from within
> > rancid, I
> > > don't get any output at all.
> > > >
> > > > Anyone got any ideas on what to look for?
> > >
> > > Errors :)  specicially look at the log file in logs/ for the group
the
> > > device
> > > is a member of.
> >
> > Actually when I look into the log files the only thing I find beside
> > successful collections is:
> >
> >
> > Trying to get all of the configs.
> > =====================================
> > Getting missed routers: round 1.
> > =====================================
> > Getting missed routers: round 2.
> > =====================================
> > Getting missed routers: round 3.
> > =====================================
> > Getting missed routers: round 4.
> 
> In what case(s) would your script remove the .new file?

I don't know...

I'll include the rancid-script below.

------------- script -----------------

#! /usr/bin/perl
##
## $Id: prancid.in,v 1.29 2004/01/11 03:49:13 heas Exp $
##
## 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.
##
#
# This version of rancid tries to deal with Motorola Expedience System.
# Done by Lars L. Christensen
#
#  RANCID - Really Awesome New Cisco confIg Differ
#
# usage: expedrancid [-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;                    # clogin timeout in seconds

my($platform);                  # platform/cpu type
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 version"
sub ShowDevice {
    print STDERR "    In ShowDevice: $_" if ($debug);

    while (<INPUT>) {
        tr/\015//d;
        last if(/^$prompt/);
        next if(/^(\s*|\s*$cmd\s*)$/);
        return(-1) if (/command authorization failed/i);

        /^device ethernet address \=>(\s+.*)$/ &&
ProcessHistory("COMMENTS","keysort","C1","\#\n# Ethernet Address: $1\n")
&& next;
        /^device nextnet address \=>(\s+.*)$/ &&
ProcessHistory("COMMENTS","keysort","C2","\# Airlink Address:  $1\n") &&
next;
        /^device unit number \=>(\s+.*)$/ &&
ProcessHistory("COMMENTS","keysort","C3","\# Unit number:
$1\n\#\n") && next;
    }
    return(0);
}

# This routine parses "show version"
sub ShowVersion {
    print STDERR "    In ShowVersion: $_" if ($debug);

    while (<INPUT>) {
        tr/\015//d;
        last if(/^$prompt/);
        next if(/^(\s*|\s*$cmd\s*)$/);
        return(-1) if (/command authorization failed/i);

        /^ / && next;
        ProcessHistory("COMMENTS","keysort","B1", "# $_") && next;

    }
    return(0);
}

# This routine processes a "show -fn"
sub ShowFN {
    print STDERR "    In ShowFN: $_" if ($debug);

    while (<INPUT>) {
        tr/\015//d;
        last if(/^$prompt/);
        return(-1) if (/command authorization failed/i);

        # filter out any RCS/CVS tags to avoid confusing local CVS
storage
        s/\$(Revision|Id):/ $1:/;

        /^$/ && next;
        # catch anything that wasnt matched above.
        ProcessHistory("","","","$_");
        # end of config.
    }
    $found_end = 1;
    return(1);
}

# dummy function
sub DoNothing {print STDOUT;}

# Main
%commands=(
        'show version'          => "ShowVersion",
        'show device'           => "ShowDevice",
        'show -fn'              => "ShowFN"
);
# 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 version",
        "show device",
        "show -fn"
);
$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 clogin -t $timeo -c \"$cisco_cmds\" $host\n"
if ($debug);
    print STDOUT "executing clogin -t $timeo -c \"$cisco_cmds\" $host\n"
if ($log);
    if (defined($ENV{NOPIPE})) {
        system "clogin -t $timeo -c \"$cisco_cmds\" $host </dev/null >
$host.raw 2>&1" || die "clogin failed for $host: $!\n";
        open(INPUT, "< $host.raw") || die "clogin failed for $host:
$!\n";
    } else {
        open(INPUT,"clogin -t $timeo -c \"$cisco_cmds\" $host </dev/null
|") || die "clogin 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:
motorolaexpedience\n\#\n");
#ProcessHistory("COMMENTS","keysort","B0","\#\n");
# show version
ProcessHistory("COMMENTS","keysort","H0","\#\n\# Actual
configuration\n\#\n");

TOP: while(<INPUT>) {
    tr/\015//d;
    if ($prompt) {
        $clean_run=1;
        last;
    }

    if (/^Error:/) {
        print STDOUT ("$host clogin error: $_");
        print STDERR ("$host clogin error: $_") if ($debug);
        $clean_run=0;
        last;
    }

    while (/[>#]\s*($cmds_regexp)\s*$/) {
        $cmd = $1;
        if (!defined($prompt)) {
            $prompt = ($_ =~ /^([^>]+>)/)[0];
            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;
        }
        $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) {

    $clean_run = 1;
    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);
}

-------------- end script ------------------

A sample of the output from the Motorola Expedience equipment would
eventually look like the following:

-------------- start output ----------------

#RANCID-CONTENT-TYPE: motorolaexpedience
#
# version Version 4.3.28 Expedience AMOD Base Station 
# ATI Aggregation Library Version 1.1.24
# ASIC: Ver 42, Rev B 
#
# Ethernet Address:  00:03:D7:F0:0A:B3 
# Airlink Address:  00:F0:0A:B3 
# Unit number:  15731379 
#
#
# Actual configuration
#
aaa authority = remote
aaa port = 12541
(bunch of more lines like the above one)

------------- end output ------------------- 

Hope somebody might get an idea...

BR Lars



More information about the Rancid-discuss mailing list