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.
17 # $Id: F5BigIp.pm,v 1.2 2011-12-16 22:43:52 ivan Exp $
18 # Shawn Ferry <sferry at sevenspace dot com> <lalartu at obscure dot org>
20 # F5 BigIp Load Balancer
22 package Torrus::DevDiscover::F5BigIp;
28 $Torrus::DevDiscover::registry{'F5BigIp'} = {
30 'checkdevtype' => \&checkdevtype,
31 'discover' => \&discover,
32 'buildConfig' => \&buildConfig
38 'f5' => '1.3.6.1.4.1.3375',
40 '4.x_globalStatUptime' => '1.3.6.1.4.1.3375.1.1.1.2.1.0',
41 '3.x_uptime' => '1.3.6.1.4.1.3375.1.1.50.0',
43 '4.x_globalAttrProductCode' => '1.3.6.1.4.1.3375.1.1.1.1.5.0',
45 '4.x_virtualServer' => '1.3.6.1.4.1.3375.1.1.3',
46 '4.x_virtualServerNumber' => '1.3.6.1.4.1.3375.1.1.3.1.0',
47 '4.x_virtualServerTable' => '1.3.6.1.4.1.3375.1.1.3.2',
48 '4.x_virtualServerIp' => '1.3.6.1.4.1.3375.1.1.3.2.1.1',
49 '4.x_virtualServerPort' => '1.3.6.1.4.1.3375.1.1.3.2.1.2',
50 '4.x_virtualServerPool' => '1.3.6.1.4.1.3375.1.1.3.2.1.30',
52 '4.x_poolTable' => '1.3.6.1.4.1.3375.1.1.7.2',
53 '4.x_poolName' => '1.3.6.1.4.1.3375.1.1.7.2.1.1',
55 '4.x_poolMemberTable' => '1.3.6.1.4.1.3375.1.1.8.2',
56 '4.x_poolMemberPoolName' => '1.3.6.1.4.1.3375.1.1.8.2.1.1',
57 '4.x_poolMemberIpAddress' => '1.3.6.1.4.1.3375.1.1.8.2.1.2',
58 '4.x_poolMemberPort' => '1.3.6.1.4.1.3375.1.1.8.2.1.3',
60 '4.x_sslProxyTable' => '1.3.6.1.4.1.3375.1.1.9.2.1',
61 '4.x_sslProxyOrigIpAddress' => '1.3.6.1.4.1.3375.1.1.9.2.1.1',
62 '4.x_sslProxyOrigPort' => '1.3.6.1.4.1.3375.1.1.9.2.1.2',
63 '4.x_sslProxyDestIpAddress' => '1.3.6.1.4.1.3375.1.1.9.2.1.3',
64 '4.x_sslProxyDestPort' => '1.3.6.1.4.1.3375.1.1.9.2.1.4',
65 '4.x_sslProxyConnLimit' => '1.3.6.1.4.1.3375.1.1.9.2.1.23',
69 # from https://secure.f5.com/validate/help.jsp
70 #HA (BIG-IP high availability software)
71 #3DNS (3-DNS software)
72 #LC (BIG-IP Link Controller software)
73 #LB (BIG-IP Load Balancer 520)
74 #FLB (BIG-IP FireGuard 520)
75 #CLB (BIG-IP Cache Load Balancer 520)
76 #SSL (BIG-IP eCommerce Load Balancer 520)
77 #XLB (BIG-IP user-defined special purpose product for 520 platforms)
78 #ISMAN (iControl Services Manager)
81 '1' => { 'product' => 'indeterminate', 'supported' => 0, },
82 '2' => { 'product' => 'ha', 'supported' => 1, },
83 '3' => { 'product' => 'lb', 'supported' => 1, },
84 '4' => { 'product' => 'threedns', 'supported' => 0, },
85 '5' => { 'product' => 'flb', 'supported' => 0, },
86 '6' => { 'product' => 'clb', 'supported' => 0, },
87 '7' => { 'product' => 'xlb', 'supported' => 0, },
88 '8' => { 'product' => 'ssl', 'supported' => 1, },
89 '10' => { 'product' => 'test', 'supported' => 0, },
90 '99' => { 'product' => 'unsupported', 'supported' => 0, },
93 our %f5_sslGatewayLevel = (
103 '99' => 'unsupported',
112 my $devdetails = shift;
113 my $data = $devdetails->data();
115 # You would think globalAttrProductCode would work well
116 # I need more examples to see if ha(2) is specific to
117 # BipIP HA or any ha f5 product
119 if( not $dd->checkSnmpTable( 'f5' ) )
131 my $devdetails = shift;
133 my $session = $dd->session();
134 my $data = $devdetails->data();
136 # SNMP on F5 boxes will become unresponsive over time with large
137 # enough oids-per-pdu values. 10 appears to work for everything however
138 # no exhaustive testing has been done to determine if a higer number
140 if( not defined( $data->{'param'}{'snmp-oids-per-pdu'} ) )
142 my $oidsPerPDU = $devdetails->param('F5BigIp::snmp-oids-per-pdu');
143 if( $oidsPerPDU == 0 )
147 $data->{'param'}{'snmp-oids-per-pdu'} = $oidsPerPDU;
150 # this is rather basic, per-capability checking
151 # may be required in the future
153 if( $dd->checkSnmpOID('4.x_globalStatUptime') )
155 $devdetails->setCap('BigIp_4.x');
157 elsif( $dd->checkSnmpOID('3.x_uptime') )
159 # for v3.x we are not supporting detailed stats, so don't check
161 $devdetails->setCap('BigIp_3.x');
167 my $result = $dd->retrieveSnmpOIDs( '4.x_globalAttrProductCode' );
168 my $product_code = $result->{'4.x_globalAttrProductCode'};
170 $product_name = $f5_product{$product_code}->{'product'};
171 if( $f5_product{$product_code}->{'supported'} )
173 $devdetails->setCap( 'BigIp_' . $product_name );
177 if( defined($product_name) )
179 Debug("Found an unsupported F5 product '$product_name'");
183 Debug("Found an unknown F5 product");
188 my $poolTable = $session->get_table( -baseoid =>
189 $dd->oiddef('4.x_poolTable') );
191 if( defined( $poolTable ) )
193 $devdetails->storeSnmpVars( $poolTable );
194 $devdetails->setCap('BigIp_4.x_PoolTable');
197 $ref->{'indices'} = [];
198 $data->{'poolTable'} = $ref;
200 foreach my $INDEX ( $devdetails->
201 getSnmpIndices( $dd->oiddef('4.x_poolName') ) )
203 push( @{$ref->{'indices'}}, $INDEX );
204 my $pool = $devdetails->snmpVar($dd->oiddef('4.x_poolName') .
212 $ref->{$INDEX}->{'param'} = $param;
213 $param->{'nick'} = $nick;
214 $param->{'pool'} = $pool;
215 $param->{'descr'} = "Stats for Pool $pool";
216 $param->{'INDEX'} = $INDEX;
221 my $poolMemberTable =
222 $session->get_table( -baseoid =>
223 $dd->oiddef('4.x_poolMemberTable') );
225 if( defined( $poolMemberTable ) )
227 $devdetails->storeSnmpVars( $poolMemberTable );
228 $devdetails->setCap('BigIp_4.x_PoolMemberTable');
231 $data->{'poolMemberTable'} = $ref;
235 getSnmpIndices( $dd->oiddef('4.x_poolMemberPoolName') ) )
237 push( @{ $ref->{'indices'} }, $INDEX );
239 $devdetails->snmpVar($dd->oiddef('4.x_poolMemberPoolName') .
242 $devdetails->snmpVar($dd->oiddef('4.x_poolMemberIpAddress') .
245 $devdetails->snmpVar($dd->oiddef('4.x_poolMemberPort') .
248 my $nick = "MEMBER_${pool}_${ip}_${port}";
253 $ref->{$INDEX}->{'param'} = $param;
254 $param->{'nick'} = $nick;
255 $param->{'pool'} = $pool;
256 $param->{'descr'} = "Member of Pool $pool IP: $ip Port: $port";
257 $param->{'INDEX'} = $INDEX;
262 my $virtServerNumber = $dd->retrieveSnmpOIDs( '4.x_virtualServerNumber' );
263 if( $virtServerNumber->{'4.x_virtualServerNumber'} > 0 )
265 my $virtServer = $session->get_table( -baseoid =>
266 $dd->oiddef('4.x_virtualServer') );
267 if( defined( $virtServer ) )
269 $devdetails->storeSnmpVars( $virtServer );
270 $devdetails->setCap('BigIp_4.x_VirtualServer');
273 $data->{'virtualServer'} = $ref;
277 getSnmpIndices( $dd->oiddef('4.x_virtualServerIp') ) )
279 push( @{ $ref->{'indices'} }, $INDEX);
280 my $pool = $devdetails->snmpVar(
281 $dd->oiddef('4.x_virtualServerPool') .
283 my $ip = $devdetails->snmpVar(
284 $dd->oiddef('4.x_virtualServerIp') .
286 my $port = $devdetails->snmpVar(
287 $dd->oiddef('4.x_virtualServerPort') .
291 $ref->{$INDEX}->{'param'} = $param;
293 my $descr = "Virtual Server Pool: $pool IP: $ip Port: $port";
294 my $nick = "VIP_${pool}_${ip}_${port}";
298 $param->{'INDEX'} = $INDEX;
299 $param->{'descr'} = $descr;
300 $param->{'nick'} = $nick;
301 $param->{'pool'} = $pool;
306 Debug("Virtual Servers Defined but not able to be configured");
310 my $sslProxyTable = $session->get_table( -baseoid =>
311 $dd->oiddef('4.x_sslProxyTable') );
313 if( defined( $sslProxyTable ) )
315 $devdetails->storeSnmpVars( $sslProxyTable );
316 $devdetails->setCap('BigIp_4.x_sslProxyTable');
319 $ref->{'indices'} = [];
320 $data->{'sslProxyTable'} = $ref;
322 foreach my $INDEX ( $devdetails->
323 getSnmpIndices( $dd->oiddef('4.x_sslProxyOrigIpAddress') ) )
325 push( @{$ref->{'indices'}}, $INDEX );
327 my $origIp = $devdetails->snmpVar(
328 $dd->oiddef('4.x_sslProxyOrigIpAddress')
331 my $origPort = $devdetails->snmpVar(
332 $dd->oiddef('4.x_sslProxyOrigPort')
335 my $destIp = $devdetails->snmpVar(
336 $dd->oiddef('4.x_sslProxyDestIpAddress')
339 my $destPort = $devdetails->snmpVar(
340 $dd->oiddef('4.x_sslProxyDestPort')
343 my $connLimit = $devdetails->snmpVar(
344 $dd->oiddef('4.x_sslProxyConnLimit')
349 my $nick = $origIp . '_' . $origPort . '_' . $destIp .
353 $ref->{$INDEX}->{'param'} = $param;
354 $param->{'nick'} = $nick;
355 $param->{'descr'} = "Stats for SSL Proxy Address: " .
356 "${origIp}:${origPort} -> ${destIp}:${destPort}";
357 $param->{'INDEX'} = $INDEX;
358 $param->{'connLimit'} = $connLimit;
371 my $devdetails = shift;
374 my $data = $devdetails->data();
377 my $bigIpName = 'BigIp_Global_Stats';
380 'precedence' => '-100',
381 'comment' => 'BigIp Global Stats',
382 'rrd-create-dstype' => 'GAUGE', };
384 if( $devdetails->hasCap('BigIp_4.x') )
386 my $bigIpStatsNode = $cb->addSubtree( $devNode, $bigIpName,
387 $bigIpParam, [ 'F5BigIp::BigIp_4.x' ]);
389 if( $devdetails->hasCap('BigIp_ssl') )
391 $cb->addTemplateApplication
392 ( $bigIpStatsNode , 'F5BigIp::BigIp_4.x_sslProxy_Global' );
395 elsif( $devdetails->hasCap('BigIp_3.x') )
397 $cb->addSubtree( $devNode, $bigIpName, $bigIpParam,
398 [ 'F5BigIp::BigIp_3.x' ]);
401 my $virtName = 'BigIp_VirtualServers';
404 'precedence' => '-200',
405 'comment' => 'Virtual Server(VIP) Stats',
410 if( $devdetails->hasCap('BigIp_4.x_VirtualServer') )
413 ( 'F5BigIp::BigIp_4.x_virtualServer-actvconn-overview' );
414 # 'F5BigIp::BigIp_4.x_virtualServer-connrate-overview');
417 $cb->addSubtree( $devNode, $virtName, $virtParam, \@templates );
419 my $ref = $data->{'virtualServer'};
421 foreach my $INDEX ( @{ $ref->{'indices'} } )
423 my $server = $ref->{$INDEX}->{'param'};
425 $server->{'precedence'} = '-100';
427 $cb->addSubtree( $virtTree, $server->{'nick'}, $server,
428 [ 'F5BigIp::BigIp_4.x_virtualServer' ] );
432 my $poolName = 'BigIp_Pools';
434 'precedence' => '-300',
435 'comment' => 'Pool Stats',
440 if( $devdetails->hasCap('BigIp_4.x_PoolTable') )
443 $cb->addSubtree( $devNode, $poolName, $poolParam,
444 ['F5BigIp::BigIp_4.x_pool-actvconn-overview']);
445 my $ref = $data->{'poolTable'};
447 foreach my $INDEX ( @{ $ref->{'indices'} } )
449 my $pool = $ref->{$INDEX}->{'param'};
451 $pool->{'precedence'} = '-100';
453 $cb->addSubtree( $poolTree, $pool->{'pool'}, $pool,
454 [ 'F5BigIp::BigIp_4.x_pool' ] );
459 my $poolMemberName = 'BigIp_Pool_Members';
461 my $poolMemberParam = {
462 'precedence' => '-400',
463 'comment' => 'Pool Member Stats',
468 if( $devdetails->hasCap('BigIp_4.x_PoolMemberTable') )
471 $cb->addSubtree( $devNode, $poolMemberName, $poolMemberParam );
472 my $ref = $data->{'poolMemberTable'};
474 foreach my $INDEX ( @{ $ref->{'indices'} } )
476 my $poolMemberPoolTree;
478 my $server = $ref->{$INDEX}->{'param'};
480 my $poolMemberPoolName = $server->{'pool'};
481 my $poolMemberPoolParam = {
482 'precidence' => '-100',
483 'comment' => "Members of the $server->{'pool'} Pool",
487 if( not defined( $lastPoolTree ) or
488 $poolMemberPoolName !~ /\b$lastPoolTree\b/ )
491 ( 'F5BigIp::BigIp_4.x_poolMember-actvconn-overview' );
492 $poolMemberPoolTree =
493 $cb->addSubtree( $poolMemberTree, $poolMemberPoolName,
494 $poolMemberPoolParam, \@templates );
496 $lastPoolTree = $poolMemberPoolName;
498 $server->{'precedence'} = '-100';
500 $cb->addSubtree( $poolMemberPoolTree, $server->{'nick'}, $server,
501 [ 'F5BigIp::BigIp_4.x_poolMember' ] );
507 # BigIP SSL Product Support
508 if( $devdetails->hasCap('BigIp_4.x_sslProxyTable') )
511 my $bigIpSSLProxies = 'BigIp_SSL_Proxies';
513 my $bigIpSSLParam = {
514 'comment' => 'BigIp SSL Proxies',
515 'rrd-create-dstype' => 'COUNTER', };
517 my $sslProxyTree = $cb->addSubtree(
518 $devNode, $bigIpSSLProxies, $bigIpSSLParam,
519 [ 'F5BigIp::BigIp_4.x_sslProxy-currconn-overview' ]);
521 my $ref = $data->{'sslProxyTable'};
523 foreach my $INDEX ( @{ $ref->{'indices'} } )
525 my $proxy = $ref->{$INDEX}->{'param'};
527 $cb->addSubtree( $sslProxyTree, $proxy->{'nick'}, $proxy,
528 [ 'F5BigIp::BigIp_4.x_sslProxy' ] );
541 # indent-tabs-mode: nil
542 # perl-indent-level: 4