import torrus 1.0.9
[freeside.git] / torrus / perllib / Torrus / DevDiscover / FTOS.pm
1 #
2 #  Copyright (C) 2009  Jon Nistor
3 #
4 #  This program is free software; you can redistribute it and/or modify
5 #  it under the terms of the GNU General Public License as published by
6 #  the Free Software Foundation; either version 2 of the License, or
7 #  (at your option) any later version.
8 #
9 #  This program is distributed in the hope that it will be useful,
10 #  but WITHOUT ANY WARRANTY; without even the implied warranty of
11 #  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12 #  GNU General Public License for more details.
13 #
14 #  You should have received a copy of the GNU General Public License
15 #  along with this program; if not, write to the Free Software
16 #  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
17
18 # $Id: FTOS.pm,v 1.1 2010-12-27 00:03:54 ivan Exp $
19 # Jon Nistor <nistor at snickers.org>
20
21 # Force10 Networks Real Time Operating System Software
22 #
23 # NOTE: FTOS::disable-cpu
24 #       FTOS::disable-power
25 #       FTOS::disable-temperature
26 #       FTOS::use-fahrenheit
27 #       FTOS::file-per-sensor (affects both power and temperature)
28
29 package Torrus::DevDiscover::FTOS;
30
31 use strict;
32 use Torrus::Log;
33
34 $Torrus::DevDiscover::registry{'FTOS'} = {
35     'sequence'     => 500,
36     'checkdevtype' => \&checkdevtype,
37     'discover'     => \&discover,
38     'buildConfig'  => \&buildConfig
39     };
40
41
42 our %oiddef =
43     (
44      # FORCE10-SMI
45      'f10Products'           => '1.3.6.1.4.1.6027.1',
46
47      # F10-CHASSIS-MIB
48      'chType'                => '1.3.6.1.4.1.6027.3.1.1.1.1.0',
49      'chSerialNumber'        => '1.3.6.1.4.1.6027.3.1.1.1.2.0',
50      'chSysPowerSupplyIndex' => '1.3.6.1.4.1.6027.3.1.1.2.1.1.1',
51      'chSysCardSlotIndex'    => '1.3.6.1.4.1.6027.3.1.1.2.3.1.1',
52      'chSysCardNumber'       => '1.3.6.1.4.1.6027.3.1.1.2.3.1.3',
53      'chRpmCpuIndex'         => '1.3.6.1.4.1.6027.3.1.1.3.7.1.1',
54
55      # FORCE10-SYSTEM-COMPONENT-MIB
56      'camUsagePartDesc'      => '1.3.6.1.4.1.6027.3.7.1.1.1.1.4'
57      );
58
59
60 our %f10ChassisType =
61     (
62      '1'   => 'Force10 E1200 16-slot switch/router',
63      '2'   => 'Force10 E600 9-slot switch/router',
64      '3'   => 'Force10 E300 8-slot switch/router',
65      '4'   => 'Force10 E150 8-slot switch/router',
66      '5'   => 'Force10 E610 9-slot switch/router',
67      '6'   => 'Force10 C150 6-slot switch/router',
68      '7'   => 'Force10 C300 10-slot switch/router',
69      '8'   => 'Force10 E1200i 16-slot switch/router',
70      '9'   => 'Force10 S2410 10GbE switch',
71      '10'  => 'Force10 S2410 10GbE switch',
72      '11'  => 'Force10 S50 access switch',
73      '12'  => 'Force10 S50e access switch',
74      '13'  => 'Force10 S50v access switch',
75      '14'  => 'Force10 S50nac access switch',
76      '15'  => 'Force10 S50ndc access switch',
77      '16'  => 'Force10 S25pdc access switch',
78      '17'  => 'Force10 S25pac access switch',
79      '18'  => 'Force10 S25v access switch',
80      '19'  => 'Force10 S25n access switch'
81      );
82
83 our %f10CPU =
84     (
85      '1'   => 'Control Processor',
86      '2'   => 'Routing Processor #1',
87      '3'   => 'Routing Processor #2'
88      );
89
90
91 # Not all interfaces are normally needed to monitor.
92 # You may override the interface filtering in devdiscover-siteconfig.pl:
93 # redefine $Torrus::DevDiscover::FTOS::interfaceFilter
94 # or define $Torrus::DevDiscover::FTOS::interfaceFilterOverlay
95
96 our $interfaceFilter;
97 our $interfaceFilterOverlay;
98 my %ftosInterfaceFilter;
99
100 if( not defined( $interfaceFilter ) )
101 {
102     $interfaceFilter = \%ftosInterfaceFilter;
103 }
104
105
106 # Key is some unique symbolic name, does not mean anything
107 #  ifType is the number to match the interface type
108 # ifDescr is the regexp to match the interface description
109 %ftosInterfaceFilter =
110     (
111      'other' => {
112          'ifType'  => 1,                     # other
113      },
114      'loopback' => {
115          'ifType'  => 24,                    # softwareLoopback
116      },
117      
118      );
119
120
121 sub checkdevtype
122 {
123     my $dd = shift;
124     my $devdetails = shift;
125
126     if( not $dd->oidBaseMatch
127         ( 'f10Products',
128           $devdetails->snmpVar( $dd->oiddef('sysObjectID') ) ) )
129     {
130         return 0;
131     }
132     
133     # Systems running FTOS will have chassisType, SFTOS will not.
134     if( not $dd->checkSnmpOID('chType') )
135     {
136         return 0;
137     }
138     
139     &Torrus::DevDiscover::RFC2863_IF_MIB::addInterfaceFilter
140         ($devdetails, $interfaceFilter);
141     
142     if( defined( $interfaceFilterOverlay ) )
143     {
144         &Torrus::DevDiscover::RFC2863_IF_MIB::addInterfaceFilter
145             ($devdetails, $interfaceFilterOverlay);
146     }
147
148     $devdetails->setCap('interfaceIndexingPersistent');
149
150     return 1;
151 }
152
153
154 sub discover
155 {
156     my $dd = shift;
157     my $devdetails = shift;
158
159     my $session = $dd->session();
160     my $data = $devdetails->data();
161
162     # NOTE: Comments and Serial number of device
163     my $chassisSerial = $dd->retrieveSnmpOIDs( 'chType', 'chSerialNumber' );
164
165     if( defined( $chassisSerial ) )
166     {
167         $data->{'param'}{'comment'} =
168             %f10ChassisType->{$chassisSerial->{'chType'}} .
169             ', Hw Serial#: ' . $chassisSerial->{'chSerialNumber'};
170     }
171     else
172     {
173         $data->{'param'}{'comment'} = "Force10 Networks switch/router";
174     }
175
176     # PROG: CPU statistics
177     if( $devdetails->param('FTOS::disable-cpu') ne 'yes' )
178     {
179         # Poll table to translate the CPU Index to a Name
180         my $ftosCpuTable =
181             $session->get_table( -baseoid => $dd->oiddef('chRpmCpuIndex') );
182
183         $devdetails->storeSnmpVars( $ftosCpuTable );
184
185         if( defined( $ftosCpuTable ) )
186         {
187             $devdetails->setCap('ftosCPU');
188
189             # Find the index of the CPU
190             foreach my $ftosCPUidx ( $devdetails->getSnmpIndices
191                                      ( $dd->oiddef('chRpmCpuIndex') ) )
192             {
193                 my $cpuType = $dd->oiddef('chRpmCpuIndex') . "." . $ftosCPUidx;
194                 my $cpuName = %f10CPU->{$ftosCpuTable->{$cpuType}};
195
196                 Debug("FTOS::CPU index $ftosCPUidx, $cpuName");
197
198                 # Construct the data ...
199                 $data->{'ftosCPU'}{$ftosCPUidx} = $cpuName;
200             }
201         }
202         else
203         {
204             Debug("FTOS::CPU No CPU information found, old sw?");
205         }
206     } # END: CPU
207
208
209     # PROG: Power Supplies
210     if( $devdetails->param('FTOS::disable-power') ne 'yes' )
211     {
212         # Poll table of power supplies
213         my $ftosPSUTable =
214             $session->get_table( -baseoid =>
215                                  $dd->oiddef('chSysPowerSupplyIndex') );
216
217         $devdetails->storeSnmpVars( $ftosPSUTable );
218
219         if( defined( $ftosPSUTable ) )
220         {
221             $devdetails->setCap('ftosPSU');
222
223             # Find the Index of the Power Supplies
224             foreach my $ftosPSUidx ( $devdetails->getSnmpIndices
225                                      ($dd->oiddef('chSysPowerSupplyIndex')) )
226             {
227                 Debug("FTOS::PSU index $ftosPSUidx");
228
229                 push( @{$data->{'ftosPSU'}}, $ftosPSUidx );
230             }
231         }
232     } # END: PSU
233
234
235     # PROG: Temperature
236     if( $devdetails->param('FTOS::disable-sensors') ne 'yes' )
237     {
238         # Check if temperature sensors are supported
239         my $sensorTable =
240             $session->get_table( -baseoid =>
241                                  $dd->oiddef('chSysCardSlotIndex') );
242         $devdetails->storeSnmpVars( $sensorTable );
243
244         my $sensorCard =
245             $session->get_table( -baseoid => $dd->oiddef('chSysCardNumber') );
246         $devdetails->storeSnmpVars( $sensorCard );
247
248
249         if( defined( $sensorTable ) )
250         {
251             $devdetails->setCap('ftosSensor');
252             
253             foreach my $sensorIdx ( $devdetails->getSnmpIndices
254                                     ( $dd->oiddef('chSysCardSlotIndex') ) )
255             {
256                 my $sensorCard =
257                     $devdetails->snmpVar( $dd->oiddef('chSysCardNumber') .
258                                           '.' . $sensorIdx );
259
260                 $data->{'ftosSensor'}{$sensorIdx} = $sensorCard;
261
262                 Debug("FTOS::Sensor index $sensorIdx, card $sensorCard");
263             }
264         } # END if: $sensorTable
265     } # END: disable-sensors
266
267
268     return 1;
269 }
270
271
272 sub buildConfig
273 {
274     my $devdetails = shift;
275     my $cb = shift;
276     my $devNode = shift;
277     my $data = $devdetails->data();
278
279
280     # PROG: CPU processing
281     if( $devdetails->hasCap('ftosCPU') )
282     {
283         my $nodeTop = $cb->addSubtree( $devNode, 'CPU_Usage', undef,
284                                        [ 'FTOS::ftos-cpu-subtree'] );
285
286         foreach my $CPUidx ( sort {$a <=> $b} keys %{$data->{'ftosCPU'}} )
287         {
288             my $CPUName = $data->{'ftosCPU'}{$CPUidx};
289             my $subName = sprintf( 'CPU_%.2d', $CPUidx );
290
291             my $nodeCPU = $cb->addSubtree( $nodeTop, $subName,
292                                            { 'comment'   => $CPUName,
293                                              'cpu-index' => $CPUidx,
294                                              'cpu-name'  => $CPUName },
295                                            [ 'FTOS::ftos-cpu' ] );
296         }
297     } # END if ftosCPU
298
299
300     # PROG: Power supplies
301     if( $devdetails->hasCap('ftosPSU') )
302     {
303         my $subtreeName = "Power_Supplies";
304         my $param       = { 'comment'    => 'Power supplies status',
305                             'precedence' => -600 };
306         my $filePerSensor 
307             = $devdetails->param('FTOS::file-per-sensor') eq 'yes';
308         my $templates   = [];
309
310         $param->{'data-file'} = '%snmp-host%_power' .
311             ($filePerSensor ? '_%power-index%':'') .
312             '.rrd';
313
314         my $nodeTop = $cb->addSubtree( $devNode, $subtreeName,
315                                        $param, $templates );
316
317
318         foreach my $PSUidx ( sort {$a <=> $b} @{$data->{'ftosPSU'}} )
319         {
320             my $leafName = sprintf( 'power_%.2d', $PSUidx );
321
322             my $nodePSU = $cb->addLeaf( $nodeTop, $leafName, 
323                                         { 'power-index' => $PSUidx },
324                                         [ 'FTOS::ftos-power-supply-leaf' ]);
325         }
326     }
327
328
329     # PROG: Temperature sensors
330     if( $devdetails->hasCap('ftosSensor') )
331     {
332         my $subtreeName = "Temperature_Sensors";
333         my $param       = {};
334         my $fahrenheit  = $devdetails->param('FTOS::use-fahrenheit') eq 'yes';
335         my $filePerSensor 
336             = $devdetails->param('FTOS::file-per-sensor') eq 'yes';
337         my $templates   = [ 'FTOS::ftos-temperature-subtree' ];
338
339         $param->{'data-file'} = '%snmp-host%_sensors' .
340             ($filePerSensor ? '_%sensor-index%':'') .
341             ($fahrenheit ? '_fahrenheit':'') . '.rrd';
342
343         my $subtreeNode = $cb->addSubtree( $devNode, $subtreeName,
344                                            $param, $templates );
345
346         foreach my $sIndex ( sort {$a<=>$b} keys %{$data->{'ftosSensor'}} )
347         {
348             my $leafName   = sprintf( 'sensor_%.2d', $sIndex );
349             my $threshold  = 60;  # Forced value for the time being, 60 degC
350             my $sensorCard = $data->{'ftosSensor'}{$sIndex};
351
352             if( $fahrenheit )
353             {
354                 $threshold = $threshold * 1.8 + 32;
355             }
356
357             my $param = {
358                 'sensor-index'       => $sIndex,
359                 'sensor-description' => 'Module ' . $sensorCard,
360                 'upper-limit'        => $threshold
361                 };
362
363             my $templates = ['FTOS::ftos-temperature-sensor' .
364                              ($fahrenheit ? '-fahrenheit':'')];
365
366             $cb->addLeaf( $subtreeNode, $leafName, $param, $templates );
367         } 
368     }
369 }
370
371
372 1;
373
374 # Local Variables:
375 # mode: perl
376 # indent-tabs-mode: nil
377 # perl-indent-level: 4
378 # End: