[cisco-stats] Honor Port-channel interfaces and pushed output generation into functions.
authorMaximilian Wilhelm <max@rfc2324.org>
Sat, 5 Jan 2008 23:08:29 +0000 (00:08 +0100)
committerMaximilian Wilhelm <max@rfc2324.org>
Sat, 5 Jan 2008 23:08:29 +0000 (00:08 +0100)
Signed-off-by: Maximilian Wilhelm <max@rfc2324.org>

cisco-stats/generate_cisco_port_configuration_overview

index 1a1d4c5..09626fe 100755 (executable)
@@ -14,6 +14,7 @@
 #
 
 use strict;
+use Carp;
 
 use Getopt::Long;
 
@@ -41,7 +42,7 @@ my $include_ports = undef;
 
 #
 # Hash with interfaces
-#  Top level keys: Interface type (FastEthernet, GigabitEthernet, ...)
+#  Top level keys: Interface type (FastEthernet, GigabitEthernet, ...) or (Portchannel)
 #  2nd level keys: Module or interface number
 #  optional 3rd level keys: interface number in case of modules.
 my $interfaces = {};
@@ -108,11 +109,12 @@ while (my $line = <RUNNING_CONFIG>) { # Read device configuration {{{
        if ($line =~ /^interface (.+)$/) { # {{{
                my $port_name = $1;
 
+               # Honor include_ports list if set
                if (defined $include_ports && ! defined $include_ports->{$port_name}) {
                        next;
                }
 
-               # Simple IOS interface on unmodular switch
+               # Simple IOS interface on (un)modular switch
                if ($port_name =~ /^([a-zA-Z]+)([0-9])\/([0-9]+)$/) { # {{{
                        my ($type, $module, $port) = ($1, $2, $3);
 
@@ -139,8 +141,34 @@ while (my $line = <RUNNING_CONFIG>) { # Read device configuration {{{
                        next;
                } # }}}
 
+               # IOS Port-channels
+               elsif ($port_name =~ /^Port-channel([0-9]+)$/) { # {{{
+                       my $channel_group_num = $1;
+
+                       if (exists $interfaces->{Channel}->{$channel_group_num}) {
+                               die "Error: Redefined interface $port_name at line $line_num\n";
+                       }
+
+
+                       $interfaces->{Channel}->{$channel_group_num} = {
+                               type => "port_channel",
+                               channel_group_num => $channel_group_num,
+
+                               name => "Port-channel$channel_group_num",
+                               access_vlan => undef,
+                               trunk_allowed_vlans => undef,
+                               mode => undef,
+                               desc => undef,
+                               disabled => undef,
+                       };
+
+                       # Act on this interface util finding next
+                       $current_int = $interfaces->{Channel}->{$channel_group_num};
+                       next;
+               } # }}}
+
                # Warn user on unknown/unhandled interface types
-               elsif ($line =~ /^interface (.*)$/) { # {{{
+               else { # {{{
                        print STDERR "Unknown interface \"$1\" at line $line_num, skipping it\n";
                        next;
                } # }}}
@@ -262,6 +290,101 @@ my $vlan_count = scalar (@vlan_list);
 # Output generation
 #
 
+#
+# Print information about channel interfaces
+sub print_channel_interfaces ($) { # print_channel_interfaces ($interfaces->{channel}) {{{
+       my $channel_int_ref = shift;
+
+       if (! $channel_int_ref || ref ($channel_int_ref) ne 'HASH') {
+               confess "print_channel_interfaces(): Called without or invalid argument!\n";
+       }
+
+       print_interfaces ($channel_int_ref);
+} # }}}
+
+#
+# Print information about generic interfaces (FastEthernet, GigabitEthernet)
+# and all modules with this type
+sub print_generic_interfaces ($) { # print_generic_interfaces ($interfaces->{$int_type}) {{{
+       my $int_type_hash = shift;
+
+       if (! $int_type_hash || ref ($int_type_hash) ne 'HASH') {
+               confess "print_generic_interfaces(): Called without or invalid argument!\n";
+       }
+
+       # Loop over each module found with the current interface type
+       foreach my $module (sort { $a <=> $b }  keys %{$int_type_hash}) {
+               print_interfaces ($int_type_hash->{$module});
+       }
+} # }}}
+
+#
+# Print information about all interfaces in given hash_ref in prepared table
+sub print_interfaces ($) { # print_interfaces (\%interfaces_of_$type) {{{
+       my $interfaces_hash = shift;
+
+       if (! $interfaces_hash || ref ($interfaces_hash) ne 'HASH') {
+               confess "print_generic_module(): Called without or invalid argument!\n";
+       }
+
+       # Loop over each interface found on the current module
+       foreach my $int (sort { $a <=> $b } keys %{$interfaces_hash}) {
+               my $int_ref = $interfaces_hash->{$int};
+
+               print "\t   <tr>\n";
+               my $int_class="";
+
+               # IntName [(IntDesc)] \[IntMode [UNLIMITED]\]
+               my $int_string = "$int_ref->{name} ";
+               if (defined $int_ref->{desc}) {
+                       $int_string .= "($int_ref->{desc}) ";
+               }
+
+               # Port mode (access or trunk)
+               $int_class = "$int_ref->{mode}" . "_port";
+
+               $int_string .= "[";
+               if ($int_ref->{mode} eq 'trunk' && ! defined $int_ref->{trunk_allowed_vlans}) {
+                       $int_string .= "UNLIMITED ";
+                       $int_class = "unlimited_trunk";
+               }
+               $int_string .= "$int_ref->{mode}]";
+
+               # Is the port shutdown?
+               if ($int_ref->{disabled}) {
+                       $int_string = "<strike>$int_string</strike>";
+               }
+
+               # Print it
+               print "\t    <td class=\"$int_class\">\n";
+               print "\t     $int_string\n";
+               print "\t    </td>  ";
+
+               # Print X'es
+               foreach my $vlan_id (@vlan_list) {
+                       if ($int_ref->{disabled}) {
+                               print " <td class=\"x_linethrough\">";
+                       } else {
+                               print " <td class=\"x\">";
+                       }
+
+                       if (($int_ref->{mode} eq 'access' && $int_ref->{access_vlan} == $vlan_id) ||
+                           ($int_ref->{mode} eq 'trunk' && (! defined $int_ref->{trunk_allowed_vlans} || grep {/^$vlan_id$/} @{$int_ref->{trunk_allowed_vlans}})) )  {
+                               print "<b>X</b>";
+                       } else {
+                               print " &nbsp; ";
+                       }
+
+                       print "</td> ";
+               }
+
+               print "\t   </tr>\n";
+       }
+
+       print "\n";
+} # }}}
+
+
 # HTML header + styles # {{{
 print '<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/1999/REC-html401-19991224/strict.dtd">
        <html>
@@ -344,6 +467,7 @@ print '<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/1
 
 '; # }}}
 
+
 # Generate table row with vlan IDs
 my $vlan_row = '         <tr>
           <th class="border_right_2px_solid">Interface \ Vlan</th>
@@ -363,63 +487,12 @@ foreach my $int_type (sort keys %{$interfaces}) {
        print $vlan_row;
        print "\n";
 
-       # Loop over each module found with the current interface type
-       foreach my $module (sort { $a <=> $b } keys %{$interfaces->{$int_type}}) {
-
-               # Loop over each interface found on the current module
-               foreach my $int (sort { $a <=> $b } keys %{$interfaces->{$int_type}->{$module}}) { # {{{
-                       my $int_ref = $interfaces->{$int_type}->{$module}->{$int};
-
-                       print "\t   <tr>\n";
-                       my $int_class="";
-
-                       # IntName [(IntDesc)] \[IntMode [UNLIMITED]\]
-                       my $int_string = "$int_ref->{name} ";
-                       if (defined $int_ref->{desc}) {
-                               $int_string .= "($int_ref->{desc}) ";
-                       }
-
-                       # Port mode (access or trunk)
-                       $int_class = "$int_ref->{mode}" . "_port";
-
-                       $int_string .= "[";
-                       if ($int_ref->{mode} eq 'trunk' && ! defined $int_ref->{trunk_allowed_vlans}) {
-                               $int_string .= "UNLIMITED ";
-                               $int_class = "unlimited_trunk";
-                       }
-                       $int_string .= "$int_ref->{mode}]";
-
-                       # Is the port shutdown?
-                       if ($int_ref->{disabled}) {
-                               $int_string = "<strike>$int_string</strike>";
-                       }
-
-                       # Print it
-                       print "\t    <td class=\"$int_class\">\n";
-                       print "\t     $int_string\n";
-                       print "\t    </td>  ";
-
-                       # Print X'es
-                       foreach my $vlan_id (@vlan_list) {
-                               if ($int_ref->{disabled}) {
-                                       print " <td class=\"x_linethrough\">";
-                               } else {
-                                       print " <td class=\"x\">";
-                               }
-
-                               if (($int_ref->{mode} eq 'access' && $int_ref->{access_vlan} == $vlan_id) ||
-                                   ($int_ref->{mode} eq 'trunk' && (! defined $int_ref->{trunk_allowed_vlans} || grep {/^$vlan_id$/} @{$int_ref->{trunk_allowed_vlans}})) )  {
-                                       print "<b>X</b>";
-                               } else {
-                                       print " &nbsp; ";
-                               }
-
-                               print "</td> ";
-                       }
+       if ($int_type eq "Channel") {
+               print_interfaces ($interfaces->{$int_type});
+       }
 
-                       print "\t   </tr>\n";
-               } # }}}
-               print "\n";
+       else {
+               print_generic_interfaces ($interfaces->{$int_type});
        }
 
        print "  </table>\n";