Merge remote-tracking branch 'upstream/master'
[torrus-plus.git] / src / lib / Torrus / DevDiscover / CiscoSCE.pm
blob7216a7db490bc41f1bdbba8cb9717693f6d5c65b
2 # Discovery module for Cisco Service Control Engine (formely PCube)
4 # Copyright (C) 2007 Jon Nistor
5 # Copyright (C) 2007 Stanislav Sinyagin
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.
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.
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.
21 # $Id$
22 # Jon Nistor <nistor at snickers dot org>
24 # NOTE: Options for this module
25 # CiscoSCE::disable-disk
26 # CiscoSCE::disable-gc
27 # CiscoSCE::disable-qos
28 # CiscoSCE::disable-rdr
29 # CiscoSCE::disable-subs
30 # CiscoSCE::disable-tp
33 # Cisco SCE devices discovery
34 package Torrus::DevDiscover::CiscoSCE;
36 use strict;
37 use warnings;
39 use Torrus::Log;
41 our $VERSION = 1.0;
43 $Torrus::DevDiscover::registry{'CiscoSCE'} = {
44 'sequence' => 500,
45 'checkdevtype' => \&checkdevtype,
46 'discover' => \&discover,
47 'buildConfig' => \&buildConfig
50 # pmodule-dependend OIDs are presented for module #1 only.
51 # currently devices with more than one module do not exist
53 our %oiddef =
55 # PCUBE-SE-MIB
56 'pcubeProducts' => '1.3.6.1.4.1.5655.1',
57 'pchassisSysType' => '1.3.6.1.4.1.5655.4.1.2.1.0',
58 'pchassisNumSlots' => '1.3.6.1.4.1.5655.4.1.2.6.0',
59 'pmoduleType' => '1.3.6.1.4.1.5655.4.1.3.1.1.2.1',
60 'pmoduleNumLinks' => '1.3.6.1.4.1.5655.4.1.3.1.1.7.1',
61 'pmoduleSerialNumber' => '1.3.6.1.4.1.5655.4.1.3.1.1.9.1',
62 'pmoduleNumTrafficProcessors' => '1.3.6.1.4.1.5655.4.1.3.1.1.3.1',
63 'rdrFormatterEnable' => '1.3.6.1.4.1.5655.4.1.6.1.0',
64 'rdrFormatterCategoryName' => '1.3.6.1.4.1.5655.4.1.6.11.1.2',
65 'subscribersNumIpAddrMappings' => '1.3.6.1.4.1.5655.4.1.8.1.1.3.1',
66 'subscribersNumIpRangeMappings' => '1.3.6.1.4.1.5655.4.1.8.1.1.5.1',
67 'subscribersNumVlanMappings' => '1.3.6.1.4.1.5655.4.1.8.1.1.7.1',
68 'subscribersNumAnonymous' => '1.3.6.1.4.1.5655.4.1.8.1.1.16.1',
69 'pportNumTxQueues' => '1.3.6.1.4.1.5655.4.1.10.1.1.4.1',
70 'pportIfIndex' => '1.3.6.1.4.1.5655.4.1.10.1.1.5.1',
71 'txQueuesDescription' => '1.3.6.1.4.1.5655.4.1.11.1.1.4.1',
73 # CISCO-SCAS-BB-MIB (PCUBE-ENGAGE-MIB)
74 'globalScopeServiceCounterName' => '1.3.6.1.4.1.5655.4.2.5.1.1.3.1',
78 our %sceChassisNames =
80 '1' => 'unknown',
81 '2' => 'SE 1000',
82 '3' => 'SE 100',
83 '4' => 'SE 2000',
86 our %sceModuleDesc =
88 '1' => 'unknown',
89 '2' => '2xGBE + 1xFE Mgmt',
90 '3' => '2xFE + 1xFE Mgmt',
91 '4' => '4xGBE + 1 or 2 FastE Mgmt',
92 '5' => '4xFE + 1xFE Mgmt',
93 '6' => '4xOC-12 + 1 or 2 FastE Mgmt',
94 '7' => '16xFE + 2xGBE, 2 FastE Mgmt',
97 sub checkdevtype
99 my $dd = shift;
100 my $devdetails = shift;
102 if( not $dd->oidBaseMatch
103 ( 'pcubeProducts',
104 $devdetails->snmpVar( $dd->oiddef('sysObjectID') ) ) )
106 return 0;
109 my $result = $dd->retrieveSnmpOIDs('pchassisNumSlots');
110 if( $result->{'pchassisNumSlots'} > 1 )
112 Error('This SCE device has more than one module on the chassis.' .
113 'The current version of DevDiscover does not support such ' .
114 'devices');
115 return 0;
118 $devdetails->setCap('interfaceIndexingPersistent');
120 return 1;
123 sub discover
125 my $dd = shift;
126 my $devdetails = shift;
128 my $session = $dd->session();
129 my $data = $devdetails->data();
131 # Get the system info and display it in the comment
132 my $sceInfo = $dd->retrieveSnmpOIDs
133 ( 'pchassisSysType', 'pmoduleType', 'pmoduleNumLinks',
134 'pmoduleSerialNumber', 'pmoduleNumTrafficProcessors',
135 'rdrFormatterEnable',
136 'subscribersNumIpAddrMappings', 'subscribersNumIpRangeMappings',
137 'subscribersNumVlanMappings', 'subscribersNumAnonymous' );
139 $data->{'sceInfo'} = $sceInfo;
141 $data->{'param'}{'comment'} =
142 $sceChassisNames{$sceInfo->{'pchassisSysType'}} .
143 " chassis, " . $sceModuleDesc{$sceInfo->{'pmoduleType'}} .
144 ", Hw Serial#: " . $sceInfo->{'pmoduleSerialNumber'};
146 # TP: Traffic Processor
147 if( $devdetails->paramDisabled('CiscoSCE::disable-tp') )
149 $devdetails->setCap('sceTP');
151 $data->{'sceTrafficProcessors'} =
152 $sceInfo->{'pmoduleNumTrafficProcessors'};
155 # HDD: Disk Usage
156 if( $devdetails->paramDisabled('CiscoSCE::disable-disk') )
158 $devdetails->setCap('sceDisk');
161 # SUBS: subscriber aware configuration
162 if( $devdetails->paramDisabled('CiscoSCE::disable-subs') )
164 if( $sceInfo->{'subscribersNumIpAddrMappings'} > 0 or
165 $sceInfo->{'subscribersNumIpRangeMappings'} > 0 or
166 $sceInfo->{'subscribersNumVlanMappings'} > 0 or
167 $sceInfo->{'subscribersNumAnonymous'} > 0 )
169 $devdetails->setCap('sceSubscribers');
174 # QOS: TX Queues Names
175 if( $devdetails->paramDisabled('CiscoSCE::disable-qos') )
177 $devdetails->setCap('sceQos');
179 # Get the names of TX queues
180 my $txQueueNum = $session->get_table
181 ( -baseoid => $dd->oiddef('pportNumTxQueues') );
182 $devdetails->storeSnmpVars( $txQueueNum );
184 my $ifIndexTable = $session->get_table
185 ( -baseoid => $dd->oiddef('pportIfIndex') );
187 my $txQueueDesc = $session->get_table
188 ( -baseoid => $dd->oiddef('txQueuesDescription') );
190 $devdetails->storeSnmpVars( $txQueueDesc );
192 for my $pIndex
193 ( $devdetails->getSnmpIndices( $dd->oiddef('pportNumTxQueues') ) )
195 # We take ports with more than one queue and add queueing
196 # statistics to interface counters
197 if( $txQueueNum->{$dd->oiddef('pportNumTxQueues') .
198 '.' . $pIndex} > 1 )
200 # We need the ifIndex to retrieve the interface name
202 my $ifIndex =
203 $ifIndexTable->{$dd->oiddef('pportIfIndex') . '.'
204 . $pIndex};
206 $data->{'scePortIfIndex'}{$pIndex} = $ifIndex;
208 for my $qIndex
209 ( $devdetails->getSnmpIndices
210 ( $dd->oiddef('txQueuesDescription') . '.' . $pIndex ) )
212 my $oid = $dd->oiddef('txQueuesDescription') . '.' .
213 $pIndex . '.' . $qIndex;
215 $data->{'sceQueues'}{$pIndex}{$qIndex} =
216 $txQueueDesc->{$oid};
223 # GC: Global Service Counters
224 if( $devdetails->paramDisabled('CiscoSCE::disable-gc') )
226 # Set the Capability for the Global Counters
227 $devdetails->setCap('sceGlobalCounters');
229 my $counterNames = $session->get_table
230 ( -baseoid => $dd->oiddef('globalScopeServiceCounterName') );
232 $devdetails->storeSnmpVars( $counterNames );
234 for my $gcIndex
235 ( $devdetails->getSnmpIndices
236 ( $dd->oiddef('globalScopeServiceCounterName') ) )
238 my $oid =
239 $dd->oiddef('globalScopeServiceCounterName') . '.' . $gcIndex;
240 my $cName = $counterNames->{$oid};
242 if( defined($cName) and $cName ne '' )
244 $data->{'sceGlobalCounters'}{$gcIndex} = $cName;
250 # RDR: Raw Data Record
251 if( $devdetails->paramDisabled('CiscoSCE::disable-rdr') )
253 if( $sceInfo->{'rdrFormatterEnable'} > 0 )
255 # Set Capability for the RDR section of XML
256 $devdetails->setCap('sceRDR');
258 # Get the names of the RDR Category
259 my $categoryNames = $session->get_table
260 ( -baseoid => $dd->oiddef('rdrFormatterCategoryName') );
262 $devdetails->storeSnmpVars( $categoryNames );
264 for my $categoryIndex
265 ( $devdetails->getSnmpIndices
266 ( $dd->oiddef('rdrFormatterCategoryName') ) )
268 my $oid = $dd->oiddef('rdrFormatterCategoryName') . '.'
269 . $categoryIndex;
270 $data->{'sceRDR'}{$categoryIndex} = $categoryNames->{$oid};
275 return 1;
279 sub buildConfig
281 my $devdetails = shift;
282 my $cb = shift;
283 my $devNode = shift;
284 my $data = $devdetails->data();
286 # Disk Usage information
287 if( $devdetails->hasCap('sceDisk') )
289 $cb->addTemplateApplication($devNode, 'CiscoSCE::cisco-sce-disk');
292 if( $devdetails->hasCap('sceSubscribers') )
294 $cb->addTemplateApplication($devNode,
295 'CiscoSCE::cisco-sce-subscribers');
298 # Traffic processors subtree
299 if( $devdetails->hasCap('sceTP') )
301 my $tpNode = $cb->addSubtree( $devNode, 'SCE_TrafficProcessors',
302 { 'comment' => 'TP usage statistics' },
303 [ 'CiscoSCE::cisco-sce-tp-subtree']);
305 for my $tp ( 1 .. $data->{'sceTrafficProcessors'} )
307 $cb->addSubtree( $tpNode, sprintf('TP_%d', $tp),
308 { 'sce-tp-index' => $tp },
309 ['CiscoSCE::cisco-sce-tp'] );
314 # QoS queues
315 if( $devdetails->hasCap('sceQos') )
317 # Queues subtree
318 my $qNode =
319 $cb->addSubtree( $devNode, 'SCE_Queues',
320 { 'comment' => 'TX queues usage statistics' },
321 [ 'CiscoSCE::cisco-sce-queues-subtree']);
323 for my $pIndex ( sort {$a <=> $b}
324 keys %{$data->{'scePortIfIndex'}} )
326 my $ifIndex = $data->{'scePortIfIndex'}{$pIndex};
327 my $interface = $data->{'interfaces'}{$ifIndex};
329 my $portNode =
330 $cb->addSubtree
331 ( $qNode,
332 $interface->{$data->{'nameref'}{'ifSubtreeName'}},
333 { 'sce-port-index' => $pIndex,
334 'precedence' => 1000 - $pIndex });
336 for my $qIndex ( sort {$a <=> $b} keys
337 %{$data->{'sceQueues'}{$pIndex}} )
339 my $qName = $data->{'sceQueues'}{$pIndex}{$qIndex};
340 my $subtreeName = 'Q' . $qIndex;
342 $cb->addLeaf( $portNode, $subtreeName,
343 { 'sce-queue-index' => $qIndex,
344 'comment' => $qName,
345 'precedence' => 1000 - $qIndex });
348 } # hasCap sceQos
351 # Global counters
352 if( $devdetails->hasCap('sceGlobalCounters') )
354 for my $linkIndex ( 1 .. $data->{'sceInfo'}{'pmoduleNumLinks'} )
356 my $gcNode =
357 $cb->addSubtree( $devNode,
358 'SCE_Global_Counters_L' . $linkIndex,
359 { 'comment' =>
360 'Global service counters for link #'
361 . $linkIndex
363 [ 'CiscoSCE::cisco-sce-gc-subtree']);
365 for my $gcIndex
366 ( sort {$a <=> $b} keys %{$data->{'sceGlobalCounters'}} )
368 my $srvName = $data->{'sceGlobalCounters'}{$gcIndex};
369 my $subtreeName = $srvName;
370 $subtreeName =~ s/\W/_/g;
372 $cb->addSubtree( $gcNode, $subtreeName,
373 { 'sce-link-index' => $linkIndex,
374 'sce-gc-index' => $gcIndex,
375 'comment' => $srvName,
376 'sce-service-name' => $srvName,
377 'precedence' => 1000 - $gcIndex,
378 'searchable' => 'yes'},
379 [ 'CiscoSCE::cisco-sce-gcounter' ]);
382 } # END hasCap sceGlobalCounters
385 # RDR Formatter reports
386 if( $devdetails->hasCap('sceRDR') )
388 $cb->addTemplateApplication($devNode, 'CiscoSCE::cisco-sce-rdr');
390 # Add a Subtree for "SCE_RDR_Categories"
391 my $rdrNode =
392 $cb->addSubtree( $devNode, 'SCE_RDR_Categories',
393 { 'comment' => 'Raw Data Records per Category' },
394 [ 'CiscoSCE::cisco-sce-rdr-category-subtree' ]);
396 for my $cIndex ( sort {$a <=> $b} keys %{$data->{'sceRDR'}} )
398 my $categoryName;
399 if ( $data->{'sceRDR'}{$cIndex} )
401 $categoryName = $data->{'sceRDR'}{$cIndex};
403 else
405 $categoryName = 'Category_' . $cIndex;
408 $cb->addSubtree( $rdrNode, 'Category_' . $cIndex,
409 { 'precedence' => 1000 - $cIndex,
410 'sce-rdr-index' => $cIndex,
411 'sce-rdr-comment' => $categoryName },
412 ['CiscoSCE::cisco-sce-rdr-category'] );
414 } # END hasCap sceRDR
416 return;
421 # Local Variables:
422 # mode: perl
423 # indent-tabs-mode: nil
424 # perl-indent-level: 4
425 # End: