%commands vs. @commands
Ed Ravin
eravin at panix.com
Wed Jun 8 15:23:20 UTC 2005
On Wed, Jun 08, 2005 at 06:37:51AM +0100, Jee Kay wrote:
> On a side note, what is the difference between the %commands and
> @commands list in rancid? Which one does it actually use?
Both are used. The %commands hash is an association between commands run
on the device and the subroutine used to process the output of that command:
# Main
%commands=(
'admin show version' => "ShowVersion",
'show version' => "ShowVersion",
'show redundancy secondary' => "ShowRedundancy",
[...]
But RANCID also needs to send the commands to the device in a certain
order. Unfortunately, there's no concept of order in a hash, you can ask
for a list of every item in the hash with the keys() function, but it
doesn't promise to you that it will return them in any particular order.
Hence the comment below that precedes the declaration of @commands:
# 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=(
"admin show version",
"show version",
"show redundancy secondary",
[...]
This redundant construction has been grating on me when working on RANCID
code, so I've spent a few minutes thinking about how to fix it. One way
to fix this would be to use an array of anonymous hashes. Since it starts
out as an array, you keep the order of the list, and the individual entries
give you the association between command name and subroutine name:
@commandtable= (
{'admin show version' => "ShowVersion"},
{'show version' => "ShowVersion"},
{'show redundancy secondary' => "ShowRedundancy"},
[...]
);
And then, to keep code changes to a minimum, build @commands and %commands
automatically from @commandtable. Here we don't care about the order of
things returned by keys() or values(), because each has has only one entry:
my $i= 0;
foreach my $cmdref (@commandtable)
{
my @tmp= keys(%{$cmdref});
@commands[$i]= $tmp[0];
@tmp= values(%{$cmdref});
$commands{$commands[$i]}= $tmp[0];
$i++;
};
And the rest of the RANCID code remains unchanged, since @commands and
%commands now exist just as they did before.
Any thoughts from the RANCID maintainers about this? I'll be happy to
test this out and submit patches. The fragments above work as expected
when I tested them in isolation.
> I'd like to
> prune out all the commands I know my switches/routers don't support
> (or in the case of write term, will always support). Do I need to
> add/remove any new commands to both lists?
Yes, you would need to edit both lists. Or use the code above so that
there's only one list.
On the larger issue of pruning out commands, note my previous (unanswered)
query to the list about running both "show running-config" and "write term".
RANCID's philosophy seems to be "send all commands, let RANCID sort 'em out
afterwards". This makes sense because the xxxrancid programs don't talk
directly to the router, the xxxlogin program does that and produces an
output file that is presented to xxxrancid for parsing. RANCID happily
ignores commands that aren't supported on the device. And if one day you
upgrade IOS and one of those commands is supported, then all the better,
you get more data in your repository. In almost all cases, there's barely
any penalty for sending the unrecognized commands, so why bother pruning
them? My query about "show running-config" / "write term" was due to
a router here that takes 30-45 seconds to dump its config - which to my
mind was a penalty worth trying to program around. Or maybe not -
remember, RANCID connects to multiple devices in parallel, so unless there
are dozens of devices at your site that are slow to dump their config,
the RANCID won't take that much longer to finish.
I'm a firm believer in letting the computer do extra work so that the
programmer doesn't have to. Unless there's really a lot of damage caused
by the extra commands, I'd rather leave them in that figure out how to
code them out.
-- Ed
More information about the Rancid-discuss
mailing list