diff options
Diffstat (limited to 'torrus/perllib/Torrus/DevDiscover/CiscoSCE.pm')
-rw-r--r-- | torrus/perllib/Torrus/DevDiscover/CiscoSCE.pm | 418 |
1 files changed, 418 insertions, 0 deletions
diff --git a/torrus/perllib/Torrus/DevDiscover/CiscoSCE.pm b/torrus/perllib/Torrus/DevDiscover/CiscoSCE.pm new file mode 100644 index 000000000..e9d200347 --- /dev/null +++ b/torrus/perllib/Torrus/DevDiscover/CiscoSCE.pm @@ -0,0 +1,418 @@ +# +# Discovery module for Cisco Service Control Engine (formely PCube) +# +# Copyright (C) 2007 Jon Nistor +# Copyright (C) 2007 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: CiscoSCE.pm,v 1.1 2010-12-27 00:03:56 ivan Exp $ +# Jon Nistor <nistor at snickers dot org> +# +# NOTE: Options for this module +# CiscoSCE::disable-disk +# CiscoSCE::disable-gc +# CiscoSCE::disable-qos +# CiscoSCE::disable-rdr +# CiscoSCE::disable-subs +# CiscoSCE::disable-tp +# + +# Cisco SCE devices discovery +package Torrus::DevDiscover::CiscoSCE; + +use strict; +use Torrus::Log; + + +$Torrus::DevDiscover::registry{'CiscoSCE'} = { + 'sequence' => 500, + 'checkdevtype' => \&checkdevtype, + 'discover' => \&discover, + 'buildConfig' => \&buildConfig +}; + +# pmodule-dependend OIDs are presented for module #1 only. +# currently devices with more than one module do not exist + +our %oiddef = + ( + # PCUBE-SE-MIB + 'pcubeProducts' => '1.3.6.1.4.1.5655.1', + 'pchassisSysType' => '1.3.6.1.4.1.5655.4.1.2.1.0', + 'pchassisNumSlots' => '1.3.6.1.4.1.5655.4.1.2.6.0', + 'pmoduleType' => '1.3.6.1.4.1.5655.4.1.3.1.1.2.1', + 'pmoduleNumLinks' => '1.3.6.1.4.1.5655.4.1.3.1.1.7.1', + 'pmoduleSerialNumber' => '1.3.6.1.4.1.5655.4.1.3.1.1.9.1', + 'pmoduleNumTrafficProcessors' => '1.3.6.1.4.1.5655.4.1.3.1.1.3.1', + 'rdrFormatterEnable' => '1.3.6.1.4.1.5655.4.1.6.1.0', + 'rdrFormatterCategoryName' => '1.3.6.1.4.1.5655.4.1.6.11.1.2', + 'subscribersNumIpAddrMappings' => '1.3.6.1.4.1.5655.4.1.8.1.1.3.1', + 'subscribersNumIpRangeMappings' => '1.3.6.1.4.1.5655.4.1.8.1.1.5.1', + 'subscribersNumVlanMappings' => '1.3.6.1.4.1.5655.4.1.8.1.1.7.1', + 'subscribersNumAnonymous' => '1.3.6.1.4.1.5655.4.1.8.1.1.16.1', + 'pportNumTxQueues' => '1.3.6.1.4.1.5655.4.1.10.1.1.4.1', + 'pportIfIndex' => '1.3.6.1.4.1.5655.4.1.10.1.1.5.1', + 'txQueuesDescription' => '1.3.6.1.4.1.5655.4.1.11.1.1.4.1', + + # CISCO-SCAS-BB-MIB (PCUBE-ENGAGE-MIB) + 'globalScopeServiceCounterName' => '1.3.6.1.4.1.5655.4.2.5.1.1.3.1', + + ); + +our %sceChassisNames = + ( + '1' => 'unknown', + '2' => 'SE 1000', + '3' => 'SE 100', + '4' => 'SE 2000', + ); + +our %sceModuleDesc = + ( + '1' => 'unknown', + '2' => '2xGBE + 1xFE Mgmt', + '3' => '2xFE + 1xFE Mgmt', + '4' => '4xGBE + 1 or 2 FastE Mgmt', + '5' => '4xFE + 1xFE Mgmt', + '6' => '4xOC-12 + 1 or 2 FastE Mgmt', + '7' => '16xFE + 2xGBE, 2 FastE Mgmt', + ); + +sub checkdevtype +{ + my $dd = shift; + my $devdetails = shift; + + if( not $dd->oidBaseMatch + ( 'pcubeProducts', + $devdetails->snmpVar( $dd->oiddef('sysObjectID') ) ) ) + { + return 0; + } + + my $result = $dd->retrieveSnmpOIDs('pchassisNumSlots'); + if( $result->{'pchassisNumSlots'} > 1 ) + { + Error('This SCE device has more than one module on the chassis.' . + 'The current version of DevDiscover does not support such ' . + 'devices'); + return 0; + } + + $devdetails->setCap('interfaceIndexingPersistent'); + + return 1; +} + +sub discover +{ + my $dd = shift; + my $devdetails = shift; + + my $session = $dd->session(); + my $data = $devdetails->data(); + + # Get the system info and display it in the comment + my $sceInfo = $dd->retrieveSnmpOIDs + ( 'pchassisSysType', 'pmoduleType', 'pmoduleNumLinks', + 'pmoduleSerialNumber', 'pmoduleNumTrafficProcessors', + 'rdrFormatterEnable', + 'subscribersNumIpAddrMappings', 'subscribersNumIpRangeMappings', + 'subscribersNumVlanMappings', 'subscribersNumAnonymous' ); + + $data->{'sceInfo'} = $sceInfo; + + $data->{'param'}{'comment'} = + $sceChassisNames{$sceInfo->{'pchassisSysType'}} . + " chassis, " . $sceModuleDesc{$sceInfo->{'pmoduleType'}} . + ", Hw Serial#: " . $sceInfo->{'pmoduleSerialNumber'}; + + # TP: Traffic Processor + if( $devdetails->param('CiscoSCE::disable-tp') ne 'yes' ) + { + $devdetails->setCap('sceTP'); + + $data->{'sceTrafficProcessors'} = + $sceInfo->{'pmoduleNumTrafficProcessors'}; + } + + # HDD: Disk Usage + if( $devdetails->param('CiscoSCE::disable-disk') ne 'yes' ) + { + $devdetails->setCap('sceDisk'); + } + + # SUBS: subscriber aware configuration + if( $devdetails->param('CiscoSCE::disable-subs') ne 'yes' ) + { + if( $sceInfo->{'subscribersNumIpAddrMappings'} > 0 or + $sceInfo->{'subscribersNumIpRangeMappings'} > 0 or + $sceInfo->{'subscribersNumVlanMappings'} > 0 or + $sceInfo->{'subscribersNumAnonymous'} > 0 ) + { + $devdetails->setCap('sceSubscribers'); + } + } + + + # QOS: TX Queues Names + if( $devdetails->param('CiscoSCE::disable-qos') ne 'yes' ) + { + $devdetails->setCap('sceQos'); + + # Get the names of TX queues + my $txQueueNum = $session->get_table + ( -baseoid => $dd->oiddef('pportNumTxQueues') ); + $devdetails->storeSnmpVars( $txQueueNum ); + + my $ifIndexTable = $session->get_table + ( -baseoid => $dd->oiddef('pportIfIndex') ); + + my $txQueueDesc = $session->get_table + ( -baseoid => $dd->oiddef('txQueuesDescription') ); + + $devdetails->storeSnmpVars( $txQueueDesc ); + + foreach my $pIndex + ( $devdetails->getSnmpIndices( $dd->oiddef('pportNumTxQueues') ) ) + { + # We take ports with more than one queue and add queueing + # statistics to interface counters + if( $txQueueNum->{$dd->oiddef('pportNumTxQueues') . + '.' . $pIndex} > 1 ) + { + # We need the ifIndex to retrieve the interface name + + my $ifIndex = + $ifIndexTable->{$dd->oiddef('pportIfIndex') . '.' + . $pIndex}; + + $data->{'scePortIfIndex'}{$pIndex} = $ifIndex; + + foreach my $qIndex + ( $devdetails->getSnmpIndices + ( $dd->oiddef('txQueuesDescription') . '.' . $pIndex ) ) + { + my $oid = $dd->oiddef('txQueuesDescription') . '.' . + $pIndex . '.' . $qIndex; + + $data->{'sceQueues'}{$pIndex}{$qIndex} = + $txQueueDesc->{$oid}; + } + } + } + } + + + # GC: Global Service Counters + if( $devdetails->param('CiscoSCE::disable-gc') ne 'yes' ) + { + # Set the Capability for the Global Counters + $devdetails->setCap('sceGlobalCounters'); + + my $counterNames = $session->get_table + ( -baseoid => $dd->oiddef('globalScopeServiceCounterName') ); + + $devdetails->storeSnmpVars( $counterNames ); + + foreach my $gcIndex + ( $devdetails->getSnmpIndices + ( $dd->oiddef('globalScopeServiceCounterName') ) ) + { + my $oid = + $dd->oiddef('globalScopeServiceCounterName') . '.' . $gcIndex; + if( length( $counterNames->{$oid} ) > 0 ) + { + $data->{'sceGlobalCounters'}{$gcIndex} = $counterNames->{$oid}; + } + } + } + + + # RDR: Raw Data Record + if( $devdetails->param('CiscoSCE::disable-rdr') ne 'yes' ) + { + if( $sceInfo->{'rdrFormatterEnable'} > 0 ) + { + # Set Capability for the RDR section of XML + $devdetails->setCap('sceRDR'); + + # Get the names of the RDR Category + my $categoryNames = $session->get_table + ( -baseoid => $dd->oiddef('rdrFormatterCategoryName') ); + + $devdetails->storeSnmpVars( $categoryNames ); + + foreach my $categoryIndex + ( $devdetails->getSnmpIndices + ( $dd->oiddef('rdrFormatterCategoryName') ) ) + { + my $oid = $dd->oiddef('rdrFormatterCategoryName') . '.' + . $categoryIndex; + $data->{'sceRDR'}{$categoryIndex} = $categoryNames->{$oid}; + } + } + } + + return 1; +} + + +sub buildConfig +{ + my $devdetails = shift; + my $cb = shift; + my $devNode = shift; + my $data = $devdetails->data(); + + # Disk Usage information + if( $devdetails->hasCap('sceDisk') ) + { + $cb->addTemplateApplication($devNode, 'CiscoSCE::cisco-sce-disk'); + } + + if( $devdetails->hasCap('sceSubscribers') ) + { + $cb->addTemplateApplication($devNode, + 'CiscoSCE::cisco-sce-subscribers'); + } + + # Traffic processors subtree + if( $devdetails->hasCap('sceTP') ) + { + my $tpNode = $cb->addSubtree( $devNode, 'SCE_TrafficProcessors', + { 'comment' => 'TP usage statistics' }, + [ 'CiscoSCE::cisco-sce-tp-subtree']); + + foreach my $tp ( 1 .. $data->{'sceTrafficProcessors'} ) + { + $cb->addSubtree( $tpNode, sprintf('TP_%d', $tp), + { 'sce-tp-index' => $tp }, + ['CiscoSCE::cisco-sce-tp'] ); + } + } + + + # QoS queues + if( $devdetails->hasCap('sceQos') ) + { + # Queues subtree + my $qNode = + $cb->addSubtree( $devNode, 'SCE_Queues', + { 'comment' => 'TX queues usage statistics' }, + [ 'CiscoSCE::cisco-sce-queues-subtree']); + + foreach my $pIndex ( sort {$a <=> $b} + keys %{$data->{'scePortIfIndex'}} ) + { + my $ifIndex = $data->{'scePortIfIndex'}{$pIndex}; + my $interface = $data->{'interfaces'}{$ifIndex}; + + my $portNode = + $cb->addSubtree + ( $qNode, + $interface->{$data->{'nameref'}{'ifSubtreeName'}}, + { 'sce-port-index' => $pIndex, + 'precedence' => 1000 - $pIndex }); + + foreach my $qIndex ( sort {$a <=> $b} keys + %{$data->{'sceQueues'}{$pIndex}} ) + { + my $qName = $data->{'sceQueues'}{$pIndex}{$qIndex}; + my $subtreeName = 'Q' . $qIndex; + + $cb->addLeaf( $portNode, $subtreeName, + { 'sce-queue-index' => $qIndex, + 'comment' => $qName, + 'precedence' => 1000 - $qIndex }); + } + } + } # hasCap sceQos + + + # Global counters + if( $devdetails->hasCap('sceGlobalCounters') ) + { + foreach my $linkIndex ( 1 .. $data->{'sceInfo'}{'pmoduleNumLinks'} ) + { + my $gcNode = + $cb->addSubtree( $devNode, + 'SCE_Global_Counters_L' . $linkIndex, + { 'comment' => + 'Global service counters for link #' + . $linkIndex + }, + [ 'CiscoSCE::cisco-sce-gc-subtree']); + + foreach my $gcIndex + ( sort {$a <=> $b} keys %{$data->{'sceGlobalCounters'}} ) + { + my $srvName = $data->{'sceGlobalCounters'}{$gcIndex}; + my $subtreeName = $srvName; + $subtreeName =~ s/\W/_/g; + + $cb->addSubtree( $gcNode, $subtreeName, + { 'sce-link-index' => $linkIndex, + 'sce-gc-index' => $gcIndex, + 'comment' => $srvName, + 'sce-service-name' => $srvName, + 'precedence' => 1000 - $gcIndex, + 'searchable' => 'yes'}, + [ 'CiscoSCE::cisco-sce-gcounter' ]); + } + } + } # END hasCap sceGlobalCounters + + + # RDR Formatter reports + if( $devdetails->hasCap('sceRDR') ) + { + $cb->addTemplateApplication($devNode, 'CiscoSCE::cisco-sce-rdr'); + + # Add a Subtree for "SCE_RDR_Categories" + my $rdrNode = + $cb->addSubtree( $devNode, 'SCE_RDR_Categories', + { 'comment' => 'Raw Data Records per Category' }, + [ 'CiscoSCE::cisco-sce-rdr-category-subtree' ]); + + foreach my $cIndex ( sort {$a <=> $b} keys %{$data->{'sceRDR'}} ) + { + my $categoryName; + if ( $data->{'sceRDR'}{$cIndex} ) + { + $categoryName = $data->{'sceRDR'}{$cIndex}; + } + else + { + $categoryName = 'Category_' . $cIndex; + } + + $cb->addSubtree( $rdrNode, 'Category_' . $cIndex, + { 'precedence' => 1000 - $cIndex, + 'sce-rdr-index' => $cIndex, + 'sce-rdr-comment' => $categoryName }, + ['CiscoSCE::cisco-sce-rdr-category'] ); + } + } # END hasCap sceRDR +} + +1; + +# Local Variables: +# mode: perl +# indent-tabs-mode: nil +# perl-indent-level: 4 +# End: |