[c-nsp] Monitoring Nexus 7000 platform
Lincoln Dale
ltd at cisco.com
Sun Aug 16 05:41:43 EDT 2009
On 15/08/2009, at 7:37 AM, Lee wrote:
> On 8/14/09, Lincoln Dale <ltd at cisco.com> wrote:
>
> .. snip lots of really cool examples ..
>
>> why one would ever touch SNMP willingly after using the above is
>> beyond me. :)
>
> Is there an XML equivalent to the Net-SNMP package?
i'm not aware of any standard perl modules for NetConf, however we
(Cisco) and other vendors have sample scripts available which
demonstrate how to make use of Netconf with the CPAN Expect and
XML::DOM.
most sample scripts turn out to be <50 lines of code, e.g.
#!/usr/bin/perl
# netconf/xml sample demonstration script to gather ip arp table
# -- ltd at cisco.com march 2009
die "usage: $0 (switch) (user) (pass) (vrf)\n" if ($#ARGV != 3);
($switch,$user,$pass,$vrf) = @ARGV;
$debug = 1;
$| = 1;
use Expect;
use XML::DOM;
$Expect::Log_Stdout = 0 if ($debug < 2);
# ssh to switch with netconf
my $exp = new Expect();
$exp->raw_pty(1);
printf STDERR "logging into switch %s as %s\n",$switch,$user if $debug;
die "could not spawn ssh: $!\n" if (!$exp->spawn("ssh","-s","-2","-v",
$user."@".$switch,"xmlagent"));
# send password and login
$exp->expect(20,
[ qr/Are you sure you want /,
sub { my $self = shift; $self->send("yes\n");
exp_continue; }],
[ qr/Name or service not known/,
sub { die "$switch unknown.\n"; }],
[ qr/password: /i,
sub { my $self = shift; printf STDERR "sending password\n"
if $debug;
$self->send($pass."\n"); exp_continue; }],
[ qr#<session-id>(\d+)</session-id>(.*)#,
sub { my $self = shift;
printf STDERR "netconf session %d established\n",
($self->matchlist)[0] if $debug;
$self->send(wrap_xml('
<nc:hello xmlns:nc="urn:ietf:params:xml:ns:netconf:base:1.0">
<nc:capabilities>
<nc:capability>urn:ietf:params:xml:ns:netconf:base:1.0</
nc:capability>
</nc:capabilities>
</nc:hello>'));
exp_continue; }],
[ timeout =>
sub { die "could not login\n"; } ],
']]>]]>');
# collect statistics
$exp->send(wrap_rpc("urib",'
<nc:get>
<nc:filter type="subtree">
<show>
<ip>
<arp>
<vrf><'.$vrf.'/></vrf>
</arp>
</ip>
</show>
</nc:filter>
</nc:get>'));
my $raw = read_rpc(30);
# printf STDERR "got %s\n",$raw if $debug;
my $parser = new XML::DOM::Parser;
my $stats = $parser->parsestring($raw);
my $nodes = $stats->getElementsByTagName("ROW_adj");
my $n = $nodes->getLength;
printf STDERR "found %d adjacencies\n",$n if $debug;
for (my $i = 0; $i < $n; $i++) {
my $node = $nodes->item($i);
# result data will be like this:
# <ROW_adj>
# <intf-out>mgmt0</intf-out>
# <ip-addr-out>10.67.16.12</ip-addr-out>
# <time-stamp>00:05:32</time-stamp>
# <mac>001e.c9b4.e670</mac>
foreach my $stat ($node->getChildNodes) {
next if ($stat->getNodeType() != ELEMENT_NODE);
my $key = $stat->getNodeName;
my $value = $stat->getFirstChild->getData;
printf STDERR " row %d key %s value %s\n",$i,$key,
$value if $debug;
}
}
$stats->dispose;
exit(0);
###############################################
# helper routing to format a netconf request inside rpc wrapper
sub wrap_rpc {
my $xmlns = shift;
my $cmd = shift;
$rpc_message_id = 100 if (!defined $rpc_message_id);
$rpc_message_id++;
return wrap_xml('<nc:rpc message-id="'.$rpc_message_id.'"
xmlns:nc="urn:ietf:params:xml:ns:netconf:base:1.0" xmlns="http://www.cisco.com/nxos:1.0:'.$xmlns.'
">'.$cmd.'</nc:rpc>');
}
###############################################
# helper routine to format a xml requst
sub wrap_xml {
my $cmd = shift;
return '<?xml version="1.0"?>'.$cmd.']]>]]>';
}
###############################################
# helper routine to receive a netconf/xml response
sub read_rpc {
my $timeout = shift;
my $data = "";
if ($exp->expect($timeout, ']]>]]>')) {
$data = $exp->before().$exp->match();
}
$data =~ s/]]>]]>$//g;
return $data;
}
###############################################
# the end
> For example,
> finding devices that haven't had their config saved is easy with SNMP:
>
> chgTime=`snmpget -OqUtv $DEV ccmHistoryRunningLastChanged.0`
> savTime=`snmpget -OqUtv $DEV ccmHistoryStartupLastChanged.0`
> if [ $savTime -lt $chgTime ]; then
> printf "%-14s config needs to be saved\n" $DEV
> fi
>
> how do you do that with Netconf/XML?
good question. the key to doing something in NetConf is to find a CLI
command that provides the data you want. e.g. if there was a CLI
command that provided time/datestamps of startup-config vs running-
config (or a flag indicating config has changed between them), then
you'd do that command.
off the top of my head, i can't think of a command that provides that,
however one COULD in theory ask the switch to provide a diff between
the running-config and the startup-config, e.g.
switch# show diff rollback-patch running-config startup-config
and if you get any changes then there is a difference.
its a bit heavyweight versus a flag, but assuming your script wanted
to do something intelligent based on said output, could be useful.
NX-OS does support the SNMP trap for ccmCLIRunningConfigChanged so you
could use that.
another way i can forsee that one could accomplish a simple trigger is
an EEM event that creates a file on config-change and clears it on
config-save, e.g.
event manager applet set_config_changed_flag
event cli match "config"
action 1 cli echo config_changed > volatile:config_changed
action 2 event-default
event manager applet clear_config_config_changed
event cli match "copy running-config startup-config"
action 1 cli delete volatile:config_changed
action 2 event-default
then your NetConf/XML can do the equivalent of "tail
volatile:config_changed" and see what result it gets back.
probably overkill but you get the idea - many ways to achieve what you
want.
cheers,
lincoln.
>
>
> Regards,
> Lee
More information about the cisco-nsp
mailing list