076d79867b607a5c35ac1f1a0749599bf7b5e42c
[freeside.git] / torrus / perllib / Torrus / DevDiscover / Arbor_E.pm
1 #
2 #  Discovery module for Arbor|e Series devices
3 #  Formerly Ellacoya Networks
4 #
5 #  Copyright (C) 2008 Jon Nistor
6 #
7 #  This program is free software; you can redistribute it and/or modify
8 #  it under the terms of the GNU General Public License as published by
9 #  the Free Software Foundation; either version 2 of the License, or
10 #  (at your option) any later version.
11 #
12 #  This program is distributed in the hope that it will be useful,
13 #  but WITHOUT ANY WARRANTY; without even the implied warranty of
14 #  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15 #  GNU General Public License for more details.
16 #
17 #  You should have received a copy of the GNU General Public License
18 #  along with this program; if not, write to the Free Software
19 #  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
20 #
21 # $Id: Arbor_E.pm,v 1.1 2010-12-27 00:03:52 ivan Exp $
22 # Jon Nistor <nistor at snickers.org>
23 #
24 # NOTE: This module has been tested against v7.5.x, v7.6.x, v9.0.x, v9.1.x
25 #
26 # -- Common
27 #      Arbor_E::disable-bundle-offer
28 #      Arbor_E::disable-bundle-offer-deny
29 #      Arbor_E::disable-bundle-offer-pktsize
30 #      Arbor_E::disable-bundle-offer-rate
31 #      Arbor_E::disable-bundle-offer-subcount
32 #      Arbor_E::enable-bundle-name-rrd
33 #      Arbor_E::disable-flowdev
34 #
35 # -- e30 specific
36 #      Arbor_E::disable-e30-buffers
37 #      Arbor_E::disable-e30-bundle
38 #      Arbor_E::disable-e30-cpu
39 #      Arbor_E::disable-e30-fwdTable
40 #      Arbor_E::disable-e30-fwdTable-login
41 #      Arbor_E::disable-e30-hdd
42 #      Arbor_E::enable-e30-hdd-errors
43 #      Arbor_E::disable-e30-hdd-logs
44 #      Arbor_E::disable-e30-l2tp
45 #      Arbor_E::disable-e30-mem
46 #      Arbor_E::enable-e30-mempool
47 #      Arbor_E::disable-e30-bundle
48 #      Arbor_E::disable-e30-bundle-deny
49 #      Arbor_E::disable-e30-bundle-rate
50 #      Arbor_E::disable-e30-slowpath 
51 #
52 # -- e100 specific
53 #      Arbor_E::disable-e100-cpu
54 #      Arbor_E::disable-e100-hdd
55 #      Arbor_E::disable-e100-mem
56 #      Arbor_E::disable-e100-policymgmt
57 #      Arbor_E::disable-e100-submgmt
58 #
59
60 # Arbor_E devices discovery
61 package Torrus::DevDiscover::Arbor_E;
62
63 use strict;
64 use Torrus::Log;
65
66
67 $Torrus::DevDiscover::registry{'Arbor_E'} = {
68     'sequence'     => 500,
69     'checkdevtype' => \&checkdevtype,
70     'discover'     => \&discover,
71     'buildConfig'  => \&buildConfig
72     };
73
74 our %oiddef =
75     (
76      # ELLACOYA-MIB
77      'eProducts'             => '1.3.6.1.4.1.3813.2',
78      'codeVer'               => '1.3.6.1.4.1.3813.1.4.1.1.0',
79      'sysIdSerialNum'        => '1.3.6.1.4.1.3813.1.4.1.5.2.0',
80      'memPoolNameIndex'      => '1.3.6.1.4.1.3813.1.4.2.5.1.1',
81      'hDriveErrModel'        => '1.3.6.1.4.1.3813.1.4.2.10.16.0',
82      'hDriveErrSerialNum'    => '1.3.6.1.4.1.3813.1.4.2.10.17.0',
83      'partitionName'         => '1.3.6.1.4.1.3813.1.4.2.11.1.2', # e100
84      'cpuSdramIndex'         => '1.3.6.1.4.1.3813.1.4.2.12.1.1', # e100
85      'hDriveDailyLogSize'    => '1.3.6.1.4.1.3813.1.4.2.13.0',
86      'cpuUtilization'        => '1.3.6.1.4.1.3813.1.4.4.1.0',
87      'cpuUtilTable'          => '1.3.6.1.4.1.3813.1.4.4.2',      # e100
88      'cpuIndex'              => '1.3.6.1.4.1.3813.1.4.4.2.1.1',  # e100
89      'cpuName'               => '1.3.6.1.4.1.3813.1.4.4.2.1.2',  # e100
90      'loginRespOkStatsIndex' => '1.3.6.1.4.1.3813.1.4.3.15.1.1',
91
92      # ELLACOYA-MIB::cpuCounters, e30 (available in 7.5.x -- slowpath counters)
93      'cpuCounters'           => '1.3.6.1.4.1.3813.1.4.4.10',
94      'slowpathCounters'      => '1.3.6.1.4.1.3813.1.4.4.10.1',
95      'sigCounters'           => '1.3.6.1.4.1.3813.1.4.4.10.2',
96
97      # ELLACOYA-MIB::flow
98      'flowPoolNameD1'        => '1.3.6.1.4.1.3813.1.4.5.1.1.1.2',
99      'flowPoolNameD2'        => '1.3.6.1.4.1.3813.1.4.5.2.1.1.2',
100
101      # ELLACOYA-MIB::bundleStatsTable
102      'bundleName'                    => '1.3.6.1.4.1.3813.1.4.12.1.1.2',
103      'bundleBytesSentDenyPolicyDrop' => '1.3.6.1.4.1.3813.1.4.12.1.1.6',
104      'bundleBytesSentRateLimitDrop'  => '1.3.6.1.4.1.3813.1.4.12.1.1.8',
105      'boBundleID'                    => '1.3.6.1.4.1.3813.1.4.12.2.1.1',
106      'boBundleName'                  => '1.3.6.1.4.1.3813.1.4.12.2.1.3',
107      'boOfferName'                   => '1.3.6.1.4.1.3813.1.4.12.2.1.4',
108      'boBundleSubCount'              => '1.3.6.1.4.1.3813.1.4.12.2.1.7',
109      'boPacketsSent64'               => '1.3.6.1.4.1.3813.1.4.12.2.1.8',
110      'boBundleBytesSentDenyPolicyDrop' => '1.3.6.1.4.1.3813.1.4.12.2.1.22',
111      'boBundleBytesSentRateLimitDrop'  => '1.3.6.1.4.1.3813.1.4.12.2.1.24',
112
113      # ELLACOYA-MIB::policyMgmt, e100
114      'policyMgmt'                    => '1.3.6.1.4.1.3813.1.4.16',
115
116      # ELLACOYA-MIB::subscriberMgmt, e100
117      'subscriberMgmt'                => '1.3.6.1.4.1.3813.1.4.17',
118      'subscriberStateName'           => '1.3.6.1.4.1.3813.1.4.17.7.1.2',
119
120      # ELLACOYA-MIB::l2tp, e30 (available in 7.5.x)
121      'l2tpConfigEnabled'             => '1.3.6.1.4.1.3813.1.4.18.1.1.0',
122      'l2tpSecureEndpointIpAddress'   => '1.3.6.1.4.1.3813.1.4.18.3.2.1.1.1',
123      'l2tpSecureEndpointOverlapping' => '1.3.6.1.4.1.3813.1.4.18.3.2.1.1.3',
124
125      );
126
127 our %eChassisName =
128     (
129         '1'  => 'e16k',
130         '2'  => 'e4k',
131         '3'  => 'e30 Revision: R',
132         '4'  => 'e30 Revision: S',
133         '5'  => 'e30 Revision: T',
134         '6'  => 'e30 Revision: U',
135         '7'  => 'e30 Revision: V',
136         '8'  => 'Ellacoya e100',
137         '9'  => 'e100'
138     );
139
140 our %eCpuName =
141     (
142         '1'  => 'Control Module',
143         '3'  => 'DPI Module 1 CPU 1',
144         '4'  => 'DPI Module 1 CPU 2',
145         '5'  => 'DPI Module 2 CPU 1',
146         '6'  => 'DPI Module 2 CPU 2',
147         '7'  => 'I/O Module'
148     );
149
150 sub checkdevtype
151 {
152     my $dd = shift;
153     my $devdetails = shift;
154
155     if( not $dd->oidBaseMatch
156         ( 'eProducts', $devdetails->snmpVar( $dd->oiddef('sysObjectID') ) ) )
157     {
158         return 0;
159     }
160    
161     $devdetails->setCap('interfaceIndexingPersistent');
162
163     return 1;
164 }
165
166
167 sub discover
168 {
169     my $dd = shift;
170     my $devdetails = shift;
171
172     my $session = $dd->session();
173     my $data = $devdetails->data();
174
175     # PROG: Grab versions, serials and type of chassis.
176     my $eInfo = $dd->retrieveSnmpOIDs
177                    ( 'codeVer', 'sysIdSerialNum', 'sysObjectID' );
178     $eInfo->{'modelNum'} = $eInfo->{'sysObjectID'};
179     $eInfo->{'modelNum'} =~ s/.*(\d)$/$1/; # Last digit
180
181     # SNMP: System comment
182     $data->{'param'}{'comment'} =
183             "Arbor " . $eChassisName{$eInfo->{'modelNum'}} .
184             ", Hw Serial#: " . $eInfo->{'sysIdSerialNum'} .
185             ", Version: " .  $eInfo->{'codeVer'};
186
187     # ------------------------------------------------------------------------
188     # Arbor_E e30 related material here
189     if( $eInfo->{'modelNum'} < 8 )
190     {
191         Debug("Arbor_E: Found " . $eChassisName{$eInfo->{'modelNum'}} );
192
193         # PROG: Set Capability to be the e30 device
194         $devdetails->setCap('e30');
195
196         # PROG: Check status oids
197         if( $devdetails->param('Arbor_E::disable-e30-buffers') ne 'yes' )
198         {
199             $devdetails->setCap('e30-buffers');
200         }
201
202         if( $devdetails->param('Arbor_E::disable-e30-cpu') ne 'yes' )
203         {
204             $devdetails->setCap('e30-cpu');
205         }
206
207         if( $devdetails->param('Arbor_E::disable-e30-fwdTable') ne 'yes' )
208         {
209             $devdetails->setCap('e30-fwdTable');
210
211             if( $devdetails->param('Arbor_E::disable-e30-fwdTable-login')
212                 ne 'yes' )
213             {
214                 my $loginTable = $session->get_table(
215                        -baseoid => $dd->oiddef('loginRespOkStatsIndex') );
216                 $devdetails->storeSnmpVars( $loginTable );
217
218                 if( defined( $loginTable ) )
219                 {
220                     $devdetails->setCap('e30-fwdTable-login');
221
222                     foreach my $statsIdx ( $devdetails->getSnmpIndices(
223                                       $dd->oiddef('loginRespOkStatsIndex') ) )
224                     {
225                         push(@{$data->{'e30'}{'loginResp'}}, $statsIdx);
226                     }
227                 }
228             } # END hasCap disable-e30-fwdTable-login
229         }
230
231         if( $devdetails->param('Arbor_E::disable-e30-hdd') ne 'yes' )
232         {
233             $devdetails->setCap('e30-hdd');
234
235             # SNMP: Add harddrive comment information
236             $eInfo = $dd->retrieveSnmpOIDs( 'hDriveErrModel',
237                                             'hDriveErrSerialNum' );
238
239             $data->{'e30'}{'hddModel'}  = $eInfo->{'hDriveErrModel'};
240             $data->{'e30'}{'hddSerial'} = $eInfo->{'hDriveErrSerialNum'};
241
242             # PROG: Do we want errors as well?
243             if( $devdetails->param('Arbor_E::enable-e30-hdd-errors') eq 'yes' )
244             {
245                 $devdetails->setCap('e30-hdd-errors');
246             }
247
248             # PROG: Do we want to look at daily log files? (New in 7.6)
249             if( $devdetails->param('Arbor_E::disable-e30-hdd-logs') ne 'yes' )
250             {
251                 $eInfo = $dd->retrieveSnmpOIDs( 'hDriveDailyLogSize' );
252
253                 if( $eInfo->{'hDriveDailyLogSize'} )
254                 {
255                     $devdetails->setCap('e30-hdd-logs');
256                 }
257             }
258         } # END: if disable-e30-hdd
259
260         if( $devdetails->param('Arbor_E::disable-e30-l2tp') ne 'yes' )
261         {
262             # 1 - disabled, 2 - enabled, 3 - session aware
263             $eInfo = $dd->retrieveSnmpOIDs('l2tpConfigEnabled');
264
265             if( $eInfo->{'l2tpConfigEnabled'} > 1 )
266             {
267                 $devdetails->setCap('e30-l2tp');
268
269                 my $l2tpSecEndTable = $session->get_table(
270                        -baseoid => $dd->oiddef('l2tpSecureEndpointIpAddress') );
271                 $devdetails->storeSnmpVars( $l2tpSecEndTable );
272
273                 Debug("e30: L2TP secure endpoints found:");
274                 foreach my $SEP ( $devdetails->getSnmpIndices(
275                                   $dd->oiddef('l2tpSecureEndpointIpAddress') ) )
276                 {
277                         next if( ! $SEP );
278                         $data->{'e30'}{'l2tpSEP'}{$SEP} = 0;
279                         Debug("e30:    $SEP");
280                 }
281             } # END: if l2tpConfigEnabled
282         }
283
284         # Memory usage on system
285         if( $devdetails->param('Arbor_E::disable-e30-mem') ne 'yes' )
286         {
287             $devdetails->setCap('e30-mem');
288         }
289
290         # Memory usage / individual blocks
291         if( $devdetails->param('Arbor_E::enable-e30-mempool') eq 'yes' )
292         {
293             my $mempoolTable = $session->get_table(
294                                  -baseoid => $dd->oiddef('memPoolNameIndex') );
295             $devdetails->storeSnmpVars( $mempoolTable );
296
297             if( defined( $mempoolTable ) )
298             {
299                 $devdetails->setCap('e30-mempool');
300
301                 foreach my $memOID (
302                            $devdetails->getSnmpIndices(
303                                 $dd->oiddef('memPoolNameIndex') ) )
304                 {
305                     my $memName = $mempoolTable->{
306                                $dd->oiddef('memPoolNameIndex') . '.' . $memOID};
307
308                     Debug("e30:  Mempool: $memName");
309                     $data->{'e30'}{'mempool'}{$memOID} = $memName;
310                 }
311             }
312         }
313
314         # Traffic statistics per Bundle
315         if( $devdetails->param('Arbor_E::disable-e30-bundle') ne 'yes' )
316         {
317             # Set capability 
318             $devdetails->setCap('e30-bundle');
319
320             # Pull table information
321             my $bundleTable = $session->get_table(
322                                 -baseoid => $dd->oiddef('bundleName') );
323             $devdetails->storeSnmpVars( $bundleTable );
324
325             Debug("e30: Bundle Information id:name");
326             foreach my $bundleID (
327                        $devdetails->getSnmpIndices( $dd->oiddef('bundleName') ))
328             {
329                     my $bundleName = $bundleTable->{$dd->oiddef('bundleName') .
330                                         '.' . $bundleID};
331                     $data->{'e30'}{'bundleID'}{$bundleID} = $bundleName;
332         
333                     Debug("e30:    $bundleID $bundleName");
334             } # END foreache my $bundleID
335
336             if( $devdetails->param('Arbor_E::disable-e30-bundle-deny') ne 'yes')
337             {
338                 my $bundleDenyTable = $session->get_table(
339                      -baseoid => $dd->oiddef('bundleBytesSentDenyPolicyDrop') );
340                 $devdetails->storeSnmpVars( $bundleDenyTable );
341
342                 if( $bundleDenyTable )
343                 {
344                     $devdetails->setCap('e30-bundle-denyStats');
345                 }
346             }
347
348             if( $devdetails->param('Arbor_E::disable-e30-bundle-rate') ne 'yes')
349             {
350                 my $bundleRateLimitTable = $session->get_table(
351                      -baseoid => $dd->oiddef('bundleBytesSentRateLimitDrop') );
352                 $devdetails->storeSnmpVars( $bundleRateLimitTable );
353
354                 if( $bundleRateLimitTable )
355                 {
356                     $devdetails->setCap('e30-bundle-rateLimitStats');
357                 }
358             }
359
360         } # END if Arbor_E::disable-e30-bundle
361
362         # PROG: Counters
363         if( $devdetails->param('Arbor_E::disable-e30-slowpath') ne 'yes' )
364         {
365             # Slowpath counters are available as of 7.5.x
366             my $counters = $session->get_table(
367                             -baseoid => $dd->oiddef('slowpathCounters') );
368             $devdetails->storeSnmpVars( $counters );
369
370             if( defined( $counters ) )
371             {
372                 $devdetails->setCap('e30-slowpath');
373             }
374         }
375     }
376
377
378     # ------------------------------------------------------------------------
379     #
380     # Arbor E100 related material here
381
382     if( $eInfo->{'modelNum'} >= 8 )
383     {
384         Debug("Arbor_E: Found " . $eChassisName{$eInfo->{'modelNum'}} );
385
386         # PROG: Set Capability to be the e100 device
387         $devdetails->setCap('e100');
388
389         # CPU parameters ...
390         if( $devdetails->param('Arbor_E::disable-e100-cpu') ne 'yes' )
391         {
392           my $cpuNameTable = $session->get_table(
393                             -baseoid => $dd->oiddef('cpuName') );
394           $devdetails->storeSnmpVars( $cpuNameTable );
395
396           if( defined( $cpuNameTable ) )
397           {
398             $devdetails->setCap('e100-cpu');
399
400             # PROG: Find all the CPU's ..
401             foreach my $cpuIndex ( $devdetails->getSnmpIndices(
402                                    $dd->oiddef('cpuName') ) )
403             {
404               my $cpuName = $cpuNameTable->{$dd->oiddef('cpuName') .
405                                                    '.' . $cpuIndex};
406
407               Debug("  CPU found: $cpuIndex, $cpuName");
408               $data->{'e100'}{'cpu'}{$cpuIndex} = $cpuName;
409             }
410           }
411         }
412
413         # HDD Parameters
414         if( $devdetails->param('Arbor_E::disable-e100-hdd') ne 'yes' )
415         {
416           my $hddTable = $session->get_table(
417                            -baseoid => $dd->oiddef('partitionName') );
418           $devdetails->storeSnmpVars( $hddTable );
419
420           if( defined( $hddTable ) )
421           {
422             $devdetails->setCap('e100-hdd');
423
424             # PROG: Find all the paritions and names ..
425             foreach my $hddIndex ( $devdetails->getSnmpIndices(
426                                    $dd->oiddef('partitionName') ) )
427             {
428               my $partitionName = $hddTable->{$dd->oiddef('partitionName') .
429                                               '.' . $hddIndex};
430               Debug("HDD Partition: $hddIndex, $partitionName");
431               $data->{'e100'}{'hdd'}{$hddIndex} = $partitionName;
432             }
433           }
434         }
435
436         # MEM Parameters
437         if( $devdetails->param('Arbor_E::disable-e100-mem') ne 'yes' )
438         {
439           my $cpuSdramTable = $session->get_table(
440                              -baseoid => $dd->oiddef('cpuSdramIndex') );
441           $devdetails->storeSnmpVars( $cpuSdramTable );
442
443           if( defined( $cpuSdramTable ) )
444           {
445             $devdetails->setCap('e100-mem');
446
447             # PROG: Find all memory indexes
448             foreach my $memIndex ( $devdetails->getSnmpIndices(
449                                    $dd->oiddef('cpuSdramIndex') ) )
450             {
451               my $memName = $data->{'e100'}{'cpu'}{$memIndex};
452               Debug("MEM found: $memIndex, $memName");
453               $data->{'e100'}{'mem'}{$memIndex} = $memName;
454             }
455           }
456         }
457
458         # Policy Mgmt parameters
459         if( $devdetails->param('Arbor_E::disable-e100-policymgmt') ne 'yes' )
460         {
461           my $policyTable = $session->get_table(
462                               -baseoid => $dd->oiddef('policyMgmt')
463                             );
464           $devdetails->storeSnmpVars( $policyTable );
465
466           if( defined( $policyTable ) )
467           {
468             $devdetails->setCap('e100-policymgmt');
469           }
470         }
471
472         # Subscriber Mgmt parameters
473         if( $devdetails->param('Arbor_E::disable-e100-submgmt') ne 'yes' )
474         {
475           my $subTable = $session->get_table(
476                             -baseoid => $dd->oiddef('subscriberStateName')
477                          );
478           $devdetails->storeSnmpVars( $subTable );
479
480           if( defined( $subTable ) )
481           {
482             $devdetails->setCap('e100-submgmt');
483
484             # Sub: Find state name entries
485             foreach my $stateIDX ( $devdetails->getSnmpIndices( $dd->oiddef(
486                                         'subscriberStateName') ) )
487             {
488                my $state = $subTable->{
489                               $dd->oiddef('subscriberStateName') .
490                               '.' .  $stateIDX
491                            };
492                
493                Debug("  State index: $stateIDX, name: $state");
494                $data->{'e100'}{'submgmt'}{$stateIDX} = $state;
495             }
496           }
497         }
498     }
499
500
501     # ------------------------------------------------------------------------
502     #
503     # Common information between e30 and e100
504
505     if( $devdetails->param('Arbor_E::disable-flowdev') ne 'yes' )
506     {
507         $devdetails->setCap('arbor-flowLookup');
508
509         # Flow Lookup Device information
510         # Figure out what pools exist for the 2 flow switching modules
511         # ------------------------------------------------------------
512         my $switchingModules = 2;
513
514         foreach my $flowModule (1 .. $switchingModules) {
515             Debug("common:  Flow Lookup Device " . $flowModule);
516
517             my $flowPoolOid  = 'flowPoolNameD' . $flowModule;
518             my $flowModTable = $session->get_table (
519                               -baseoid => $dd->oiddef($flowPoolOid) );
520             $devdetails->storeSnmpVars ( $flowModTable );
521
522             # PROG: Look for pool names and indexes and store them.
523             if( $flowModTable ) {
524                 foreach my $flowPoolIDX ( $devdetails->getSnmpIndices(
525                                             $dd->oiddef($flowPoolOid) ) )
526                 {
527                     my $flowPoolName = $flowModTable->{
528                            $dd->oiddef($flowPoolOid) . '.' . $flowPoolIDX};
529
530                     $data->{'arbor_e'}{'flowModule'}{$flowModule}{$flowPoolIDX}
531                           = $flowPoolName;
532
533                     Debug("common:    IDX: $flowPoolIDX  Pool: $flowPoolName");
534
535                 } # END: foreach my $flowPoolIDX
536             } # END: if $flowModTable
537         } # END: foreach my $flowModule
538     }
539
540
541     if( $devdetails->param('Arbor_E::disable-bundle-offer') ne 'yes' )
542     {
543         my $boOfferNameTable = $session->get_table(
544                             -baseoid => $dd->oiddef('boOfferName') );
545         $devdetails->storeSnmpVars( $boOfferNameTable );
546
547         my $boBundleNameTable = $session->get_table(
548                             -baseoid => $dd->oiddef('boBundleName') );
549         $devdetails->storeSnmpVars( $boBundleNameTable );
550
551         if( defined( $boOfferNameTable ) )
552         {
553             $devdetails->setCap('arbor-bundle');
554
555             foreach my $boOfferNameID ( $devdetails->getSnmpIndices(
556                                 $dd->oiddef('boOfferName') ) )
557             {
558                 my ($bundleID,$offerNameID) = split( /\./, $boOfferNameID );
559
560                 my $offerName = $boOfferNameTable->{
561                                     $dd->oiddef('boOfferName')
562                                     . '.' . $boOfferNameID };
563                 my $bundleName = $boBundleNameTable->{
564                                     $dd->oiddef('boBundleName')
565                                     . '.' . $boOfferNameID };
566
567                 $data->{'arbor_e'}{'offerName'}{$offerNameID} = $offerName;
568                 $data->{'arbor_e'}{'bundleName'}{$bundleID}   = $bundleName;
569
570                 push( @{$data->{'arbor_e'}{'boOfferBundle'}{$offerNameID}},
571                       $bundleID );
572             }
573         }
574
575         # PROG: Subscribers using the bundle
576         if( $devdetails->param('Arbor_E::disable-bundle-offer-subcount')
577             ne 'yes' )
578         {
579             my $oidSubcount = $dd->oiddef('boBundleSubCount');
580
581             if( defined $session->get_table( -baseoid => $oidSubcount ) )
582             {
583                 $devdetails->setCap('arbor-bundle-subcount');
584             }
585         }
586
587         # PROG: Packets sent on this bundle with a size
588         if( $devdetails->param('Arbor_E::disable-bundle-offer-pktsize')
589             ne 'yes' )
590         {
591             my $oidPktsize = $dd->oiddef('boPacketsSent64');
592
593             if( defined $session->get_table( -baseoid => $oidPktsize ) )
594             {
595                 $devdetails->setCap('arbor-bundle-pktsize');
596             }
597         }
598
599         # PROG: Bytes sent on this bundle for deny policy drop
600         if( $devdetails->param('Arbor_E::disable-bundle-offer-deny')
601             ne 'yes' )
602         {
603             my $oidDenypolicy = $dd->oiddef('boBundleBytesSentDenyPolicyDrop');
604
605             if( defined $session->get_table( -baseoid => $oidDenypolicy ) )
606             {
607                 $devdetails->setCap('arbor-bundle-deny');
608             }
609         }
610
611         # PROG: Bytes sent on this bundle for rate limit drop
612         if( $devdetails->param('Arbor_E::disable-bundle-offer-rate')
613             ne 'yes' )
614         {
615             my $oidRatelimit = $dd->oiddef('boBundleBytesSentRateLimitDrop');
616
617             if( defined $session->get_table( -baseoid => $oidRatelimit ) )
618             {
619                 $devdetails->setCap('arbor-bundle-ratelimit');
620             }
621         }
622     }
623
624     return 1;
625 }
626
627
628 sub buildConfig
629 {
630     my $devdetails = shift;
631     my $cb = shift;
632     my $devNode = shift;
633     my $data = $devdetails->data();
634
635     # PROG: Lets do e30 first ...
636     if( $devdetails->hasCap('e30') )
637     {
638         # e30 buffer information
639         if( $devdetails->hasCap('e30-buffers') )
640         {
641             $cb->addTemplateApplication($devNode, 'Arbor_E::e30-buffers');
642         }
643
644         if( $devdetails->hasCap('e30-bundle') )
645         {
646             # Create topLevel subtree
647             my $bundleNode = $cb->addSubtree( $devNode, 'Bundle_Stats',
648                                     { 'comment' => 'Bundle statistics' },
649                                     [ 'Arbor_E::e30-bundle-subtree' ] );
650
651             foreach my $bundleID
652                 ( sort {$a <=> $b} keys %{$data->{'e30'}{'bundleID'} } )
653             {
654                 my $srvName     =  $data->{'e30'}{'bundleID'}{$bundleID};
655                 my $subtreeName =  $srvName;
656                    $subtreeName =~ s/\W/_/g; 
657                 my $bundleRRD   = $bundleID;
658                 my @templates   = ( 'Arbor_E::e30-bundle' );
659
660                 if( $devdetails->param('Arbor_E::enable-e30-bundle-name-rrd')
661                     eq 'yes' )
662                 {
663                     # Filenames written out as the bundle name
664                     $bundleRRD =  lc($srvName);
665                     $bundleRRD =~ s/\W/_/g;
666                 }
667
668                 if( $devdetails->hasCap('e30-bundle-denyStats') )
669                 {
670                     push( @templates, 'Arbor_E::e30-bundle-deny' );
671                 }
672
673                 if( $devdetails->hasCap('e30-bundle-rateLimitStats') )
674                 {
675                     push( @templates, 'Arbor_E::e30-bundle-ratelimit' );
676                 }
677
678                 $cb->addSubtree( $bundleNode, $subtreeName,
679                                  { 'comment'          => $srvName,
680                                    'e30-bundle-index' => $bundleID,
681                                    'e30-bundle-name'  => $srvName,
682                                    'e30-bundle-rrd'   => $bundleRRD,
683                                    'precedence'       => 1000 - $bundleID },
684                                  \@templates );
685             } # END foreach my $bundleID
686         }
687
688         # e30 cpu
689         if( $devdetails->hasCap('e30-cpu') )
690         {
691             $cb->addTemplateApplication($devNode, 'Arbor_E::e30-cpu');
692         }
693
694         # e30 forwarding table
695         if( $devdetails->hasCap('e30-fwdTable') )
696         {
697             $cb->addTemplateApplication($devNode, 'Arbor_E::e30-fwdTable');
698
699             if( $devdetails->hasCap('e30-fwdTable-login') )
700             {
701                 my $subtree  = "Forwarding_Table_Login_Stats";
702                 my $comment  = "Discovery attempts statistics";
703                 my $nodeTree = $cb->addSubtree( $devNode, $subtree, 
704                                               { 'comment' => $comment },
705                                                 undef );
706
707                 my @colors =
708                     ('##one', '##two', '##three', '##four', '##five',
709                      '##six', '##seven', '##eight', '##nine', '##ten'
710                     );
711
712                 my $multiParam = {
713                     'precedence'        => 1000,
714                     'comment'           => 'Summary of login attempt responses',
715                     'graph-lower-limit' => 0,
716                     'graph-title'       => 'Summary of login attempt responses',
717                     'rrd-hwpredict'     => 'disabled',
718                     'vertical-label'    => 'Responses',
719                     'ds-type'           => 'rrd-multigraph'
720                     };
721                 my $dsList;
722
723                 foreach my $sindex ( sort { $a <=> $b } 
724                                      @{$data->{'e30'}{'loginResp'}} )
725                 {
726                 
727                     $cb->addLeaf( $nodeTree, 'Login_' . $sindex,
728                                 { 'comment'    => 'Login attempt #' . $sindex,
729                                   'login-idx'  => $sindex,
730                                   'precedence' => 100 - $sindex },
731                                 [ 'Arbor_E::e30-fwdTable-login' ] );
732
733                     # Addition for multi-graph
734                     my $dsName  = "Login_$sindex";
735                     my $color   = shift @colors;
736                        $dsList .= $dsName . ',';
737
738                     $multiParam->{"ds-expr-$dsName"}      = "{$dsName}";
739                     $multiParam->{"graph-legend-$dsName"} = "Attempt $sindex";
740                     $multiParam->{"line-style-$dsName"}   = "LINE1";
741                     $multiParam->{"line-color-$dsName"}   = $color;
742                     $multiParam->{"line-order-$dsName"}   = $sindex;
743
744                     Debug("  loginReps: $sindex, color: $color");
745                 } # END: foreach $sindex
746
747                 $dsList =~ s/,$//o;     # Remove final comma
748                 $multiParam->{'ds-names'} = $dsList;
749
750                 $cb->addLeaf($nodeTree, 'Summary', $multiParam, undef );
751
752             } # END: hasCap e30-fwdTable-login
753         } # END: hasCap e30-fwdTable
754
755         # e30 hard drive
756         if( $devdetails->hasCap('e30-hdd') )
757         {
758             my $comment = "Model: "  . $data->{'e30'}{'hddModel'} . ", " .
759                           "Serial: " . $data->{'e30'}{'hddSerial'};
760             my $subtree = "Hard_Drive";
761             my @templates;
762             push( @templates, 'Arbor_E::e30-hdd-subtree' );
763             push( @templates, 'Arbor_E::e30-hdd' );
764
765             # PROG: Process hdd errors
766             if( $devdetails->hasCap('e30-hdd-errors') )
767             {
768                 push( @templates, 'Arbor_E::e30-hdd-errors' );
769             }
770
771             # PROG: Process hdd daily logs
772             if( $devdetails->hasCap('e30-hdd-logs') )
773             {
774                 push( @templates, 'Arbor_E::e30-hdd-logs' );
775             }
776
777             my $hdNode = $cb->addSubtree($devNode, $subtree,
778                                         { 'comment' => $comment },
779                                         \@templates);
780         }
781
782         # e30 L2TP tunnel information
783         if( $devdetails->hasCap('e30-l2tp') )
784         {
785             # PROG: First add the appropriate template
786             my $l2tpNode = $cb->addSubtree( $devNode, 'L2TP', undef,
787                                           [ 'Arbor_E::e30-l2tp-subtree' ]);
788
789             # PROG: Cycle through the SECURE EndPoint devices
790             if( $data->{'e30'}{'l2tpSEP'} )
791             {
792                 # PROG: Add the assisting template first
793                 my $l2tpEndNode = $cb->addSubtree( $l2tpNode, 'Secure_Endpoint',
794                              { 'comment' => 'Secure endpoint parties' },
795                              [ 'Arbor_E::e30-l2tp-secure-endpoints-subtree' ] );
796
797                 foreach my $SEP ( keys %{$data->{'e30'}{'l2tpSEP'}} )
798                 {
799                   my $endPoint =  $SEP;
800                      $endPoint =~ s/\W/_/g;
801
802                   $cb->addSubtree($l2tpEndNode, $endPoint,
803                               { 'e30-l2tp-ep'   => $SEP,
804                                 'e30-l2tp-file' => $endPoint },
805                               [ 'Arbor_E::e30-l2tp-secure-endpoints-leaf' ]);
806                 } # END: foreach
807             }
808         }
809
810         # e30 memory
811         if( $devdetails->hasCap('e30-mem') )
812         {
813             $cb->addTemplateApplication($devNode, 'Arbor_E::e30-mem');
814         }
815
816         # e30 memory pool
817         if( $devdetails->hasCap('e30-mempool') )
818         {
819             my $subtreeName = "Memory_Pool";
820             my $param       = { 'comment' => 'Memory Pool Statistics' };
821             my $templates   = [ 'Arbor_E::e30-mempool-subtree' ];
822             my $memIndex    = $data->{'e30'}{'mempool'};
823
824             my $nodeTop     = $cb->addSubtree( $devNode, $subtreeName,
825                                                $param, $templates );
826
827             foreach my $memIDX ( keys %{$memIndex} )
828             {
829                 my $leafName = $memIndex->{$memIDX};
830                 my $dataFile = "%snmp-host%_mempool_" . $leafName . '.rrd';
831
832                 my $nodeMem = $cb->addSubtree( $nodeTop, $leafName, 
833                                             { 'data-file'         => $dataFile,
834                                               'e30-mempool-index' => $memIDX,
835                                               'e30-mempool-name'  => $leafName
836                                             },
837                                             [ 'Arbor_E::e30-mempool' ] );
838             }
839         }
840
841         # e30 slowpath counters
842         if( $devdetails->hasCap('e30-slowpath') )
843         {
844             my $slowNode = $cb->addSubtree( $devNode, 'SlowPath', undef,
845                                           [ 'Arbor_E::e30-slowpath' ] );
846         }
847     } # END: if e30 device
848
849
850     # -----------------------------------------------------
851     #
852     # E100 series...
853
854     if( $devdetails->hasCap('e100') )
855     {
856         # CPU: per-cpu information
857         if( $devdetails->hasCap('e100-cpu') )
858         {
859             my @colors  = ( '##one', '##two', '##three', '##four', '##five',
860                             '##six', '##seven', '##eight', '##nine', '##ten'
861                           );
862             my $subtree = "CPU_Usage";
863             my $cpuTree = $cb->addSubtree( $devNode, $subtree, undef,
864                                          [ 'Arbor_E::e100-cpu-subtree' ] );
865             my $multiParam = {
866                 'precedence'        => 1000,
867                 'comment'           => 'Summary of all CPU utilization',
868                 'graph-lower-limit' => 0,
869                 'graph-title'       => 'Summary of all CPU utilization',
870                 'rrd-hwpredict'     => 'disabled',
871                 'vertical-label'    => 'Percent',
872                 'ds-type'           => 'rrd-multigraph'
873                 };
874             my $dsList;
875
876             foreach my $cpuIndex ( sort keys %{$data->{'e100'}{'cpu'}} )
877             {
878                 my $cpuName = $data->{'e100'}{'cpu'}{$cpuIndex};
879   
880                 # Is there proper desc for the CPU index?
881                 my $comment;
882                 if( $eCpuName{$cpuIndex} )
883                 {
884                     $comment = $eCpuName{$cpuIndex};
885                 } else {
886                     $comment = "CPU: $cpuName";
887                 }
888   
889                 $cb->addLeaf( $cpuTree, $cpuName,
890                             { 'comment'    => $comment,
891                               'cpu-index'  => $cpuIndex,
892                               'cpu-name'   => $cpuName,
893                               'precedence' => 1000 - $cpuIndex },
894                             [ 'Arbor_E::e100-cpu' ] );
895   
896                 # Multi-graph additions
897                 my $color   = shift @colors;
898                    $dsList .= $cpuName . ',';
899                 $multiParam->{"ds-expr-$cpuName"}      = "{$cpuName}";
900                 $multiParam->{"graph-legend-$cpuName"} = "$cpuName";
901                 $multiParam->{"line-style-$cpuName"}   = "LINE1";
902                 $multiParam->{"line-color-$cpuName"}   = $color;
903                 $multiParam->{"line-order-$cpuName"}   = $cpuIndex;
904             } # END: foreach $cpuIndex
905
906             $dsList =~ s/,$//o;     # Remove final comma
907             $multiParam->{'ds-names'} = $dsList;
908             $cb->addLeaf($cpuTree, 'Summary', $multiParam, undef );
909
910         } # END: hasCap e100-cpu
911
912         # HDD: Partition sizes / usage
913         if( $devdetails->hasCap('e100-hdd') )
914         {
915             my $subtree = "HDD_Usage";
916             my $hddTree = $cb->addSubtree( $devNode, $subtree, undef,
917                                          [ 'Arbor_E::e100-hdd-subtree' ] );
918
919             foreach my $hddIndex ( sort keys %{$data->{'e100'}{'hdd'}} )
920             {
921               my $hddName = $data->{'e100'}{'hdd'}{$hddIndex};
922               $cb->addSubtree( $hddTree, $hddName,
923                              { 'comment'    => 'HDD: ' . $hddName,
924                                'hdd-index'  => $hddIndex,
925                                'hdd-name'   => $hddName,
926                                'precedence' => 1000 - $hddIndex },
927                              [ 'Arbor_E::e100-hdd' ] );
928             }
929         }
930
931         # MEM: per-cpu memory usage
932         if( $devdetails->hasCap('e100-mem') )
933         {
934             my $subtree = "Memory_Usage";
935             my $memTree = $cb->addSubtree( $devNode, $subtree, undef,
936                                          [ 'Arbor_E::e100-mem-subtree' ] );
937             foreach my $memIndex ( sort keys %{$data->{'e100'}{'mem'}} )
938             {
939               my $memName = $data->{'e100'}{'cpu'}{$memIndex};
940
941               my $comment = "Memory for $memName CPU";
942               $cb->addSubtree( $memTree, $memName,
943                              { 'comment'    => $comment,
944                                'mem-index'  => $memIndex,
945                                'mem-name'   => $memName,
946                                'precedence' => 1000 - $memIndex },
947                              [ 'Arbor_E::e100-mem' ] );
948             }
949         }
950
951         # PolicyMmgt: Information regarding delta, service bundles, subnets
952         if( $devdetails->hasCap('e100-policymgmt') )
953         {
954             $cb->addTemplateApplication($devNode, 'Arbor_E::e100-policymgmt');
955         }
956
957         # SubscriberMgmt: Information regarding subscriber counts, states, etc.
958         if( $devdetails->hasCap('e100-submgmt') )
959         {
960             my $subMgmtTree = $cb->addSubtree( $devNode, 'Subscribers', undef,
961                                       [ 'Arbor_E::e100-submgmt-subtree' ]
962                              );
963
964             my $stateTree  = $cb->addSubtree( $subMgmtTree, 'Subscriber_State',
965                                         undef,
966                                       [ 'Arbor_E::e100-submgmt-state-subtree' ]
967                              );
968
969             # State: Multigraph display
970             my @colors =
971                 ('##one', '##two', '##three', '##four', '##five',
972                  '##six', '##seven', '##eight', '##nine', '##ten'
973                 );
974             my $multiParam = {
975                 'precedence'        => 1000,
976                 'graph-lower-limit' => 0,
977                 'graph-title'       => 'Summary of subscriber states',
978                 'rrd-hwpredict'     => 'disabled',
979                 'vertical-label'    => 'Subscribers',
980                 'comment'           => 'Summary of all states',
981                 'ds-type'           => 'rrd-multigraph'
982             };
983             my $dsList;
984
985             foreach my $stateIDX ( sort keys %{$data->{'e100'}{'submgmt'}} )
986             {
987                 my $color        =  shift @colors;
988                 my $stateName    =  $data->{'e100'}{'submgmt'}{$stateIDX};
989                 my $stateNameRRD =  $stateName;
990                    $stateNameRRD =~ s/[^a-zA-Z_]/_/o;
991
992                 my $stateNode = $cb->addLeaf( $stateTree, $stateName,
993                                    { 'comment'    => "State: $stateName",
994                                      'state-idx'  => $stateIDX,
995                                      'state-name' => $stateName,
996                                      'state-rrd'  => $stateNameRRD,
997                                      'precedence' => 100 - $stateIDX },
998                                    [ 'Arbor_E::e100-submgmt-state' ] );
999                 $dsList .= $stateName . ',';
1000
1001                 $multiParam->{"ds-expr-$stateName"}      = "{$stateName}";
1002                 $multiParam->{"graph-legend-$stateName"} = "$stateName";
1003                 $multiParam->{"line-style-$stateName"}   = "LINE1";
1004                 $multiParam->{"line-color-$stateName"}   = $color,
1005                 $multiParam->{"line-order-$stateName"}   = $stateIDX;
1006             }
1007             $dsList =~ s/,$//o;
1008             $multiParam->{'ds-names'} = $dsList;
1009
1010             $cb->addLeaf($stateTree, 'Summary', $multiParam, undef );
1011
1012         }
1013     }
1014
1015     # -------------------------------------------------------------------------
1016     #
1017     # Common information between e30 and e100
1018
1019     if( $devdetails->hasCap('arbor-bundle') )
1020     {
1021         my $subtreeName = "Bundle_Offer_Stats";
1022         my $param       = { 'comment'    => 'Byte counts for each bundle ' . 
1023                                             'per Offer' };
1024         my $templates   = [ ];
1025         my $nodeTop     = $cb->addSubtree( $devNode, $subtreeName,
1026                                            $param, $templates );
1027
1028         foreach my $offerNameID ( keys %{$data->{'arbor_e'}{'offerName'}} )
1029         {
1030             my $offerName   =  $data->{'arbor_e'}{'offerName'}{$offerNameID};
1031                $offerName   =~ s/\W/_/g;
1032             my $offerBundle =  $data->{'arbor_e'}{'boOfferBundle'};
1033             my $offerRRD    =  $offerNameID;
1034
1035             if( $devdetails->param('Arbor_E::enable-bundle-name-rrd')
1036                 eq 'yes' )
1037             {
1038                 # Filename will now be written as offer name
1039                 $offerRRD = lc($offerName);
1040             }
1041
1042             # Build tree
1043             my $oparam = { 'comment'   => 'Offer: ' . $offerName,
1044                            'offer-id'  => $offerNameID,
1045                            'offer-rrd' => $offerRRD };
1046             my $otemplates = [ 'Arbor_E::arbor-bundle-subtree' ];
1047             my $offerTop = $cb->addSubtree( $nodeTop, $offerName, $oparam,
1048                                             $otemplates );
1049
1050             Debug("    Offer: $offerName");
1051
1052             foreach my $bundleID ( @{%{$offerBundle}->{$offerNameID}} )
1053             {
1054                 my @btemplates;
1055                 my $bundleName =  $data->{'arbor_e'}{'bundleName'}{$bundleID};
1056                    $bundleName =~ s/\W/_/g;
1057                 my $bundleRRD  =  $bundleID;
1058
1059                 Debug("      $bundleID: $bundleName");
1060
1061                 if( $devdetails->param('Arbor_E::enable-bundle-name-rrd')
1062                     eq 'yes' )
1063                 {
1064                     # Filename will now be written as bundle name
1065                     $bundleRRD = lc($bundleName);
1066                 }
1067
1068                 my $bparam     = { 'comment'     => 'Bundle ID: ' . $bundleID,
1069                                    'data-file'   => '%system-id%_bo_' .
1070                                                     '%offer-rrd%_' .
1071                                                     '%bundle-rrd%.rrd',
1072                                    'bundle-id'   => $bundleID,
1073                                    'bundle-name' => $bundleName,
1074                                    'bundle-rrd'  => $bundleRRD };
1075                 push( @btemplates, 'Arbor_E::arbor-bundle' );
1076
1077                 # PROG: Subscribers using the bundle
1078                 if( $devdetails->hasCap('arbor-bundle-subcount') )
1079                 {
1080                     push( @btemplates, 'Arbor_E::arbor-bundle-subcount' );
1081                 }
1082
1083                 # PROG: Packets sent on this bundle per size
1084                 if( $devdetails->hasCap('arbor-bundle-pktsize') )
1085                 {
1086                     push( @btemplates, 'Arbor_E::arbor-bundle-pktsize' );
1087                 }
1088
1089                 # PROG: Bytes sent on this bundle for deny policy drop
1090                 if( $devdetails->hasCap('arbor-bundle-deny') )
1091                 {
1092                     push( @btemplates, 'Arbor_E::arbor-bundle-deny' );
1093                 }
1094
1095                 # PROG: Bytes sent on this bundle for rate limit drop
1096                 if( $devdetails->hasCap('arbor-bundle-ratelimit') )
1097                 {
1098                     push( @btemplates, 'Arbor_E::arbor-bundle-ratelimit' );
1099                 }
1100
1101                 # Build tree
1102                 $cb->addSubtree( $offerTop, $bundleName,
1103                                  $bparam, \@btemplates );
1104             } # END: foreach $bundleID
1105         } # END: foreach $offerNameID
1106     } # END: hasCap arbor-bundle
1107
1108     # Flow device lookups
1109     if( $devdetails->hasCap('arbor-flowLookup') )
1110     {
1111         # PROG: Flow Lookup Device (pool names)
1112         my $flowNode = $cb->addSubtree( $devNode, 'Flow_Lookup',
1113                                       { 'comment' => 'Switching modules' },
1114                                         undef );
1115
1116         my $flowLookup = $data->{'arbor_e'}{'flowModule'};
1117
1118         foreach my $flowDevIdx ( keys %{$flowLookup} )
1119         {
1120             my $flowNodeDev = $cb->addSubtree( $flowNode,
1121                               'Flow_Lookup_' .  $flowDevIdx,
1122                               { 'comment' => 'Switching module '
1123                                               . $flowDevIdx },
1124                               [ 'Arbor_E::arbor-flowlkup-subtree' ] );
1125
1126             # PROG: Find all the pool names and add Subtree
1127             foreach my $flowPoolIdx ( keys %{$flowLookup->{$flowDevIdx}} )
1128             {
1129                 my $poolName = $flowLookup->{$flowDevIdx}{$flowPoolIdx};
1130
1131                 my $poolNode = $cb->addSubtree( $flowNodeDev, $poolName,
1132                                { 'comment'        => 'Flow Pool: ' . $poolName,
1133                                  'flowdev-index'  => $flowDevIdx,
1134                                  'flowpool-index' => $flowPoolIdx,
1135                                  'flowpool-name'  => $poolName,
1136                                  'precedence'     => 1000 - $flowPoolIdx},
1137                                [ 'Arbor_E::arbor-flowlkup-leaf' ] );
1138             } # END: foreach my $flowPoolIdx
1139         } # END: foreach my $flowDevIdx
1140     } # END: hasCap arbor-flowLookup
1141
1142 }
1143
1144 1;
1145
1146 # Local Variables:
1147 # mode: perl
1148 # indent-tabs-mode: nil
1149 # perl-indent-level: 4
1150 # End: