RT#39115: View SNMP info on svc_broadband service [timeout fix & multiple value handling]
authorJonathan Prykop <jonathan@freeside.biz>
Thu, 21 Jan 2016 22:42:08 +0000 (16:42 -0600)
committerJonathan Prykop <jonathan@freeside.biz>
Thu, 21 Jan 2016 23:47:33 +0000 (17:47 -0600)
FS/FS/part_export/broadband_snmp_get.pm
httemplate/elements/broadband_snmp_get.html

index fafe91a..18ba8ea 100644 (file)
@@ -61,15 +61,15 @@ Configuration for realtime snmp requests to svc_broadband IP address
 
 =item snmp_results SVC
 
-Request statistics from SVC ip address.  Returns an array of hashes with keys 
+Request statistics from SVC ip address.  Returns an array of hashrefs with keys 
 
-objectID
+error - error message
 
-label
+objectID - dotted decimal fully qualified OID
 
-value
+label - leaf textual identifier (e.g., 'sysDescr')
 
-error - error when attempting to load this object
+values - arrayref of arrayrefs describing values, [<obj>, <iid>, <val>, <type>]
 
 =cut
 
@@ -78,7 +78,7 @@ sub snmp_results {
   my $host = $svc->ip_addr;
   my $comm = $self->option('snmp_community');
   my $vers = $self->option('snmp_version');
-  my $time = ($self->option('snmp_timeout') || 1) * 1000;
+  my $time = ($self->option('snmp_timeout') || 1) * 1000000;
   my @oids = split("\n", $self->option('snmp_oid'));
   my %connect = (
     'DestHost'  => $host,
@@ -92,13 +92,33 @@ sub snmp_results {
   my @out;
   foreach my $oid (@oids) {
     $oid = $SNMP::MIB{$oid}->{'objectID'} if $SNMP::MIB{$oid};
-    my $value = $snmp->get($oid.'.0');
-    if ($snmp->{'ErrorStr'}) {
-      push @out, { 'error' => $snmp->{'ErrorStr'} };
+    my @values;
+    if ($vers eq '1') {
+      my $varbind = new SNMP::Varbind [$oid];
+      my $max = 1000; #sanity check
+      while ($max > 0 and $snmp->getnext($varbind)) {
+        last if $snmp->{'ErrorStr'};
+        last unless $SNMP::MIB{$varbind->[0]}; # does this happen?
+        my $nextoid = $SNMP::MIB{$varbind->[0]}->{'objectID'};
+        last unless $nextoid =~ /^$oid/;
+        $max--;
+        push @values, new SNMP::Varbind [ @$varbind ];
+      }
+    } else {
+      # not clear on what max-repeaters (25) does, plucked value from example code
+      # but based on testing, it isn't capping number of returned values
+      @values = $snmp->bulkwalk(0,25,$oid);
+    }
+    if ($snmp->{'ErrorStr'} || !@values) {
+      push @out, { 'error' => $snmp->{'ErrorStr'} || 'No values retrieved' };
       next;
     }
-    my %result = map { $_ => $SNMP::MIB{$oid}{$_} } qw( objectID label value );
-    $result{'value'} = $value;
+    my %result = map { $_ => $SNMP::MIB{$oid}{$_} } qw( objectID label );
+    # unbless @values, for ease of JSON encoding
+    $result{'values'} = [];
+    foreach my $value (@values) {
+      push @{$result{'values'}}, [ map { $_ } @$value ];
+    }
     push @out, \%result;
   }
   return @out;      
index d4cc4e4..213bc44 100644 (file)
@@ -22,22 +22,29 @@ function broadband_snmp_get (svcnum) {
       if (objects.length) {
         var table = document.createElement('table');
         for (i = 0; i < objects.length; i++) {
-          var row = document.createElement('tr');
           var obj = objects[i];
           if (obj.error) {
+            var row = document.createElement('tr');
             var cell = document.createElement('td');
             cell.colSpan = '2';
             cell.innerHTML = obj['error'];
             row.appendChild(cell);
+            table.appendChild(row);
           } else {
+            for (j = 0; j < obj['values'].length; j++) {
+              var row = document.createElement('tr');
+              var value = obj['values'][j];
+              var label = (obj['values'].length > 1) ? (value[0] + '.' + value[1]) : obj['label'];
               var cell = document.createElement('td');
-              cell.innerHTML = obj['label'];
+              cell.innerHTML = label;
               row.appendChild(cell);
               cell = document.createElement('td');
-              cell.innerHTML = obj['value'];
+              cell.innerHTML = value[2];
+              cell.style.paddingLeft = '3em';
               row.appendChild(cell);
+              table.appendChild(row);
+            }
           }
-          table.appendChild(row);
         }
         var resultblock = document.getElementById('broadband_snmp_get');
         resultblock.innerHTML = '';