summaryrefslogtreecommitdiff
path: root/torrus/perllib/Torrus/DevDiscover/CiscoGeneric.pm
diff options
context:
space:
mode:
Diffstat (limited to 'torrus/perllib/Torrus/DevDiscover/CiscoGeneric.pm')
-rw-r--r--torrus/perllib/Torrus/DevDiscover/CiscoGeneric.pm743
1 files changed, 743 insertions, 0 deletions
diff --git a/torrus/perllib/Torrus/DevDiscover/CiscoGeneric.pm b/torrus/perllib/Torrus/DevDiscover/CiscoGeneric.pm
new file mode 100644
index 000000000..4262bdd71
--- /dev/null
+++ b/torrus/perllib/Torrus/DevDiscover/CiscoGeneric.pm
@@ -0,0 +1,743 @@
+# Copyright (C) 2002 Stanislav Sinyagin
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
+
+# $Id: CiscoGeneric.pm,v 1.1 2010-12-27 00:03:48 ivan Exp $
+# Stanislav Sinyagin <ssinyagin@yahoo.com>
+
+# Common Cisco MIBs, supported by many IOS and CatOS devices
+
+package Torrus::DevDiscover::CiscoGeneric;
+
+use strict;
+use Torrus::Log;
+
+
+$Torrus::DevDiscover::registry{'CiscoGeneric'} = {
+ 'sequence' => 500,
+ 'checkdevtype' => \&checkdevtype,
+ 'discover' => \&discover,
+ 'buildConfig' => \&buildConfig
+ };
+
+
+our %oiddef =
+ (
+ # CISCO-SMI
+ 'cisco' => '1.3.6.1.4.1.9',
+
+ # CISCO-ENVMON-MIB
+ 'ciscoEnvMonTemperatureStatusDescr' => '1.3.6.1.4.1.9.9.13.1.3.1.2',
+ 'ciscoEnvMonTemperatureStatusValue' => '1.3.6.1.4.1.9.9.13.1.3.1.3',
+ 'ciscoEnvMonTemperatureThreshold' => '1.3.6.1.4.1.9.9.13.1.3.1.4',
+ 'ciscoEnvMonTemperatureStatusState' => '1.3.6.1.4.1.9.9.13.1.3.1.6',
+ 'ciscoEnvMonSupplyState' => '1.3.6.1.4.1.9.9.13.1.5.1.3',
+
+ # CISCO-ENHANCED-MEMPOOL-MIB
+ 'cempMemPoolName' => '1.3.6.1.4.1.9.9.221.1.1.1.1.3',
+
+ # CISCO-MEMORY-POOL-MIB
+ 'ciscoMemoryPoolName' => '1.3.6.1.4.1.9.9.48.1.1.1.2',
+
+ # CISCO-PROCESS-MIB
+ 'cpmCPUTotalTable' => '1.3.6.1.4.1.9.9.109.1.1.1.1',
+ 'cpmCPUTotalPhysicalIndex' => '1.3.6.1.4.1.9.9.109.1.1.1.1.2',
+ 'cpmCPUTotal1minRev' => '1.3.6.1.4.1.9.9.109.1.1.1.1.7',
+ 'cpmCPUTotal1min' => '1.3.6.1.4.1.9.9.109.1.1.1.1.4',
+
+ # OLD-CISCO-CPU-MIB
+ 'avgBusy1' => '1.3.6.1.4.1.9.2.1.57.0'
+ );
+
+sub checkdevtype
+{
+ my $dd = shift;
+ my $devdetails = shift;
+
+ if( not $dd->oidBaseMatch
+ ( 'cisco', $devdetails->snmpVar( $dd->oiddef('sysObjectID') ) ) )
+ {
+ return 0;
+ }
+
+ return 1;
+}
+
+
+sub discover
+{
+ my $dd = shift;
+ my $devdetails = shift;
+
+ my $session = $dd->session();
+ my $data = $devdetails->data();
+
+ if( $devdetails->param('CiscoGeneric::disable-sensors') ne 'yes' )
+ {
+ # Check if temperature sensors are supported
+
+ my $oidTempDescr = $dd->oiddef('ciscoEnvMonTemperatureStatusDescr');
+ my $oidTempValue = $dd->oiddef('ciscoEnvMonTemperatureStatusValue');
+ my $oidTempThrsh = $dd->oiddef('ciscoEnvMonTemperatureThreshold');
+ my $oidTempState = $dd->oiddef('ciscoEnvMonTemperatureStatusState');
+
+ if( defined $session->get_table( -baseoid => $oidTempValue ) )
+ {
+ $devdetails->setCap('ciscoTemperatureSensors');
+ $data->{'ciscoTemperatureSensors'} = {};
+
+ my $tempDescr = $session->get_table( -baseoid => $oidTempDescr );
+ my $tempThrsh = $session->get_table( -baseoid => $oidTempThrsh );
+
+ # Get the sensor states and ignore those notPresent(5)
+
+ my $tempState = $session->get_table( -baseoid => $oidTempState );
+
+ my $prefixLen = length( $oidTempDescr ) + 1;
+ while( my( $oid, $descr ) = each %{$tempDescr} )
+ {
+ # Extract the sensor index from OID
+ my $sIndex = substr( $oid, $prefixLen );
+
+ if( $tempState->{$oidTempState.'.'.$sIndex} != 5 )
+ {
+ $data->{'ciscoTemperatureSensors'}{$sIndex}{
+ 'description'} = $descr;
+ $data->{'ciscoTemperatureSensors'}{$sIndex}{
+ 'threshold'} = $tempThrsh->{$oidTempThrsh.'.'.$sIndex};
+ }
+ }
+ }
+ }
+
+ if( $devdetails->param('CiscoGeneric::disable-psupplies') ne 'yes' )
+ {
+ # Check if power supply status is supported
+
+ my $oidSupply = $dd->oiddef('ciscoEnvMonSupplyState');
+
+ my $supplyTable = $session->get_table( -baseoid => $oidSupply );
+ if( defined( $supplyTable ) )
+ {
+ $devdetails->setCap('ciscoPowerSupplies');
+ $data->{'ciscoPowerSupplies'} = [];
+
+ my $prefixLen = length( $oidSupply ) + 1;
+ while( my( $oid, $val ) = each %{$supplyTable} )
+ {
+ # Extract the supply index from OID
+ my $sIndex = substr( $oid, $prefixLen );
+
+ #check if the value is not notPresent(5)
+ if( $val != 5 )
+ {
+ push( @{$data->{'ciscoPowerSupplies'}}, $sIndex );
+ }
+ }
+ }
+ }
+
+ if( $devdetails->param('CiscoGeneric::disable-memory-pools') ne 'yes' )
+ {
+ my $eMemPool =
+ $session->get_table( -baseoid =>
+ $dd->oiddef('cempMemPoolName') );
+ if( defined $eMemPool and scalar( %{$eMemPool} ) > 0 and
+ $devdetails->isDevType('RFC2737_ENTITY_MIB') )
+ {
+ $devdetails->storeSnmpVars( $eMemPool );
+ $devdetails->setCap('cempMemPool');
+ $data->{'cempMemPool'} = {};
+
+ foreach my $INDEX
+ ( $devdetails->
+ getSnmpIndices($dd->oiddef('cempMemPoolName') ) )
+ {
+ # $INDEX is a pair entPhysicalIndex . cempMemPoolIndex
+ my ( $phyIndex, $poolIndex ) = split('\.', $INDEX);
+
+ my $poolName = $devdetails->
+ snmpVar($dd->oiddef('cempMemPoolName') . '.' . $INDEX );
+
+ $poolName = 'Processor' unless $poolName;
+
+ my $phyDescr = $data->{'entityPhysical'}{$phyIndex}{'descr'};
+ my $phyName = $data->{'entityPhysical'}{$phyIndex}{'name'};
+
+ $phyDescr = 'Processor' unless $phyDescr;
+ $phyName = ('Chassis #' .
+ $phyIndex) unless $phyName;
+
+ $data->{'cempMemPool'}{$INDEX} = {
+ 'phyIndex' => $phyIndex,
+ 'poolIndex' => $poolIndex,
+ 'poolName' => $poolName,
+ 'phyDescr' => $phyDescr,
+ 'phyName' => $phyName
+ };
+ }
+ }
+ else
+ {
+ my $MemoryPool =
+ $session->get_table( -baseoid =>
+ $dd->oiddef('ciscoMemoryPoolName') );
+
+ if( defined $MemoryPool and scalar( %{$MemoryPool} ) > 0 )
+ {
+ $devdetails->storeSnmpVars( $MemoryPool );
+ $devdetails->setCap('ciscoMemoryPool');
+
+ $data->{'ciscoMemoryPool'} = {};
+
+ foreach my $memType
+ ( $devdetails->
+ getSnmpIndices($dd->oiddef('ciscoMemoryPoolName')) )
+ {
+ # According to CISCO-MEMORY-POOL-MIB, only types 1 to 5
+ # are static, and the rest are dynamic
+ # (of which none ever seen)
+ if( $memType <= 5 )
+ {
+ my $name =
+ $devdetails->
+ snmpVar($dd->oiddef('ciscoMemoryPoolName') .
+ '.' . $memType );
+
+ $data->{'ciscoMemoryPool'}{$memType} = $name;
+ }
+ }
+ }
+ }
+ }
+
+ if( $devdetails->param('CiscoGeneric::disable-cpu-stats') ne 'yes' )
+ {
+ my $ciscoCpuStats =
+ $session->get_table( -baseoid => $dd->oiddef('cpmCPUTotalTable') );
+
+ if( defined $ciscoCpuStats )
+ {
+ $devdetails->setCap('ciscoCpuStats');
+ $devdetails->storeSnmpVars( $ciscoCpuStats );
+
+ $data->{'ciscoCpuStats'} = {};
+
+ # Find multiple CPU entries pointing to the same Phy index
+ my %phyReferers = ();
+ foreach my $INDEX
+ ( $devdetails->
+ getSnmpIndices($dd->oiddef('cpmCPUTotalPhysicalIndex') ) )
+ {
+ my $phyIndex = $devdetails->
+ snmpVar($dd->oiddef('cpmCPUTotalPhysicalIndex') .
+ '.' . $INDEX );
+ $phyReferers{$phyIndex}++;
+ }
+
+ foreach my $INDEX
+ ( $devdetails->
+ getSnmpIndices($dd->oiddef('cpmCPUTotalPhysicalIndex') ) )
+ {
+ $data->{'ciscoCpuStats'}{$INDEX} = {};
+
+ my $phyIndex = $devdetails->
+ snmpVar($dd->oiddef('cpmCPUTotalPhysicalIndex') .
+ '.' . $INDEX );
+
+ my $phyDescr;
+ my $phyName;
+
+ if( $phyIndex > 0 and
+ $devdetails->isDevType('RFC2737_ENTITY_MIB') )
+ {
+ $phyDescr = $data->{'entityPhysical'}{$phyIndex}{'descr'};
+ $phyName = $data->{'entityPhysical'}{$phyIndex}{'name'};
+ }
+
+ $phyDescr = 'Central Processor' unless $phyDescr;
+ $phyName = ('Chassis #' . $phyIndex) unless $phyName;
+ ;
+ my $cpuNick = $phyName;
+ $cpuNick =~ s/^\///;
+ $cpuNick =~ s/\W/_/g;
+ $cpuNick =~ s/_+/_/g;
+
+ if( $phyReferers{$phyIndex} > 1 )
+ {
+ $phyDescr .= ' (' . $INDEX . ')';
+ $cpuNick .= '_' . $INDEX;
+ }
+
+ $data->{'ciscoCpuStats'}{$INDEX} = {
+ 'phy-index' => $phyIndex,
+ 'phy-name' => $phyName,
+ 'phy-descr' => $phyDescr,
+ 'phy-referers' => $phyReferers{$phyIndex},
+ 'cpu-nick' => $cpuNick };
+
+ if( $devdetails->hasOID( $dd->oiddef('cpmCPUTotal1minRev') .
+ '.' . $INDEX ) )
+ {
+ $data->{'ciscoCpuStats'}{$INDEX}{'stats-type'} = 'revised';
+ }
+ }
+ }
+ else
+ {
+ # Although OLD-CISCO-CPU-MIB is implemented in IOS only,
+ # it is easier to leave it here in Generic
+
+ if( $dd->checkSnmpOID('avgBusy1') )
+ {
+ $devdetails->setCap('old-ciscoCpuStats');
+ push( @{$data->{'templates'}}, 'CiscoGeneric::old-cisco-cpu' );
+ }
+ }
+ }
+
+ return 1;
+}
+
+
+sub buildConfig
+{
+ my $devdetails = shift;
+ my $cb = shift;
+ my $devNode = shift;
+
+ my $data = $devdetails->data();
+
+ # Temperature Sensors
+
+ if( $devdetails->hasCap('ciscoTemperatureSensors') )
+ {
+ # Create a subtree for the sensors
+ my $subtreeName = 'Temperature_Sensors';
+
+ my $fahrenheit =
+ $devdetails->param('CiscoGeneric::use-fahrenheit') eq 'yes';
+
+ my $param = {
+ 'node-display-name' => 'Temperature Sensors',
+ };
+ my $templates = [ 'CiscoGeneric::cisco-temperature-subtree' ];
+
+ my $filePerSensor =
+ $devdetails->param('CiscoGeneric::file-per-sensor') eq 'yes';
+
+ $param->{'data-file'} = '%snmp-host%_sensors' .
+ ($filePerSensor ? '_%sensor-index%':'') .
+ ($fahrenheit ? '_fahrenheit':'') . '.rrd';
+
+ my $subtreeNode = $cb->addSubtree( $devNode, $subtreeName,
+ $param, $templates );
+
+ foreach my $sIndex ( sort {$a<=>$b} keys
+ %{$data->{'ciscoTemperatureSensors'}} )
+ {
+ my $leafName = sprintf( 'sensor_%.2d', $sIndex );
+
+ my $desc =
+ $data->{'ciscoTemperatureSensors'}{$sIndex}{'description'};
+ my $threshold =
+ $data->{'ciscoTemperatureSensors'}{$sIndex}{'threshold'};
+
+ if( $fahrenheit )
+ {
+ $threshold = $threshold * 1.8 + 32;
+ }
+
+ my $param = {
+ 'sensor-index' => $sIndex,
+ 'sensor-description' => $desc,
+ 'upper-limit' => $threshold
+ };
+
+ my $templates = ['CiscoGeneric::cisco-temperature-sensor' .
+ ($fahrenheit ? '-fahrenheit':'')];
+
+ my $monitor = $data->{'ciscoTemperatureSensors'}{$sIndex}->{
+ 'selectorActions'}{'Monitor'};
+ if( defined( $monitor ) )
+ {
+ $param->{'monitor'} = $monitor;
+ }
+
+ my $tset = $data->{'ciscoTemperatureSensors'}{$sIndex}->{
+ 'selectorActions'}{'TokensetMember'};
+ if( defined( $tset ) )
+ {
+ $param->{'tokenset-member'} = $tset;
+ }
+
+ $cb->addLeaf( $subtreeNode, $leafName, $param, $templates );
+ }
+ }
+
+ # Power supplies
+
+ if( $devdetails->hasCap('ciscoPowerSupplies') )
+ {
+ # Create a subtree for the power supplies
+ my $subtreeName = 'Power_Supplies';
+
+ my $param = {
+ 'node-display-name' => 'Power Supplies',
+ 'comment' => 'Power supplies status',
+ 'precedence' => -600,
+ };
+ my $templates = [];
+
+ $param->{'data-file'} = '%system-id%_power.rrd';
+
+ my $monitor = $devdetails->param('CiscoGeneric::power-monitor');
+ if( length( $monitor ) > 0 )
+ {
+ $param->{'monitor'} = $monitor;
+ }
+
+ my $subtreeNode = $cb->addSubtree( $devNode, $subtreeName,
+ $param, $templates );
+
+ foreach my $sIndex ( sort {$a<=>$b} @{$data->{'ciscoPowerSupplies'}} )
+ {
+ my $leafName = sprintf( 'power_%.2d', $sIndex );
+
+ my $param = {
+ 'power-index' => $sIndex
+ };
+
+ my $templates = ['CiscoGeneric::cisco-power-supply'];
+
+ $cb->addLeaf( $subtreeNode, $leafName, $param, $templates );
+ }
+ }
+
+
+ # Memory Pools
+
+ if( $devdetails->hasCap('cempMemPool') or
+ $devdetails->hasCap('ciscoMemoryPool') )
+ {
+ my $subtreeName = 'Memory_Usage';
+
+ my $param = {
+ 'node-display-name' => 'Memory Usage',
+ 'precedence' => '-100',
+ 'comment' => 'Router memory utilization'
+ };
+
+ my $subtreeNode =
+ $cb->addSubtree( $devNode, $subtreeName, $param,
+ ['CiscoGeneric::cisco-memusage-subtree']);
+
+ if( $devdetails->hasCap('cempMemPool') )
+ {
+ foreach my $INDEX ( sort {
+ $data->{'cempMemPool'}{$a}{'phyIndex'} <=>
+ $data->{'cempMemPool'}{$b}{'phyIndex'} or
+ $data->{'cempMemPool'}{$a}{'poolIndex'} <=>
+ $data->{'cempMemPool'}{$b}{'poolIndex'} }
+ keys %{$data->{'cempMemPool'}} )
+ {
+ my $pool = $data->{'cempMemPool'}{$INDEX};
+
+ # Chop off the long chassis description, like
+ # uBR7246VXR chassis, Hw Serial#: XXXXX, Hw Revision: A
+ my $phyName = $pool->{'phyName'};
+ if( $phyName =~ /chassis/ )
+ {
+ $phyName =~ s/,.+//;
+ }
+
+ my $poolSubtreeName =
+ $phyName . '_' . $pool->{'poolName'};
+ $poolSubtreeName =~ s/^\///;
+ $poolSubtreeName =~ s/\W/_/g;
+ $poolSubtreeName =~ s/_+/_/g;
+
+ my $param = {};
+
+ $param->{'comment'} =
+ $pool->{'poolName'} . ' memory of ';
+ if( $pool->{'phyDescr'} eq $pool->{'phyName'} )
+ {
+ $param->{'comment'} .= $phyName;
+ }
+ else
+ {
+ $param->{'comment'} .=
+ $pool->{'phyDescr'} . ' in ' . $phyName;
+ }
+
+ $param->{'mempool-index'} = $INDEX;
+ $param->{'mempool-phyindex'} = $pool->{'phyIndex'};
+ $param->{'mempool-poolindex'} = $pool->{'poolIndex'};
+
+ $param->{'mempool-name'} = $pool->{'poolName'};
+ $param->{'precedence'} =
+ sprintf("%d", 1000 -
+ $pool->{'phyIndex'} * 100 - $pool->{'poolIndex'});
+
+ $cb->addSubtree( $subtreeNode, $poolSubtreeName, $param,
+ [ 'CiscoGeneric::cisco-enh-mempool' ]);
+ }
+ }
+ else
+ {
+ foreach my $memType
+ ( sort {$a<=>$b} keys %{$data->{'ciscoMemoryPool'}} )
+ {
+ my $poolName = $data->{'ciscoMemoryPool'}{$memType};
+
+ my $poolSubtreeName = $poolName;
+ $poolSubtreeName =~ s/^\///;
+ $poolSubtreeName =~ s/\W/_/g;
+ $poolSubtreeName =~ s/_+/_/g;
+
+ my $param = {
+ 'comment' => 'Memory Pool: ' . $poolName,
+ 'mempool-type' => $memType,
+ 'mempool-name' => $poolName,
+ 'precedence' => sprintf("%d", 1000 - $memType)
+ };
+
+ $cb->addSubtree( $subtreeNode, $poolSubtreeName,
+ $param, [ 'CiscoGeneric::cisco-mempool' ]);
+ }
+ }
+ }
+
+ if( $devdetails->hasCap('ciscoCpuStats') )
+ {
+ my $subtreeName = 'CPU_Usage';
+ my $param = {
+ 'node-display-name' => 'CPU Usage',
+ 'precedence' => '-500',
+ 'comment' => 'Overall CPU busy percentage'
+ };
+
+ my $subtreeNode =
+ $cb->addSubtree( $devNode, $subtreeName, $param,
+ ['CiscoGeneric::cisco-cpu-usage-subtree']);
+
+ foreach my $INDEX ( sort {$a<=>$b} keys %{$data->{'ciscoCpuStats'}} )
+ {
+ my $cpu = $data->{'ciscoCpuStats'}{$INDEX};
+
+ my $param = {
+ 'comment' => $cpu->{'phy-descr'} . ' in ' . $cpu->{'phy-name'}
+ };
+
+ # On newer dual-CPU routers, several (two seen) CPU entries
+ # refer to the same physical entity. For such entries,
+ # we map them directly to cpmCPUTotalTable index.
+ if( $cpu->{'phy-referers'} > 1 )
+ {
+ $param->{'cisco-cpu-indexmap'} = $INDEX;
+ $param->{'cisco-cpu-ref'} = $INDEX;
+ }
+ else
+ {
+ $param->{'entity-phy-index'} = $cpu->{'phy-index'};
+ $param->{'cisco-cpu-ref'} = '%entity-phy-index%';
+ }
+
+ my @templates;
+
+ if( $cpu->{'stats-type'} eq 'revised' )
+ {
+ push( @templates, 'CiscoGeneric::cisco-cpu-revised' );
+ }
+ else
+ {
+ push( @templates, 'CiscoGeneric::cisco-cpu' );
+ }
+
+ my $cpuNode = $cb->addSubtree( $subtreeNode, $cpu->{'cpu-nick'},
+ $param, \@templates );
+
+ my $tset = $cpu->{'selectorActions'}{'TokensetMember'};
+ if( defined( $tset ) )
+ {
+ $cb->addLeaf( $cpuNode, 'CPU_Total_1min',
+ { 'tokenset-member' => $tset } );
+ }
+ }
+ }
+}
+
+
+
+#######################################
+# Selectors interface
+#
+
+$Torrus::DevDiscover::selectorsRegistry{'CiscoSensor'} = {
+ 'getObjects' => \&getSelectorObjects,
+ 'getObjectName' => \&getSelectorObjectName,
+ 'checkAttribute' => \&checkSelectorAttribute,
+ 'applyAction' => \&applySelectorAction,
+};
+
+$Torrus::DevDiscover::selectorsRegistry{'CiscoCPU'} = {
+ 'getObjects' => \&getSelectorObjects,
+ 'getObjectName' => \&getSelectorObjectName,
+ 'checkAttribute' => \&checkSelectorAttribute,
+ 'applyAction' => \&applySelectorAction,
+};
+
+## Objects are interface indexes
+
+sub getSelectorObjects
+{
+ my $devdetails = shift;
+ my $objType = shift;
+
+ my $data = $devdetails->data();
+ my @ret;
+
+ if( $objType eq 'CiscoSensor' )
+ {
+ @ret = keys( %{$data->{'ciscoTemperatureSensors'}} );
+ }
+ elsif( $objType eq 'CiscoCPU' )
+ {
+ @ret = keys( %{$data->{'ciscoCpuStats'}} );
+ }
+
+ return( sort {$a<=>$b} @ret );
+}
+
+
+sub checkSelectorAttribute
+{
+ my $devdetails = shift;
+ my $object = shift;
+ my $objType = shift;
+ my $attr = shift;
+ my $checkval = shift;
+
+ my $data = $devdetails->data();
+
+ my $value;
+ my $operator = '=~';
+
+ if( $objType eq 'CiscoSensor' )
+ {
+ my $sensor = $data->{'ciscoTemperatureSensors'}{$object};
+ if( $attr eq 'SensorDescr' )
+ {
+ $value = $sensor->{'description'};
+ }
+ else
+ {
+ Error('Unknown CiscoSensor selector attribute: ' . $attr);
+ $value = '';
+ }
+ }
+ elsif( $objType eq 'CiscoCPU' )
+ {
+ my $cpu = $data->{'ciscoCpuStats'}{$object};
+ if( $attr eq 'CPUName' )
+ {
+ $value = $cpu->{'cpu-nick'};
+ }
+ elsif( $attr eq 'CPUDescr' )
+ {
+ $value = $cpu->{'cpu-descr'};
+ }
+ else
+ {
+ Error('Unknown CiscoCPU selector attribute: ' . $attr);
+ $value = '';
+ }
+ }
+
+ return eval( '$value' . ' ' . $operator . '$checkval' ) ? 1:0;
+}
+
+
+sub getSelectorObjectName
+{
+ my $devdetails = shift;
+ my $object = shift;
+ my $objType = shift;
+
+ my $data = $devdetails->data();
+ my $name;
+
+ if( $objType eq 'CiscoSensor' )
+ {
+ $name = $data->{'ciscoTemperatureSensors'}{$object}{'description'};
+ }
+ elsif( $objType eq 'CiscoCPU' )
+ {
+ $name = $data->{'ciscoCpuStats'}{$object}{'cpu-nick'};
+ }
+ return $name;
+}
+
+
+my %knownSelectorActions =
+ (
+ 'CiscoSensor' => {
+ 'Monitor' => 1,
+ 'TokensetMember' => 1 },
+ 'CiscoCPU' => {
+ 'TokensetMember' => 1 }
+ );
+
+
+sub applySelectorAction
+{
+ my $devdetails = shift;
+ my $object = shift;
+ my $objType = shift;
+ my $action = shift;
+ my $arg = shift;
+
+ my $data = $devdetails->data();
+ my $objref;
+ if( $objType eq 'CiscoSensor' )
+ {
+ $objref = $data->{'ciscoTemperatureSensors'}{$object};
+ }
+ elsif( $objType eq 'CiscoCPU' )
+ {
+ $objref = $data->{'ciscoCpuStats'}{$object};
+ }
+
+ if( $knownSelectorActions{$objType}{$action} )
+ {
+ $objref->{'selectorActions'}{$action} = $arg;
+ }
+ else
+ {
+ Error('Unknown Cisco selector action: ' . $action);
+ }
+}
+
+
+
+1;
+
+
+# Local Variables:
+# mode: perl
+# indent-tabs-mode: nil
+# perl-indent-level: 4
+# End: