r3510 Nexus-related improvements:
authorDenis Ovsienko <infrastation@yandex.ru>
Sun, 2 May 2010 22:21:17 +0000 (22:21 +0000)
committerDenis Ovsienko <infrastation@yandex.ru>
Sun, 2 May 2010 22:21:17 +0000 (22:21 +0000)
nxos4.connector: a Perl implementation by Dmitry Tejblum
nxos4Read8021QConfig(): add real code copied from ios12 set of functions
nxos4ScanTopLevel(): new function
nxos4PickVLANs(): new function
nxos4PickSwitchportCommand(): new function

gateways/deviceconfig/nxos4.connector [new file with mode: 0755]
inc/functions.php

diff --git a/gateways/deviceconfig/nxos4.connector b/gateways/deviceconfig/nxos4.connector
new file mode 100755 (executable)
index 0000000..3cbaaef
--- /dev/null
@@ -0,0 +1,68 @@
+#!/usr/bin/perl
+
+# a working NX-OS connector for RackTables by Dmitry Tejblum
+
+use strict;
+use File::FnMatch qw(:fnmatch);
+use Net::Telnet::Cisco;
+$#ARGV == 2 or die "usage";
+my $endpoint = shift @ARGV;
+my $command = shift @ARGV;
+my $workfile = shift @ARGV;
+
+$0 =~ m,^(.*)/[^/]+$,;
+my $mydir = $1;
+open(SECRETS, "<$mydir/switch.secrets.php") || die "switch.secrets.php: $!";
+my $skip = 1;
+my ($username, $password, $enable_password);
+while (<SECRETS>) {
+    chomp;
+    if ($skip && ($_ eq "# S-T-A-R-T")) {
+        $skip = 0;
+        next;
+    }
+    if (!$skip && ($_ eq "# S-T-O-P")) {
+        $skip = 1;
+        next;
+    }
+    next if ($skip);
+    next if m,^\s*(#.*)?$,;
+    my @f = split;
+    if (fnmatch($f[0], $endpoint)) {
+        $username = $f[4];
+        $password = $f[5];
+        $enable_password = $f[6];
+        last;
+    }
+}
+
+if (!defined($username)) {
+    exit(3);
+}
+
+my $session = Net::Telnet::Cisco->new('Host' => $endpoint, 
+  Prompt => ' /(?m:^\015?\000?[\w.-]+(?:\(config[^\)]*\))?\s?[\$#>]\s?)/'
+);
+$session->login($username, $password);
+if ($enable_password ne "-") {
+    $session->enable($enable_password);
+}
+if ($command eq "retrieve") {
+    open(WORKFILE, ">$workfile") || die "$workfile: $!";
+    $session->cmd ('terminal length 0');
+    $session->cmd ('terminal no monitor');
+    $session->cmd ('show running-config vlan 1-4094');
+    $session->cmd ('show running-config interface');
+    my @r = $session->cmd ('show running-config vlan 1-4094');
+    print WORKFILE @r;
+    @r = $session->cmd('show running-config interface');
+    print WORKFILE @r;
+    exit(0);
+}
+if ($command eq "deploy") {
+    open(WORKFILE, "<$workfile") || die "$workfile: $!";
+    while (<WORKFILE>) {
+        $session->put($_);
+    }
+    exit(0);
+}
index 488d99ac5b2fe5aaa126bc3f3c6b265b73f55831..9b9092606b90569fa5f8994f0efe1f18c4b2a263 100644 (file)
@@ -2760,7 +2760,119 @@ function vrp53PickInterfaceSubcommand (&$work, $line)
 
 function nxos4Read8021QConfig ($input)
 {
-       return $input;
+       $ret = array
+       (
+               'vlanlist' => array(),
+               'portdata' => array(),
+       );
+       $procfunc = 'nxos4ScanTopLevel';
+       foreach (explode ("\n", $input) as $line)
+               $procfunc = $procfunc ($ret, $line);
+       return $ret;
+}
+
+function nxos4ScanTopLevel (&$work, $line)
+{
+       $matches = array();
+       switch (TRUE)
+       {
+       case (preg_match ('@^interface ((Ethernet)[[:digit:]]+(/[[:digit:]]+)*)$@', $line, $matches)):
+               $matches[1] = preg_replace ('@^Ethernet(.+)$@', 'e\\1', $matches[1]);
+               $work['current'] = array ('port_name' => $matches[1]);
+               return 'nxos4PickSwitchportCommand';
+       case (preg_match ('@^vlan ([[:digit:]]+)$@', $line, $matches)):
+               $work['vlanlist'][] = $matches[1];
+               return 'nxos4PickVLANs';
+       default:
+               return __FUNCTION__; // continue scan
+       }
+}
+
+function nxos4PickVLANs (&$work, $line)
+{
+       switch (TRUE)
+       {
+       case ($line == ''): // end of VLAN list
+               return 'nxos4ScanTopLevel';
+       case (preg_match ('@^vlan ([[:digit:]]+)$@', $line, $matches)):
+               $work['vlanlist'][] = $matches[1];
+       default: // VLAN name or any other text
+               return __FUNCTION__;
+       }
+}
+
+function nxos4PickSwitchportCommand (&$work, $line)
+{
+       if ($line == '') // end of interface section
+       {
+               // fill in defaults
+               // below assumes "system default switchport" mode set on the device
+               if (!array_key_exists ('mode', $work['current']))
+                       $work['current']['mode'] = 'access';
+               // save work, if it makes sense
+               switch ($work['current']['mode'])
+               {
+               case 'access':
+                       if (!array_key_exists ('access vlan', $work['current']))
+                               $work['current']['access vlan'] = 1;
+                       $work['portdata'][$work['current']['port_name']] = array
+                       (
+                               'mode' => 'access',
+                               'allowed' => array ($work['current']['access vlan']),
+                               'native' => $work['current']['access vlan'],
+                       );
+                       break;
+               case 'trunk':
+                       if (!array_key_exists ('trunk native vlan', $work['current']))
+                               $work['current']['trunk native vlan'] = 1;
+                       if (!array_key_exists ('trunk allowed vlan', $work['current']))
+                               $work['current']['trunk allowed vlan'] = range (VLAN_MIN_ID, VLAN_MAX_ID);
+                       // Having configured VLAN as "native" doesn't mean anything
+                       // as long as it's not listed on the "allowed" line.
+                       $effective_native = in_array
+                       (
+                               $work['current']['trunk native vlan'],
+                               $work['current']['trunk allowed vlan']
+                       ) ? $work['current']['trunk native vlan'] : 0;
+                       $work['portdata'][$work['current']['port_name']] = array
+                       (
+                               'mode' => 'trunk',
+                               'allowed' => $work['current']['trunk allowed vlan'],
+                               'native' => $effective_native,
+                       );
+                       break;
+               default:
+                       // dot1q-tunnel, dynamic, private-vlan --- skip these
+               }
+               unset ($work['current']);
+               return 'nxos4ScanTopLevel';
+       }
+       // not yet
+       $matches = array();
+       switch (TRUE)
+       {
+       case (preg_match ('@^  switchport mode (.+)$@', $line, $matches)):
+               $work['current']['mode'] = $matches[1];
+               break;
+       case (preg_match ('@^  switchport access vlan (.+)$@', $line, $matches)):
+               $work['current']['access vlan'] = $matches[1];
+               break;
+       case (preg_match ('@^  switchport trunk native vlan (.+)$@', $line, $matches)):
+               $work['current']['trunk native vlan'] = $matches[1];
+               break;
+       case (preg_match ('@^  switchport trunk allowed vlan add (.+)$@', $line, $matches)):
+               $work['current']['trunk allowed vlan'] = array_merge
+               (
+                       $work['current']['trunk allowed vlan'],
+                       iosParseVLANString ($matches[1])
+               );
+               break;
+       case (preg_match ('@^  switchport trunk allowed vlan (.+)$@', $line, $matches)):
+               $work['current']['trunk allowed vlan'] = iosParseVLANString ($matches[1]);
+               break;
+       default: // suppress warning on irrelevant config clause
+       }
+       return __FUNCTION__;
 }
 
 // Scan given array and return the key, which addresses the first item