[c-nsp] Monitoring Nexus 7000 platform

Ash Net ashnet2009 at gmail.com
Sun Aug 16 21:38:23 EDT 2009


Thanks Lincoln and evrybody who has contributed to this thread.

The information provided is very beneficial for us to enable snmp
monitoring on our prod 7K gear.

Regards,

On 8/16/09, Lincoln Dale <ltd at cisco.com> wrote:
>
> 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
>
> _______________________________________________
> cisco-nsp mailing list  cisco-nsp at puck.nether.net
> https://puck.nether.net/mailman/listinfo/cisco-nsp
> archive at http://puck.nether.net/pipermail/cisco-nsp/
>


More information about the cisco-nsp mailing list