import torrus 1.0.9
[freeside.git] / torrus / perllib / Torrus / DevDiscover / CiscoGeneric.pm
1 #  Copyright (C) 2002  Stanislav Sinyagin
2 #
3 #  This program is free software; you can redistribute it and/or modify
4 #  it under the terms of the GNU General Public License as published by
5 #  the Free Software Foundation; either version 2 of the License, or
6 #  (at your option) any later version.
7 #
8 #  This program is distributed in the hope that it will be useful,
9 #  but WITHOUT ANY WARRANTY; without even the implied warranty of
10 #  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
11 #  GNU General Public License for more details.
12 #
13 #  You should have received a copy of the GNU General Public License
14 #  along with this program; if not, write to the Free Software
15 #  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
16
17 # $Id: CiscoGeneric.pm,v 1.1 2010-12-27 00:03:48 ivan Exp $
18 # Stanislav Sinyagin <ssinyagin@yahoo.com>
19
20 # Common Cisco MIBs, supported by many IOS and CatOS devices
21
22 package Torrus::DevDiscover::CiscoGeneric;
23
24 use strict;
25 use Torrus::Log;
26
27
28 $Torrus::DevDiscover::registry{'CiscoGeneric'} = {
29     'sequence'     => 500,
30     'checkdevtype' => \&checkdevtype,
31     'discover'     => \&discover,
32     'buildConfig'  => \&buildConfig
33     };
34
35
36 our %oiddef =
37     (
38      # CISCO-SMI
39      'cisco'                             => '1.3.6.1.4.1.9',
40
41      # CISCO-ENVMON-MIB
42      'ciscoEnvMonTemperatureStatusDescr' => '1.3.6.1.4.1.9.9.13.1.3.1.2',
43      'ciscoEnvMonTemperatureStatusValue' => '1.3.6.1.4.1.9.9.13.1.3.1.3',
44      'ciscoEnvMonTemperatureThreshold'   => '1.3.6.1.4.1.9.9.13.1.3.1.4',
45      'ciscoEnvMonTemperatureStatusState' => '1.3.6.1.4.1.9.9.13.1.3.1.6',
46      'ciscoEnvMonSupplyState'            => '1.3.6.1.4.1.9.9.13.1.5.1.3',
47
48      # CISCO-ENHANCED-MEMPOOL-MIB
49      'cempMemPoolName'                   => '1.3.6.1.4.1.9.9.221.1.1.1.1.3',
50      
51      # CISCO-MEMORY-POOL-MIB
52      'ciscoMemoryPoolName'               => '1.3.6.1.4.1.9.9.48.1.1.1.2',
53
54      # CISCO-PROCESS-MIB
55      'cpmCPUTotalTable'                  => '1.3.6.1.4.1.9.9.109.1.1.1.1',
56      'cpmCPUTotalPhysicalIndex'          => '1.3.6.1.4.1.9.9.109.1.1.1.1.2',
57      'cpmCPUTotal1minRev'                => '1.3.6.1.4.1.9.9.109.1.1.1.1.7',
58      'cpmCPUTotal1min'                   => '1.3.6.1.4.1.9.9.109.1.1.1.1.4',
59
60      # OLD-CISCO-CPU-MIB
61      'avgBusy1'                          => '1.3.6.1.4.1.9.2.1.57.0'
62      );
63
64 sub checkdevtype
65 {
66     my $dd = shift;
67     my $devdetails = shift;
68
69     if( not $dd->oidBaseMatch
70         ( 'cisco', $devdetails->snmpVar( $dd->oiddef('sysObjectID') ) ) )
71     {
72         return 0;
73     }
74     
75     return 1;
76 }
77
78
79 sub discover
80 {
81     my $dd = shift;
82     my $devdetails = shift;
83
84     my $session = $dd->session();
85     my $data = $devdetails->data();
86
87     if( $devdetails->param('CiscoGeneric::disable-sensors') ne 'yes' )
88     {
89         # Check if temperature sensors are supported
90
91         my $oidTempDescr = $dd->oiddef('ciscoEnvMonTemperatureStatusDescr');
92         my $oidTempValue = $dd->oiddef('ciscoEnvMonTemperatureStatusValue');
93         my $oidTempThrsh = $dd->oiddef('ciscoEnvMonTemperatureThreshold');
94         my $oidTempState = $dd->oiddef('ciscoEnvMonTemperatureStatusState');
95
96         if( defined $session->get_table( -baseoid => $oidTempValue ) )
97         {
98             $devdetails->setCap('ciscoTemperatureSensors');
99             $data->{'ciscoTemperatureSensors'} = {};
100
101             my $tempDescr = $session->get_table( -baseoid => $oidTempDescr );
102             my $tempThrsh = $session->get_table( -baseoid => $oidTempThrsh );
103
104             # Get the sensor states and ignore those notPresent(5)
105
106             my $tempState = $session->get_table( -baseoid => $oidTempState );
107
108             my $prefixLen = length( $oidTempDescr ) + 1;
109             while( my( $oid, $descr ) = each %{$tempDescr} )
110             {
111                 # Extract the sensor index from OID
112                 my $sIndex = substr( $oid, $prefixLen );
113
114                 if( $tempState->{$oidTempState.'.'.$sIndex} != 5 )
115                 {
116                     $data->{'ciscoTemperatureSensors'}{$sIndex}{
117                         'description'} = $descr;
118                     $data->{'ciscoTemperatureSensors'}{$sIndex}{
119                         'threshold'} = $tempThrsh->{$oidTempThrsh.'.'.$sIndex};
120                 }
121             }
122         }
123     }
124
125     if( $devdetails->param('CiscoGeneric::disable-psupplies') ne 'yes' )
126     {
127         # Check if power supply status is supported
128
129         my $oidSupply = $dd->oiddef('ciscoEnvMonSupplyState');
130
131         my $supplyTable = $session->get_table( -baseoid => $oidSupply );
132         if( defined( $supplyTable ) )
133         {
134             $devdetails->setCap('ciscoPowerSupplies');
135             $data->{'ciscoPowerSupplies'} = [];
136             
137             my $prefixLen = length( $oidSupply ) + 1;
138             while( my( $oid, $val ) = each %{$supplyTable} )
139             {
140                 # Extract the supply index from OID
141                 my $sIndex = substr( $oid, $prefixLen );
142                 
143                 #check if the value is not notPresent(5)
144                 if( $val != 5 )
145                 {
146                     push( @{$data->{'ciscoPowerSupplies'}}, $sIndex );
147                 }
148             }
149         }
150     }
151     
152     if( $devdetails->param('CiscoGeneric::disable-memory-pools') ne 'yes' )
153     {
154         my $eMemPool =
155             $session->get_table( -baseoid =>
156                                  $dd->oiddef('cempMemPoolName') );
157         if( defined $eMemPool and scalar( %{$eMemPool} ) > 0 and
158             $devdetails->isDevType('RFC2737_ENTITY_MIB') )
159         {
160             $devdetails->storeSnmpVars( $eMemPool );
161             $devdetails->setCap('cempMemPool');
162             $data->{'cempMemPool'} = {};
163
164             foreach my $INDEX
165                 ( $devdetails->
166                   getSnmpIndices($dd->oiddef('cempMemPoolName') ) )
167             {
168                 # $INDEX is a pair entPhysicalIndex . cempMemPoolIndex
169                 my ( $phyIndex, $poolIndex ) = split('\.', $INDEX);
170
171                 my $poolName = $devdetails->
172                     snmpVar($dd->oiddef('cempMemPoolName') . '.' . $INDEX );
173
174                 $poolName = 'Processor' unless $poolName;
175                 
176                 my $phyDescr = $data->{'entityPhysical'}{$phyIndex}{'descr'};
177                 my $phyName = $data->{'entityPhysical'}{$phyIndex}{'name'};
178                 
179                 $phyDescr = 'Processor' unless $phyDescr;
180                 $phyName = ('Chassis #' .
181                             $phyIndex) unless $phyName;
182                
183                 $data->{'cempMemPool'}{$INDEX} = {
184                     'phyIndex'     => $phyIndex,
185                     'poolIndex'    => $poolIndex,
186                     'poolName'     => $poolName,                    
187                     'phyDescr' => $phyDescr,
188                     'phyName'  => $phyName
189                     };
190             }
191         }
192         else
193         {
194             my $MemoryPool =
195                 $session->get_table( -baseoid =>
196                                      $dd->oiddef('ciscoMemoryPoolName') );
197
198             if( defined $MemoryPool and scalar( %{$MemoryPool} ) > 0 )
199             {
200                 $devdetails->storeSnmpVars( $MemoryPool );
201                 $devdetails->setCap('ciscoMemoryPool');
202                 
203                 $data->{'ciscoMemoryPool'} = {};
204                 
205                 foreach my $memType
206                     ( $devdetails->
207                       getSnmpIndices($dd->oiddef('ciscoMemoryPoolName')) )
208                 {
209                     # According to CISCO-MEMORY-POOL-MIB, only types 1 to 5
210                     # are static, and the rest are dynamic
211                     # (of which none ever seen)
212                     if( $memType <= 5 )
213                     {
214                         my $name =
215                             $devdetails->
216                             snmpVar($dd->oiddef('ciscoMemoryPoolName') .
217                                     '.' . $memType );
218
219                         $data->{'ciscoMemoryPool'}{$memType} = $name;
220                     }
221                 }
222             }
223         }
224     }
225
226     if( $devdetails->param('CiscoGeneric::disable-cpu-stats') ne 'yes' )
227     {
228         my $ciscoCpuStats =
229             $session->get_table( -baseoid => $dd->oiddef('cpmCPUTotalTable') );
230
231         if( defined $ciscoCpuStats )
232         {
233             $devdetails->setCap('ciscoCpuStats');
234             $devdetails->storeSnmpVars( $ciscoCpuStats );
235
236             $data->{'ciscoCpuStats'} = {};
237
238             # Find multiple CPU entries pointing to the same Phy index
239             my %phyReferers = ();            
240             foreach my $INDEX
241                 ( $devdetails->
242                   getSnmpIndices($dd->oiddef('cpmCPUTotalPhysicalIndex') ) )
243             {
244                 my $phyIndex = $devdetails->
245                     snmpVar($dd->oiddef('cpmCPUTotalPhysicalIndex') .
246                             '.' . $INDEX );
247                 $phyReferers{$phyIndex}++;
248             }
249                 
250             foreach my $INDEX
251                 ( $devdetails->
252                   getSnmpIndices($dd->oiddef('cpmCPUTotalPhysicalIndex') ) )
253             {
254                 $data->{'ciscoCpuStats'}{$INDEX} = {};
255
256                 my $phyIndex = $devdetails->
257                     snmpVar($dd->oiddef('cpmCPUTotalPhysicalIndex') .
258                             '.' . $INDEX );
259                 
260                 my $phyDescr;
261                 my $phyName;
262                 
263                 if( $phyIndex > 0 and
264                     $devdetails->isDevType('RFC2737_ENTITY_MIB') )
265                 {
266                     $phyDescr = $data->{'entityPhysical'}{$phyIndex}{'descr'};
267                     $phyName = $data->{'entityPhysical'}{$phyIndex}{'name'};
268                 }
269                 
270                 $phyDescr = 'Central Processor' unless $phyDescr;
271                 $phyName = ('Chassis #' . $phyIndex) unless $phyName;
272                     ;
273                 my $cpuNick = $phyName;
274                 $cpuNick =~ s/^\///;
275                 $cpuNick =~ s/\W/_/g;
276                 $cpuNick =~ s/_+/_/g;
277
278                 if( $phyReferers{$phyIndex} > 1 )
279                 {
280                     $phyDescr .= ' (' . $INDEX . ')';
281                     $cpuNick .= '_' . $INDEX;
282                 }
283                 
284                 $data->{'ciscoCpuStats'}{$INDEX} = {
285                     'phy-index'  => $phyIndex,
286                     'phy-name'   => $phyName,
287                     'phy-descr'  => $phyDescr,
288                     'phy-referers' => $phyReferers{$phyIndex},
289                     'cpu-nick'   => $cpuNick };
290                 
291                 if( $devdetails->hasOID( $dd->oiddef('cpmCPUTotal1minRev') .
292                                          '.' .  $INDEX ) )
293                 {
294                     $data->{'ciscoCpuStats'}{$INDEX}{'stats-type'} = 'revised';
295                 }
296             }
297         }
298         else
299         {
300             # Although OLD-CISCO-CPU-MIB is implemented in IOS only,
301             # it is easier to leave it here in Generic
302
303             if( $dd->checkSnmpOID('avgBusy1') )
304             {
305                 $devdetails->setCap('old-ciscoCpuStats');
306                 push( @{$data->{'templates'}}, 'CiscoGeneric::old-cisco-cpu' );
307             }
308         }
309     }
310
311     return 1;
312 }
313
314
315 sub buildConfig
316 {
317     my $devdetails = shift;
318     my $cb = shift;
319     my $devNode = shift;
320     
321     my $data = $devdetails->data();
322
323     # Temperature Sensors
324
325     if( $devdetails->hasCap('ciscoTemperatureSensors') )
326     {
327         # Create a subtree for the sensors
328         my $subtreeName = 'Temperature_Sensors';
329
330         my $fahrenheit =
331             $devdetails->param('CiscoGeneric::use-fahrenheit') eq 'yes';
332
333         my $param = {
334             'node-display-name' => 'Temperature Sensors',
335         };
336         my $templates = [ 'CiscoGeneric::cisco-temperature-subtree' ];
337         
338         my $filePerSensor =
339             $devdetails->param('CiscoGeneric::file-per-sensor') eq 'yes';
340         
341         $param->{'data-file'} = '%snmp-host%_sensors' .
342             ($filePerSensor ? '_%sensor-index%':'') .
343             ($fahrenheit ? '_fahrenheit':'') . '.rrd';
344
345         my $subtreeNode = $cb->addSubtree( $devNode, $subtreeName,
346                                            $param, $templates );
347         
348         foreach my $sIndex ( sort {$a<=>$b} keys
349                              %{$data->{'ciscoTemperatureSensors'}} )
350         {
351             my $leafName = sprintf( 'sensor_%.2d', $sIndex );
352
353             my $desc =
354                 $data->{'ciscoTemperatureSensors'}{$sIndex}{'description'};
355             my $threshold =
356                 $data->{'ciscoTemperatureSensors'}{$sIndex}{'threshold'};
357
358             if( $fahrenheit )
359             {
360                 $threshold = $threshold * 1.8 + 32;
361             }
362
363             my $param = {
364                 'sensor-index'       => $sIndex,
365                 'sensor-description' => $desc,
366                 'upper-limit'        => $threshold
367                 };
368
369             my $templates = ['CiscoGeneric::cisco-temperature-sensor' .
370                              ($fahrenheit ? '-fahrenheit':'')];
371
372             my $monitor = $data->{'ciscoTemperatureSensors'}{$sIndex}->{
373                 'selectorActions'}{'Monitor'};
374             if( defined( $monitor ) )
375             {
376                 $param->{'monitor'} = $monitor;
377             }
378
379             my $tset = $data->{'ciscoTemperatureSensors'}{$sIndex}->{
380                 'selectorActions'}{'TokensetMember'};
381             if( defined( $tset ) )
382             {
383                 $param->{'tokenset-member'} = $tset;
384             }
385
386             $cb->addLeaf( $subtreeNode, $leafName, $param, $templates );
387         }
388     }
389
390     # Power supplies
391
392     if( $devdetails->hasCap('ciscoPowerSupplies') )
393     {
394         # Create a subtree for the power supplies
395         my $subtreeName = 'Power_Supplies';
396
397         my $param = {
398             'node-display-name' => 'Power Supplies',
399             'comment' => 'Power supplies status',
400             'precedence' => -600,
401         };
402         my $templates = [];
403                 
404         $param->{'data-file'} = '%system-id%_power.rrd';
405
406         my $monitor = $devdetails->param('CiscoGeneric::power-monitor');
407         if( length( $monitor ) > 0 )
408         {
409             $param->{'monitor'} = $monitor;
410         }
411
412         my $subtreeNode = $cb->addSubtree( $devNode, $subtreeName,
413                                            $param, $templates );
414         
415         foreach my $sIndex ( sort {$a<=>$b} @{$data->{'ciscoPowerSupplies'}} )
416         {
417             my $leafName = sprintf( 'power_%.2d', $sIndex );
418
419             my $param = {
420                 'power-index'       => $sIndex
421                 };
422
423             my $templates = ['CiscoGeneric::cisco-power-supply'];
424
425             $cb->addLeaf( $subtreeNode, $leafName, $param, $templates );
426         }
427     }
428
429     
430     # Memory Pools
431
432     if( $devdetails->hasCap('cempMemPool') or
433         $devdetails->hasCap('ciscoMemoryPool') )
434     {
435         my $subtreeName = 'Memory_Usage';
436
437         my $param = {
438             'node-display-name' => 'Memory Usage',
439             'precedence'        => '-100',
440             'comment'           => 'Router memory utilization'
441             };
442
443         my $subtreeNode =
444             $cb->addSubtree( $devNode, $subtreeName, $param,
445                              ['CiscoGeneric::cisco-memusage-subtree']);
446
447         if( $devdetails->hasCap('cempMemPool') )
448         {
449             foreach my $INDEX ( sort {
450                 $data->{'cempMemPool'}{$a}{'phyIndex'} <=>
451                     $data->{'cempMemPool'}{$b}{'phyIndex'} or
452                     $data->{'cempMemPool'}{$a}{'poolIndex'} <=>
453                     $data->{'cempMemPool'}{$b}{'poolIndex'} }
454                                 keys %{$data->{'cempMemPool'}} )
455             {
456                 my $pool = $data->{'cempMemPool'}{$INDEX};
457
458                 # Chop off the long chassis description, like
459                 # uBR7246VXR chassis, Hw Serial#: XXXXX, Hw Revision: A
460                 my $phyName = $pool->{'phyName'};                
461                 if( $phyName =~ /chassis/ )
462                 {
463                     $phyName =~ s/,.+//;
464                 }
465                 
466                 my $poolSubtreeName =
467                     $phyName . '_' . $pool->{'poolName'};
468                 $poolSubtreeName =~ s/^\///;
469                 $poolSubtreeName =~ s/\W/_/g;
470                 $poolSubtreeName =~ s/_+/_/g;
471                 
472                 my $param = {};
473
474                 $param->{'comment'} =
475                     $pool->{'poolName'} . ' memory of ';
476                 if( $pool->{'phyDescr'} eq $pool->{'phyName'} )
477                 {
478                     $param->{'comment'} .= $phyName;
479                 }
480                 else
481                 {
482                     $param->{'comment'} .= 
483                         $pool->{'phyDescr'} . ' in ' . $phyName;
484                 }
485                 
486                 $param->{'mempool-index'} = $INDEX;
487                 $param->{'mempool-phyindex'} = $pool->{'phyIndex'};
488                 $param->{'mempool-poolindex'} = $pool->{'poolIndex'};
489                 
490                 $param->{'mempool-name'} =  $pool->{'poolName'};
491                 $param->{'precedence'} =
492                     sprintf("%d", 1000 -
493                             $pool->{'phyIndex'} * 100 - $pool->{'poolIndex'});
494                 
495                 $cb->addSubtree( $subtreeNode, $poolSubtreeName, $param,
496                                  [ 'CiscoGeneric::cisco-enh-mempool' ]);
497             }
498         }
499         else
500         {
501             foreach my $memType
502                 ( sort {$a<=>$b} keys %{$data->{'ciscoMemoryPool'}} )
503             {
504                 my $poolName = $data->{'ciscoMemoryPool'}{$memType};
505                 
506                 my $poolSubtreeName = $poolName;
507                 $poolSubtreeName =~ s/^\///;
508                 $poolSubtreeName =~ s/\W/_/g;
509                 $poolSubtreeName =~ s/_+/_/g;
510                 
511                 my $param = {
512                     'comment'      => 'Memory Pool: ' . $poolName,
513                     'mempool-type' => $memType,
514                     'mempool-name' => $poolName,
515                     'precedence'   => sprintf("%d", 1000 - $memType)
516                     };
517
518                 $cb->addSubtree( $subtreeNode, $poolSubtreeName,
519                                  $param, [ 'CiscoGeneric::cisco-mempool' ]);
520             }
521         }
522     }
523
524     if( $devdetails->hasCap('ciscoCpuStats') )
525     {
526         my $subtreeName = 'CPU_Usage';
527         my $param = {
528             'node-display-name' => 'CPU Usage',
529             'precedence'         => '-500',
530             'comment'            => 'Overall CPU busy percentage'
531             };
532
533         my $subtreeNode =
534             $cb->addSubtree( $devNode, $subtreeName, $param,
535                              ['CiscoGeneric::cisco-cpu-usage-subtree']);
536         
537         foreach my $INDEX ( sort {$a<=>$b} keys %{$data->{'ciscoCpuStats'}} )
538         {
539             my $cpu = $data->{'ciscoCpuStats'}{$INDEX};
540
541             my $param = {
542                 'comment' => $cpu->{'phy-descr'} . ' in ' . $cpu->{'phy-name'}
543                 };
544
545             # On newer dual-CPU routers, several (two seen) CPU entries
546             # refer to the same physical entity. For such entries,
547             # we map them directly to cpmCPUTotalTable index.
548             if( $cpu->{'phy-referers'} > 1 )
549             {
550                 $param->{'cisco-cpu-indexmap'} = $INDEX;
551                 $param->{'cisco-cpu-ref'} = $INDEX;
552             }
553             else
554             {
555                 $param->{'entity-phy-index'} = $cpu->{'phy-index'};
556                 $param->{'cisco-cpu-ref'} = '%entity-phy-index%';
557             }
558             
559             my @templates;
560
561             if( $cpu->{'stats-type'} eq 'revised' )
562             {
563                 push( @templates, 'CiscoGeneric::cisco-cpu-revised' );
564             }
565             else
566             {
567                 push( @templates, 'CiscoGeneric::cisco-cpu' );
568             }
569             
570             my $cpuNode = $cb->addSubtree( $subtreeNode, $cpu->{'cpu-nick'},
571                                            $param, \@templates );
572             
573             my $tset = $cpu->{'selectorActions'}{'TokensetMember'};
574             if( defined( $tset ) )
575             {
576                 $cb->addLeaf( $cpuNode, 'CPU_Total_1min',
577                               { 'tokenset-member' => $tset } );
578             }
579         }
580     }
581 }
582
583
584
585 #######################################
586 # Selectors interface
587 #
588
589 $Torrus::DevDiscover::selectorsRegistry{'CiscoSensor'} = {
590     'getObjects'      => \&getSelectorObjects,
591     'getObjectName'   => \&getSelectorObjectName,
592     'checkAttribute'  => \&checkSelectorAttribute,
593     'applyAction'     => \&applySelectorAction,
594 };
595
596 $Torrus::DevDiscover::selectorsRegistry{'CiscoCPU'} = {
597     'getObjects'      => \&getSelectorObjects,
598     'getObjectName'   => \&getSelectorObjectName,
599     'checkAttribute'  => \&checkSelectorAttribute,
600     'applyAction'     => \&applySelectorAction,
601 };
602
603 ## Objects are interface indexes
604
605 sub getSelectorObjects
606 {
607     my $devdetails = shift;
608     my $objType = shift;
609
610     my $data = $devdetails->data();
611     my @ret;
612     
613     if( $objType eq 'CiscoSensor' )
614     {
615         @ret = keys( %{$data->{'ciscoTemperatureSensors'}} );
616     }
617     elsif( $objType eq 'CiscoCPU' )
618     {
619         @ret = keys( %{$data->{'ciscoCpuStats'}} );
620     }
621
622     return( sort {$a<=>$b} @ret );
623 }
624
625
626 sub checkSelectorAttribute
627 {
628     my $devdetails = shift;
629     my $object = shift;
630     my $objType = shift;
631     my $attr = shift;
632     my $checkval = shift;
633
634     my $data = $devdetails->data();
635     
636     my $value;
637     my $operator = '=~';
638     
639     if( $objType eq 'CiscoSensor' )
640     {
641         my $sensor = $data->{'ciscoTemperatureSensors'}{$object};
642         if( $attr eq 'SensorDescr' )
643         {
644             $value = $sensor->{'description'};
645         }
646         else
647         {
648             Error('Unknown CiscoSensor selector attribute: ' . $attr);
649             $value = '';
650         }
651     }
652     elsif( $objType eq 'CiscoCPU' )
653     {
654         my $cpu = $data->{'ciscoCpuStats'}{$object};
655         if( $attr eq 'CPUName' )
656         {
657             $value = $cpu->{'cpu-nick'};
658         }
659         elsif( $attr eq 'CPUDescr' )
660         {
661             $value = $cpu->{'cpu-descr'};
662         }
663         else
664         {
665             Error('Unknown CiscoCPU selector attribute: ' . $attr);
666             $value = '';
667         }        
668     }        
669     
670     return eval( '$value' . ' ' . $operator . '$checkval' ) ? 1:0;
671 }
672
673
674 sub getSelectorObjectName
675 {
676     my $devdetails = shift;
677     my $object = shift;
678     my $objType = shift;
679     
680     my $data = $devdetails->data();
681     my $name;
682
683     if( $objType eq 'CiscoSensor' )
684     {
685         $name = $data->{'ciscoTemperatureSensors'}{$object}{'description'};
686     }
687     elsif( $objType eq 'CiscoCPU' )
688     {
689         $name = $data->{'ciscoCpuStats'}{$object}{'cpu-nick'};
690     }
691     return $name;
692 }
693
694
695 my %knownSelectorActions =
696     (
697      'CiscoSensor' => {
698          'Monitor' => 1,
699          'TokensetMember' => 1 },
700      'CiscoCPU' => {
701          'TokensetMember' => 1 }
702      );
703
704                             
705 sub applySelectorAction
706 {
707     my $devdetails = shift;
708     my $object = shift;
709     my $objType = shift;
710     my $action = shift;
711     my $arg = shift;
712
713     my $data = $devdetails->data();
714     my $objref;
715     if( $objType eq 'CiscoSensor' )
716     {
717         $objref = $data->{'ciscoTemperatureSensors'}{$object};
718     }
719     elsif( $objType eq 'CiscoCPU' )
720     {
721         $objref = $data->{'ciscoCpuStats'}{$object};
722     }
723     
724     if( $knownSelectorActions{$objType}{$action} )
725     {
726         $objref->{'selectorActions'}{$action} = $arg;
727     }
728     else
729     {
730         Error('Unknown Cisco selector action: ' . $action);
731     }
732 }   
733
734
735
736 1;
737
738
739 # Local Variables:
740 # mode: perl
741 # indent-tabs-mode: nil
742 # perl-indent-level: 4
743 # End: