bury all dead whitespace, better off to just do it in one command. i wonder why ss...
[torrus-plus.git] / src / lib / Torrus / DevDiscover / CiscoSCE.pm
blobd393e5c6dae09f69cc0c72ec5b9fd7966350fa51
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 # Jon Nistor <nistor at snickers dot org>
23 # NOTE: Options for this module
24 # CiscoSCE::disable-disk
25 # CiscoSCE::disable-gc
26 # CiscoSCE::disable-qos
27 # CiscoSCE::disable-rdr
28 # CiscoSCE::disable-subs
29 # CiscoSCE::disable-tp
32 # Cisco SCE devices discovery
33 package Torrus::DevDiscover::CiscoSCE;
35 use strict;
36 use warnings;
38 use Torrus::Log;
40 our $VERSION = 1.0;
42 $Torrus::DevDiscover::registry{'CiscoSCE'} = {
43 'sequence' => 500,
44 'checkdevtype' => \&checkdevtype,
45 'discover' => \&discover,
46 'buildConfig' => \&buildConfig
49 # pmodule-dependend OIDs are presented for module #1 only.
50 # currently devices with more than one module do not exist
52 our %oiddef =
54 # PCUBE-SE-MIB
55 'pcubeProducts' => '1.3.6.1.4.1.5655.1',
56 'pchassisSysType' => '1.3.6.1.4.1.5655.4.1.2.1.0',
57 'pchassisNumSlots' => '1.3.6.1.4.1.5655.4.1.2.6.0',
58 'pmoduleType' => '1.3.6.1.4.1.5655.4.1.3.1.1.2.1',
59 'pmoduleNumLinks' => '1.3.6.1.4.1.5655.4.1.3.1.1.7.1',
60 'pmoduleSerialNumber' => '1.3.6.1.4.1.5655.4.1.3.1.1.9.1',
61 'pmoduleNumTrafficProcessors' => '1.3.6.1.4.1.5655.4.1.3.1.1.3.1',
62 'rdrFormatterEnable' => '1.3.6.1.4.1.5655.4.1.6.1.0',
63 'rdrFormatterCategoryName' => '1.3.6.1.4.1.5655.4.1.6.11.1.2',
64 'subscribersNumIpAddrMappings' => '1.3.6.1.4.1.5655.4.1.8.1.1.3.1',
65 'subscribersNumIpRangeMappings' => '1.3.6.1.4.1.5655.4.1.8.1.1.5.1',
66 'subscribersNumVlanMappings' => '1.3.6.1.4.1.5655.4.1.8.1.1.7.1',
67 'subscribersNumAnonymous' => '1.3.6.1.4.1.5655.4.1.8.1.1.16.1',
68 'pportNumTxQueues' => '1.3.6.1.4.1.5655.4.1.10.1.1.4.1',
69 'pportIfIndex' => '1.3.6.1.4.1.5655.4.1.10.1.1.5.1',
70 'txQueuesDescription' => '1.3.6.1.4.1.5655.4.1.11.1.1.4.1',
72 # CISCO-SCAS-BB-MIB (PCUBE-ENGAGE-MIB)
73 'globalScopeServiceCounterName' => '1.3.6.1.4.1.5655.4.2.5.1.1.3.1',
77 our %sceChassisNames =
79 '1' => 'unknown',
80 '2' => 'SE 1000',
81 '3' => 'SE 100',
82 '4' => 'SE 2000',
85 our %sceModuleDesc =
87 '1' => 'unknown',
88 '2' => '2xGBE + 1xFE Mgmt',
89 '3' => '2xFE + 1xFE Mgmt',
90 '4' => '4xGBE + 1 or 2 FastE Mgmt',
91 '5' => '4xFE + 1xFE Mgmt',
92 '6' => '4xOC-12 + 1 or 2 FastE Mgmt',
93 '7' => '16xFE + 2xGBE, 2 FastE Mgmt',
96 sub checkdevtype
98 my $dd = shift;
99 my $devdetails = shift;
101 if( not $dd->oidBaseMatch
102 ( 'pcubeProducts',
103 $devdetails->snmpVar( $dd->oiddef('sysObjectID') ) ) )
105 return 0;
108 my $result = $dd->retrieveSnmpOIDs('pchassisNumSlots');
109 if( $result->{'pchassisNumSlots'} > 1 )
111 Error('This SCE device has more than one module on the chassis.' .
112 'The current version of DevDiscover does not support such ' .
113 'devices');
114 return 0;
117 $devdetails->setCap('interfaceIndexingPersistent');
119 return 1;
122 sub discover
124 my $dd = shift;
125 my $devdetails = shift;
127 my $session = $dd->session();
128 my $data = $devdetails->data();
130 # Get the system info and display it in the comment
131 my $sceInfo = $dd->retrieveSnmpOIDs
132 ( 'pchassisSysType', 'pmoduleType', 'pmoduleNumLinks',
133 'pmoduleSerialNumber', 'pmoduleNumTrafficProcessors',
134 'rdrFormatterEnable',
135 'subscribersNumIpAddrMappings', 'subscribersNumIpRangeMappings',
136 'subscribersNumVlanMappings', 'subscribersNumAnonymous' );
138 $data->{'sceInfo'} = $sceInfo;
140 $data->{'param'}{'comment'} =
141 $sceChassisNames{$sceInfo->{'pchassisSysType'}} .
142 " chassis, " . $sceModuleDesc{$sceInfo->{'pmoduleType'}} .
143 ", Hw Serial#: " . $sceInfo->{'pmoduleSerialNumber'};
145 # TP: Traffic Processor
146 if( $devdetails->paramDisabled('CiscoSCE::disable-tp') )
148 $devdetails->setCap('sceTP');
150 $data->{'sceTrafficProcessors'} =
151 $sceInfo->{'pmoduleNumTrafficProcessors'};
154 # HDD: Disk Usage
155 if( $devdetails->paramDisabled('CiscoSCE::disable-disk') )
157 $devdetails->setCap('sceDisk');
160 # SUBS: subscriber aware configuration
161 if( $devdetails->paramDisabled('CiscoSCE::disable-subs') )
163 if( $sceInfo->{'subscribersNumIpAddrMappings'} > 0 or
164 $sceInfo->{'subscribersNumIpRangeMappings'} > 0 or
165 $sceInfo->{'subscribersNumVlanMappings'} > 0 or
166 $sceInfo->{'subscribersNumAnonymous'} > 0 )
168 $devdetails->setCap('sceSubscribers');
173 # QOS: TX Queues Names
174 if( $devdetails->paramDisabled('CiscoSCE::disable-qos') )
176 $devdetails->setCap('sceQos');
178 # Get the names of TX queues
179 my $txQueueNum = $session->get_table
180 ( -baseoid => $dd->oiddef('pportNumTxQueues') );
181 $devdetails->storeSnmpVars( $txQueueNum );
183 my $ifIndexTable = $session->get_table
184 ( -baseoid => $dd->oiddef('pportIfIndex') );
186 my $txQueueDesc = $session->get_table
187 ( -baseoid => $dd->oiddef('txQueuesDescription') );
189 $devdetails->storeSnmpVars( $txQueueDesc );
191 for my $pIndex
192 ( $devdetails->getSnmpIndices( $dd->oiddef('pportNumTxQueues') ) )
194 # We take ports with more than one queue and add queueing
195 # statistics to interface counters
196 if( $txQueueNum->{$dd->oiddef('pportNumTxQueues') .
197 '.' . $pIndex} > 1 )
199 # We need the ifIndex to retrieve the interface name
201 my $ifIndex =
202 $ifIndexTable->{$dd->oiddef('pportIfIndex') . '.'
203 . $pIndex};
205 $data->{'scePortIfIndex'}{$pIndex} = $ifIndex;
207 for my $qIndex
208 ( $devdetails->getSnmpIndices
209 ( $dd->oiddef('txQueuesDescription') . '.' . $pIndex ) )
211 my $oid = $dd->oiddef('txQueuesDescription') . '.' .
212 $pIndex . '.' . $qIndex;
214 $data->{'sceQueues'}{$pIndex}{$qIndex} =
215 $txQueueDesc->{$oid};
222 # GC: Global Service Counters
223 if( $devdetails->paramDisabled('CiscoSCE::disable-gc') )
225 # Set the Capability for the Global Counters
226 $devdetails->setCap('sceGlobalCounters');
228 my $counterNames = $session->get_table
229 ( -baseoid => $dd->oiddef('globalScopeServiceCounterName') );
231 $devdetails->storeSnmpVars( $counterNames );
233 for my $gcIndex
234 ( $devdetails->getSnmpIndices
235 ( $dd->oiddef('globalScopeServiceCounterName') ) )
237 my $oid =
238 $dd->oiddef('globalScopeServiceCounterName') . '.' . $gcIndex;
239 my $cName = $counterNames->{$oid};
241 if( defined($cName) and $cName ne '' )
243 $data->{'sceGlobalCounters'}{$gcIndex} = $cName;
249 # RDR: Raw Data Record
250 if( $devdetails->paramDisabled('CiscoSCE::disable-rdr') )
252 if( $sceInfo->{'rdrFormatterEnable'} > 0 )
254 # Set Capability for the RDR section of XML
255 $devdetails->setCap('sceRDR');
257 # Get the names of the RDR Category
258 my $categoryNames = $session->get_table
259 ( -baseoid => $dd->oiddef('rdrFormatterCategoryName') );
261 $devdetails->storeSnmpVars( $categoryNames );
263 for my $categoryIndex
264 ( $devdetails->getSnmpIndices
265 ( $dd->oiddef('rdrFormatterCategoryName') ) )
267 my $oid = $dd->oiddef('rdrFormatterCategoryName') . '.'
268 . $categoryIndex;
269 $data->{'sceRDR'}{$categoryIndex} = $categoryNames->{$oid};
274 return 1;
278 sub buildConfig
280 my $devdetails = shift;
281 my $cb = shift;
282 my $devNode = shift;
283 my $data = $devdetails->data();
285 # Disk Usage information
286 if( $devdetails->hasCap('sceDisk') )
288 $cb->addTemplateApplication($devNode, 'CiscoSCE::cisco-sce-disk');
291 if( $devdetails->hasCap('sceSubscribers') )
293 $cb->addTemplateApplication($devNode,
294 'CiscoSCE::cisco-sce-subscribers');
297 # Traffic processors subtree
298 if( $devdetails->hasCap('sceTP') )
300 my $tpNode = $cb->addSubtree( $devNode, 'SCE_TrafficProcessors',
301 { 'comment' => 'TP usage statistics' },
302 [ 'CiscoSCE::cisco-sce-tp-subtree']);
304 for my $tp ( 1 .. $data->{'sceTrafficProcessors'} )
306 $cb->addSubtree( $tpNode, sprintf('TP_%d', $tp),
307 { 'sce-tp-index' => $tp },
308 ['CiscoSCE::cisco-sce-tp'] );
313 # QoS queues
314 if( $devdetails->hasCap('sceQos') )
316 # Queues subtree
317 my $qNode =
318 $cb->addSubtree( $devNode, 'SCE_Queues',
319 { 'comment' => 'TX queues usage statistics' },
320 [ 'CiscoSCE::cisco-sce-queues-subtree']);
322 for my $pIndex ( sort {$a <=> $b}
323 keys %{$data->{'scePortIfIndex'}} )
325 my $ifIndex = $data->{'scePortIfIndex'}{$pIndex};
326 my $interface = $data->{'interfaces'}{$ifIndex};
328 my $portNode =
329 $cb->addSubtree
330 ( $qNode,
331 $interface->{$data->{'nameref'}{'ifSubtreeName'}},
332 { 'sce-port-index' => $pIndex,
333 'precedence' => 1000 - $pIndex });
335 for my $qIndex ( sort {$a <=> $b} keys
336 %{$data->{'sceQueues'}{$pIndex}} )
338 my $qName = $data->{'sceQueues'}{$pIndex}{$qIndex};
339 my $subtreeName = 'Q' . $qIndex;
341 $cb->addLeaf( $portNode, $subtreeName,
342 { 'sce-queue-index' => $qIndex,
343 'comment' => $qName,
344 'precedence' => 1000 - $qIndex });
347 } # hasCap sceQos
350 # Global counters
351 if( $devdetails->hasCap('sceGlobalCounters') )
353 for my $linkIndex ( 1 .. $data->{'sceInfo'}{'pmoduleNumLinks'} )
355 my $gcNode =
356 $cb->addSubtree( $devNode,
357 'SCE_Global_Counters_L' . $linkIndex,
358 { 'comment' =>
359 'Global service counters for link #'
360 . $linkIndex
362 [ 'CiscoSCE::cisco-sce-gc-subtree']);
364 for my $gcIndex
365 ( sort {$a <=> $b} keys %{$data->{'sceGlobalCounters'}} )
367 my $srvName = $data->{'sceGlobalCounters'}{$gcIndex};
368 my $subtreeName = $srvName;
369 $subtreeName =~ s/\W/_/g;
371 $cb->addSubtree( $gcNode, $subtreeName,
372 { 'sce-link-index' => $linkIndex,
373 'sce-gc-index' => $gcIndex,
374 'comment' => $srvName,
375 'sce-service-name' => $srvName,
376 'precedence' => 1000 - $gcIndex,
377 'searchable' => 'yes'},
378 [ 'CiscoSCE::cisco-sce-gcounter' ]);
381 } # END hasCap sceGlobalCounters
384 # RDR Formatter reports
385 if( $devdetails->hasCap('sceRDR') )
387 $cb->addTemplateApplication($devNode, 'CiscoSCE::cisco-sce-rdr');
389 # Add a Subtree for "SCE_RDR_Categories"
390 my $rdrNode =
391 $cb->addSubtree( $devNode, 'SCE_RDR_Categories',
392 { 'comment' => 'Raw Data Records per Category' },
393 [ 'CiscoSCE::cisco-sce-rdr-category-subtree' ]);
395 for my $cIndex ( sort {$a <=> $b} keys %{$data->{'sceRDR'}} )
397 my $categoryName;
398 if ( $data->{'sceRDR'}{$cIndex} )
400 $categoryName = $data->{'sceRDR'}{$cIndex};
402 else
404 $categoryName = 'Category_' . $cIndex;
407 $cb->addSubtree( $rdrNode, 'Category_' . $cIndex,
408 { 'precedence' => 1000 - $cIndex,
409 'sce-rdr-index' => $cIndex,
410 'sce-rdr-comment' => $categoryName },
411 ['CiscoSCE::cisco-sce-rdr-category'] );
413 } # END hasCap sceRDR
415 return;
420 # Local Variables:
421 # mode: perl
422 # indent-tabs-mode: nil
423 # perl-indent-level: 4
424 # End: