1 # Copyright (C) 2003 Shawn Ferry
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.
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.
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.
18 # Shawn Ferry <sferry at sevenspace dot com> <lalartu at obscure dot org>
20 # F5 BigIp Load Balancer
22 package Torrus
::DevDiscover
::F5BigIp
;
31 $Torrus::DevDiscover
::registry
{'F5BigIp'} = {
33 'checkdevtype' => \
&checkdevtype
,
34 'discover' => \
&discover
,
35 'buildConfig' => \
&buildConfig
41 'f5' => '1.3.6.1.4.1.3375',
43 '4.x_globalStatUptime' => '1.3.6.1.4.1.3375.1.1.1.2.1.0',
44 '3.x_uptime' => '1.3.6.1.4.1.3375.1.1.50.0',
46 '4.x_globalAttrProductCode' => '1.3.6.1.4.1.3375.1.1.1.1.5.0',
48 '4.x_virtualServer' => '1.3.6.1.4.1.3375.1.1.3',
49 '4.x_virtualServerNumber' => '1.3.6.1.4.1.3375.1.1.3.1.0',
50 '4.x_virtualServerTable' => '1.3.6.1.4.1.3375.1.1.3.2',
51 '4.x_virtualServerIp' => '1.3.6.1.4.1.3375.1.1.3.2.1.1',
52 '4.x_virtualServerPort' => '1.3.6.1.4.1.3375.1.1.3.2.1.2',
53 '4.x_virtualServerPool' => '1.3.6.1.4.1.3375.1.1.3.2.1.30',
55 '4.x_poolTable' => '1.3.6.1.4.1.3375.1.1.7.2',
56 '4.x_poolName' => '1.3.6.1.4.1.3375.1.1.7.2.1.1',
58 '4.x_poolMemberTable' => '1.3.6.1.4.1.3375.1.1.8.2',
59 '4.x_poolMemberPoolName' => '1.3.6.1.4.1.3375.1.1.8.2.1.1',
60 '4.x_poolMemberIpAddress' => '1.3.6.1.4.1.3375.1.1.8.2.1.2',
61 '4.x_poolMemberPort' => '1.3.6.1.4.1.3375.1.1.8.2.1.3',
63 '4.x_sslProxyTable' => '1.3.6.1.4.1.3375.1.1.9.2.1',
64 '4.x_sslProxyOrigIpAddress' => '1.3.6.1.4.1.3375.1.1.9.2.1.1',
65 '4.x_sslProxyOrigPort' => '1.3.6.1.4.1.3375.1.1.9.2.1.2',
66 '4.x_sslProxyDestIpAddress' => '1.3.6.1.4.1.3375.1.1.9.2.1.3',
67 '4.x_sslProxyDestPort' => '1.3.6.1.4.1.3375.1.1.9.2.1.4',
68 '4.x_sslProxyConnLimit' => '1.3.6.1.4.1.3375.1.1.9.2.1.23',
72 # from https://secure.f5.com/validate/help.jsp
73 #HA (BIG-IP high availability software)
74 #3DNS (3-DNS software)
75 #LC (BIG-IP Link Controller software)
76 #LB (BIG-IP Load Balancer 520)
77 #FLB (BIG-IP FireGuard 520)
78 #CLB (BIG-IP Cache Load Balancer 520)
79 #SSL (BIG-IP eCommerce Load Balancer 520)
80 #XLB (BIG-IP user-defined special purpose product for 520 platforms)
81 #ISMAN (iControl Services Manager)
84 '1' => { 'product' => 'indeterminate', 'supported' => 0, },
85 '2' => { 'product' => 'ha', 'supported' => 1, },
86 '3' => { 'product' => 'lb', 'supported' => 1, },
87 '4' => { 'product' => 'threedns', 'supported' => 0, },
88 '5' => { 'product' => 'flb', 'supported' => 0, },
89 '6' => { 'product' => 'clb', 'supported' => 0, },
90 '7' => { 'product' => 'xlb', 'supported' => 0, },
91 '8' => { 'product' => 'ssl', 'supported' => 1, },
92 '10' => { 'product' => 'test', 'supported' => 0, },
93 '99' => { 'product' => 'unsupported', 'supported' => 0, },
96 our %f5_sslGatewayLevel = (
106 '99' => 'unsupported',
115 my $devdetails = shift;
116 my $data = $devdetails->data();
118 # You would think globalAttrProductCode would work well
119 # I need more examples to see if ha(2) is specific to
120 # BipIP HA or any ha f5 product
122 if( not $dd->checkSnmpTable( 'f5' ) )
134 my $devdetails = shift;
136 my $session = $dd->session();
137 my $data = $devdetails->data();
139 # SNMP on F5 boxes will become unresponsive over time with large
140 # enough oids-per-pdu values. 10 appears to work for everything however
141 # no exhaustive testing has been done to determine if a higer number
143 if( not defined( $data->{'param'}{'snmp-oids-per-pdu'} ) )
145 my $oidsPerPDU = $devdetails->param('F5BigIp::snmp-oids-per-pdu');
146 if( not defined($oidsPerPDU) or $oidsPerPDU == 0 )
150 $data->{'param'}{'snmp-oids-per-pdu'} = $oidsPerPDU;
153 # this is rather basic, per-capability checking
154 # may be required in the future
156 if( $dd->checkSnmpOID('4.x_globalStatUptime') )
158 $devdetails->setCap('BigIp_4.x');
160 elsif( $dd->checkSnmpOID('3.x_uptime') )
162 # for v3.x we are not supporting detailed stats, so don't check
164 $devdetails->setCap('BigIp_3.x');
169 my $result = $dd->retrieveSnmpOIDs( '4.x_globalAttrProductCode' );
170 my $product_code = $result->{'4.x_globalAttrProductCode'};
172 $product_name = $f5_product{$product_code}->{'product'};
173 if( $f5_product{$product_code}->{'supported'} )
175 $devdetails->setCap( 'BigIp_' . $product_name );
179 if( defined($product_name) )
181 Debug
("Found an unsupported F5 product '$product_name'");
185 Debug
("Found an unknown F5 product");
190 my $poolTable = $session->get_table( -baseoid
=>
191 $dd->oiddef('4.x_poolTable') );
193 if( defined( $poolTable ) )
195 $devdetails->storeSnmpVars( $poolTable );
196 $devdetails->setCap('BigIp_4.x_PoolTable');
199 $ref->{'indices'} = [];
200 $data->{'poolTable'} = $ref;
202 for my $INDEX ( $devdetails->
203 getSnmpIndices
( $dd->oiddef('4.x_poolName') ) )
205 push( @
{$ref->{'indices'}}, $INDEX );
206 my $pool = $devdetails->snmpVar($dd->oiddef('4.x_poolName') .
214 $ref->{$INDEX}->{'param'} = $param;
215 $param->{'nick'} = $nick;
216 $param->{'pool'} = $pool;
217 $param->{'descr'} = "Stats for Pool $pool";
218 $param->{'INDEX'} = $INDEX;
223 my $poolMemberTable =
224 $session->get_table( -baseoid
=>
225 $dd->oiddef('4.x_poolMemberTable') );
227 if( defined( $poolMemberTable ) )
229 $devdetails->storeSnmpVars( $poolMemberTable );
230 $devdetails->setCap('BigIp_4.x_PoolMemberTable');
233 $data->{'poolMemberTable'} = $ref;
237 getSnmpIndices
( $dd->oiddef('4.x_poolMemberPoolName') ) )
239 push( @
{ $ref->{'indices'} }, $INDEX );
241 $devdetails->snmpVar($dd->oiddef('4.x_poolMemberPoolName') .
244 $devdetails->snmpVar($dd->oiddef('4.x_poolMemberIpAddress') .
247 $devdetails->snmpVar($dd->oiddef('4.x_poolMemberPort') .
250 my $nick = "MEMBER_${pool}_${ip}_${port}";
255 $ref->{$INDEX}->{'param'} = $param;
256 $param->{'nick'} = $nick;
257 $param->{'pool'} = $pool;
258 $param->{'descr'} = "Member of Pool $pool IP: $ip Port: $port";
259 $param->{'INDEX'} = $INDEX;
264 my $virtServerNumber = $dd->retrieveSnmpOIDs( '4.x_virtualServerNumber' );
265 if( $virtServerNumber->{'4.x_virtualServerNumber'} > 0 )
267 my $virtServer = $session->get_table( -baseoid
=>
268 $dd->oiddef('4.x_virtualServer') );
269 if( defined( $virtServer ) )
271 $devdetails->storeSnmpVars( $virtServer );
272 $devdetails->setCap('BigIp_4.x_VirtualServer');
275 $data->{'virtualServer'} = $ref;
279 getSnmpIndices
( $dd->oiddef('4.x_virtualServerIp') ) )
281 push( @
{ $ref->{'indices'} }, $INDEX);
282 my $pool = $devdetails->snmpVar(
283 $dd->oiddef('4.x_virtualServerPool') .
285 my $ip = $devdetails->snmpVar(
286 $dd->oiddef('4.x_virtualServerIp') .
288 my $port = $devdetails->snmpVar(
289 $dd->oiddef('4.x_virtualServerPort') .
293 $ref->{$INDEX}->{'param'} = $param;
295 my $descr = "Virtual Server Pool: $pool IP: $ip Port: $port";
296 my $nick = "VIP_${pool}_${ip}_${port}";
300 $param->{'INDEX'} = $INDEX;
301 $param->{'descr'} = $descr;
302 $param->{'nick'} = $nick;
303 $param->{'pool'} = $pool;
308 Debug
("Virtual Servers Defined but not able to be configured");
312 my $sslProxyTable = $session->get_table( -baseoid
=>
313 $dd->oiddef('4.x_sslProxyTable') );
315 if( defined( $sslProxyTable ) )
317 $devdetails->storeSnmpVars( $sslProxyTable );
318 $devdetails->setCap('BigIp_4.x_sslProxyTable');
321 $ref->{'indices'} = [];
322 $data->{'sslProxyTable'} = $ref;
324 for my $INDEX ( $devdetails->
325 getSnmpIndices
( $dd->oiddef('4.x_sslProxyOrigIpAddress') ) )
327 push( @
{$ref->{'indices'}}, $INDEX );
329 my $origIp = $devdetails->snmpVar(
330 $dd->oiddef('4.x_sslProxyOrigIpAddress')
333 my $origPort = $devdetails->snmpVar(
334 $dd->oiddef('4.x_sslProxyOrigPort')
337 my $destIp = $devdetails->snmpVar(
338 $dd->oiddef('4.x_sslProxyDestIpAddress')
341 my $destPort = $devdetails->snmpVar(
342 $dd->oiddef('4.x_sslProxyDestPort')
345 my $connLimit = $devdetails->snmpVar(
346 $dd->oiddef('4.x_sslProxyConnLimit')
351 my $nick = $origIp . '_' . $origPort . '_' . $destIp .
355 $ref->{$INDEX}->{'param'} = $param;
356 $param->{'nick'} = $nick;
357 $param->{'descr'} = "Stats for SSL Proxy Address: " .
358 "${origIp}:${origPort} -> ${destIp}:${destPort}";
359 $param->{'INDEX'} = $INDEX;
360 $param->{'connLimit'} = $connLimit;
373 my $devdetails = shift;
376 my $data = $devdetails->data();
379 my $bigIpName = 'BigIp_Global_Stats';
382 'precedence' => '-100',
383 'comment' => 'BigIp Global Stats',
384 'rrd-create-dstype' => 'GAUGE', };
386 if( $devdetails->hasCap('BigIp_4.x') )
388 my $bigIpStatsNode = $cb->addSubtree( $devNode, $bigIpName,
389 $bigIpParam, [ 'F5BigIp::BigIp_4.x' ]);
391 if( $devdetails->hasCap('BigIp_ssl') )
393 $cb->addTemplateApplication
394 ( $bigIpStatsNode , 'F5BigIp::BigIp_4.x_sslProxy_Global' );
397 elsif( $devdetails->hasCap('BigIp_3.x') )
399 $cb->addSubtree( $devNode, $bigIpName, $bigIpParam,
400 [ 'F5BigIp::BigIp_3.x' ]);
403 my $virtName = 'BigIp_VirtualServers';
406 'precedence' => '-200',
407 'comment' => 'Virtual Server(VIP) Stats',
412 if( $devdetails->hasCap('BigIp_4.x_VirtualServer') )
415 ( 'F5BigIp::BigIp_4.x_virtualServer-actvconn-overview' );
416 # 'F5BigIp::BigIp_4.x_virtualServer-connrate-overview');
419 $cb->addSubtree( $devNode, $virtName, $virtParam, \
@templates );
421 my $ref = $data->{'virtualServer'};
423 for my $INDEX ( @
{ $ref->{'indices'} } )
425 my $server = $ref->{$INDEX}->{'param'};
427 $server->{'precedence'} = '-100';
429 $cb->addSubtree( $virtTree, $server->{'nick'}, $server,
430 [ 'F5BigIp::BigIp_4.x_virtualServer' ] );
434 my $poolName = 'BigIp_Pools';
436 'precedence' => '-300',
437 'comment' => 'Pool Stats',
442 if( $devdetails->hasCap('BigIp_4.x_PoolTable') )
445 $cb->addSubtree( $devNode, $poolName, $poolParam,
446 ['F5BigIp::BigIp_4.x_pool-actvconn-overview']);
447 my $ref = $data->{'poolTable'};
449 for my $INDEX ( @
{ $ref->{'indices'} } )
451 my $pool = $ref->{$INDEX}->{'param'};
453 $pool->{'precedence'} = '-100';
455 $cb->addSubtree( $poolTree, $pool->{'pool'}, $pool,
456 [ 'F5BigIp::BigIp_4.x_pool' ] );
461 my $poolMemberName = 'BigIp_Pool_Members';
463 my $poolMemberParam = {
464 'precedence' => '-400',
465 'comment' => 'Pool Member Stats',
470 if( $devdetails->hasCap('BigIp_4.x_PoolMemberTable') )
473 $cb->addSubtree( $devNode, $poolMemberName, $poolMemberParam );
474 my $ref = $data->{'poolMemberTable'};
476 for my $INDEX ( @
{ $ref->{'indices'} } )
478 my $poolMemberPoolTree;
480 my $server = $ref->{$INDEX}->{'param'};
482 my $poolMemberPoolName = $server->{'pool'};
483 my $poolMemberPoolParam = {
484 'precidence' => '-100',
485 'comment' => "Members of the $server->{'pool'} Pool",
489 if( not defined( $lastPoolTree ) or
490 $poolMemberPoolName !~ /\b$lastPoolTree\b/ )
493 ( 'F5BigIp::BigIp_4.x_poolMember-actvconn-overview' );
494 $poolMemberPoolTree =
495 $cb->addSubtree( $poolMemberTree, $poolMemberPoolName,
496 $poolMemberPoolParam, \
@templates );
498 $lastPoolTree = $poolMemberPoolName;
500 $server->{'precedence'} = '-100';
502 $cb->addSubtree( $poolMemberPoolTree, $server->{'nick'},
504 [ 'F5BigIp::BigIp_4.x_poolMember' ] );
510 # BigIP SSL Product Support
511 if( $devdetails->hasCap('BigIp_4.x_sslProxyTable') )
514 my $bigIpSSLProxies = 'BigIp_SSL_Proxies';
516 my $bigIpSSLParam = {
517 'comment' => 'BigIp SSL Proxies',
518 'rrd-create-dstype' => 'COUNTER', };
520 my $sslProxyTree = $cb->addSubtree(
521 $devNode, $bigIpSSLProxies, $bigIpSSLParam,
522 [ 'F5BigIp::BigIp_4.x_sslProxy-currconn-overview' ]);
524 my $ref = $data->{'sslProxyTable'};
526 for my $INDEX ( @
{ $ref->{'indices'} } )
528 my $proxy = $ref->{$INDEX}->{'param'};
530 $cb->addSubtree( $sslProxyTree, $proxy->{'nick'}, $proxy,
531 [ 'F5BigIp::BigIp_4.x_sslProxy' ] );
545 # indent-tabs-mode: nil
546 # perl-indent-level: 4