diff options
Diffstat (limited to 'torrus/perllib/Torrus/DevDiscover/F5BigIp.pm')
| -rw-r--r-- | torrus/perllib/Torrus/DevDiscover/F5BigIp.pm | 543 |
1 files changed, 543 insertions, 0 deletions
diff --git a/torrus/perllib/Torrus/DevDiscover/F5BigIp.pm b/torrus/perllib/Torrus/DevDiscover/F5BigIp.pm new file mode 100644 index 000000000..e0d0770bb --- /dev/null +++ b/torrus/perllib/Torrus/DevDiscover/F5BigIp.pm @@ -0,0 +1,543 @@ +# Copyright (C) 2003 Shawn Ferry +# +# 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: F5BigIp.pm,v 1.1 2010-12-27 00:03:48 ivan Exp $ +# Shawn Ferry <sferry at sevenspace dot com> <lalartu at obscure dot org> + +# F5 BigIp Load Balancer + +package Torrus::DevDiscover::F5BigIp; + +use strict; +use Torrus::Log; + + +$Torrus::DevDiscover::registry{'F5BigIp'} = { + 'sequence' => 500, + 'checkdevtype' => \&checkdevtype, + 'discover' => \&discover, + 'buildConfig' => \&buildConfig + }; + +our %oiddef = + ( + # F5 + 'f5' => '1.3.6.1.4.1.3375', + + '4.x_globalStatUptime' => '1.3.6.1.4.1.3375.1.1.1.2.1.0', + '3.x_uptime' => '1.3.6.1.4.1.3375.1.1.50.0', + + '4.x_globalAttrProductCode' => '1.3.6.1.4.1.3375.1.1.1.1.5.0', + + '4.x_virtualServer' => '1.3.6.1.4.1.3375.1.1.3', + '4.x_virtualServerNumber' => '1.3.6.1.4.1.3375.1.1.3.1.0', + '4.x_virtualServerTable' => '1.3.6.1.4.1.3375.1.1.3.2', + '4.x_virtualServerIp' => '1.3.6.1.4.1.3375.1.1.3.2.1.1', + '4.x_virtualServerPort' => '1.3.6.1.4.1.3375.1.1.3.2.1.2', + '4.x_virtualServerPool' => '1.3.6.1.4.1.3375.1.1.3.2.1.30', + + '4.x_poolTable' => '1.3.6.1.4.1.3375.1.1.7.2', + '4.x_poolName' => '1.3.6.1.4.1.3375.1.1.7.2.1.1', + + '4.x_poolMemberTable' => '1.3.6.1.4.1.3375.1.1.8.2', + '4.x_poolMemberPoolName' => '1.3.6.1.4.1.3375.1.1.8.2.1.1', + '4.x_poolMemberIpAddress' => '1.3.6.1.4.1.3375.1.1.8.2.1.2', + '4.x_poolMemberPort' => '1.3.6.1.4.1.3375.1.1.8.2.1.3', + + '4.x_sslProxyTable' => '1.3.6.1.4.1.3375.1.1.9.2.1', + '4.x_sslProxyOrigIpAddress' => '1.3.6.1.4.1.3375.1.1.9.2.1.1', + '4.x_sslProxyOrigPort' => '1.3.6.1.4.1.3375.1.1.9.2.1.2', + '4.x_sslProxyDestIpAddress' => '1.3.6.1.4.1.3375.1.1.9.2.1.3', + '4.x_sslProxyDestPort' => '1.3.6.1.4.1.3375.1.1.9.2.1.4', + '4.x_sslProxyConnLimit' => '1.3.6.1.4.1.3375.1.1.9.2.1.23', + + ); + +# from https://secure.f5.com/validate/help.jsp +#HA (BIG-IP high availability software) +#3DNS (3-DNS software) +#LC (BIG-IP Link Controller software) +#LB (BIG-IP Load Balancer 520) +#FLB (BIG-IP FireGuard 520) +#CLB (BIG-IP Cache Load Balancer 520) +#SSL (BIG-IP eCommerce Load Balancer 520) +#XLB (BIG-IP user-defined special purpose product for 520 platforms) +#ISMAN (iControl Services Manager) + +our %f5_product = ( + '1' => { 'product' => 'indeterminate', 'supported' => 0, }, + '2' => { 'product' => 'ha', 'supported' => 1, }, + '3' => { 'product' => 'lb', 'supported' => 1, }, + '4' => { 'product' => 'threedns', 'supported' => 0, }, + '5' => { 'product' => 'flb', 'supported' => 0, }, + '6' => { 'product' => 'clb', 'supported' => 0, }, + '7' => { 'product' => 'xlb', 'supported' => 0, }, + '8' => { 'product' => 'ssl', 'supported' => 1, }, + '10' => { 'product' => 'test', 'supported' => 0, }, + '99' => { 'product' => 'unsupported', 'supported' => 0, }, + ); + +our %f5_sslGatewayLevel = ( + '1' => 'none', + '3' => 'tps200', + '4' => 'tps400', + '5' => 'tps600', + '6' => 'tps800', + '7' => 'tps1000', + '9' => 'tps500', + '10' => 'tps1500', + '11' => 'tps2000', + '99' => 'unsupported', + ); + + + + +sub checkdevtype +{ + my $dd = shift; + my $devdetails = shift; + my $data = $devdetails->data(); + + # You would think globalAttrProductCode would work well + # I need more examples to see if ha(2) is specific to + # BipIP HA or any ha f5 product + + if( not $dd->checkSnmpTable( 'f5' ) ) + { + return 0; + } + + return 1; +} + + +sub discover +{ + my $dd = shift; + my $devdetails = shift; + + my $session = $dd->session(); + my $data = $devdetails->data(); + + # SNMP on F5 boxes will become unresponsive over time with large + # enough oids-per-pdu values. 10 appears to work for everything however + # no exhaustive testing has been done to determine if a higer number + # could be used. + if( not defined( $data->{'param'}{'snmp-oids-per-pdu'} ) ) + { + my $oidsPerPDU = $devdetails->param('F5BigIp::snmp-oids-per-pdu'); + if( $oidsPerPDU == 0 ) + { + $oidsPerPDU = 10; + } + $data->{'param'}{'snmp-oids-per-pdu'} = $oidsPerPDU; + } + + # this is rather basic, per-capability checking + # may be required in the future + + if( $dd->checkSnmpOID('4.x_globalStatUptime') ) + { + $devdetails->setCap('BigIp_4.x'); + } + elsif( $dd->checkSnmpOID('3.x_uptime') ) + { + # for v3.x we are not supporting detailed stats, so don't check + # anything else + $devdetails->setCap('BigIp_3.x'); + return 1; + } + + my $product_name; + my $product_name; + my $result = $dd->retrieveSnmpOIDs( '4.x_globalAttrProductCode' ); + my $product_code = $result->{'4.x_globalAttrProductCode'}; + + $product_name = %f5_product->{$product_code}->{'product'}; + if( %f5_product->{$product_code}->{'supported'} ) + { + $devdetails->setCap( 'BigIp_' . $product_name ); + } + else + { + if( defined($product_name) ) + { + Debug("Found an unsupported F5 product '$product_name'"); + } + else + { + Debug("Found an unknown F5 product"); + } + return 0; + } + + my $poolTable = $session->get_table( -baseoid => + $dd->oiddef('4.x_poolTable') ); + + if( defined( $poolTable ) ) + { + $devdetails->storeSnmpVars( $poolTable ); + $devdetails->setCap('BigIp_4.x_PoolTable'); + + my $ref = {}; + $ref->{'indices'} = []; + $data->{'poolTable'} = $ref; + + foreach my $INDEX ( $devdetails-> + getSnmpIndices( $dd->oiddef('4.x_poolName') ) ) + { + push( @{$ref->{'indices'}}, $INDEX ); + my $pool = $devdetails->snmpVar($dd->oiddef('4.x_poolName') . + '.' . $INDEX ); + + my $nick = $pool; + $nick =~ s/\W/_/g; + $nick =~ s/_+/_/g; + + my $param = {}; + $ref->{$INDEX}->{'param'} = $param; + $param->{'nick'} = $nick; + $param->{'pool'} = $pool; + $param->{'descr'} = "Stats for Pool $pool"; + $param->{'INDEX'} = $INDEX; + } + + } + + my $poolMemberTable = + $session->get_table( -baseoid => + $dd->oiddef('4.x_poolMemberTable') ); + + if( defined( $poolMemberTable ) ) + { + $devdetails->storeSnmpVars( $poolMemberTable ); + $devdetails->setCap('BigIp_4.x_PoolMemberTable'); + + my $ref = {}; + $data->{'poolMemberTable'} = $ref; + + foreach my $INDEX + ( $devdetails-> + getSnmpIndices( $dd->oiddef('4.x_poolMemberPoolName') ) ) + { + push( @{ $ref->{'indices'} }, $INDEX ); + my $pool = + $devdetails->snmpVar($dd->oiddef('4.x_poolMemberPoolName') . + '.' . $INDEX ); + my $ip = + $devdetails->snmpVar($dd->oiddef('4.x_poolMemberIpAddress') . + '.' . $INDEX ); + my $port = + $devdetails->snmpVar($dd->oiddef('4.x_poolMemberPort') . + '.' . $INDEX ); + + my $nick = "MEMBER_${pool}_${ip}_${port}"; + $nick =~ s/\W/_/g; + $nick =~ s/_+/_/g; + + my $param = {}; + $ref->{$INDEX}->{'param'} = $param; + $param->{'nick'} = $nick; + $param->{'pool'} = $pool; + $param->{'descr'} = "Member of Pool $pool IP: $ip Port: $port"; + $param->{'INDEX'} = $INDEX; + } + + } + + my $virtServerNumber = $dd->retrieveSnmpOIDs( '4.x_virtualServerNumber' ); + if( $virtServerNumber->{'4.x_virtualServerNumber'} > 0 ) + { + my $virtServer = $session->get_table( -baseoid => + $dd->oiddef('4.x_virtualServer') ); + if( defined( $virtServer ) ) + { + $devdetails->storeSnmpVars( $virtServer ); + $devdetails->setCap('BigIp_4.x_VirtualServer'); + + my $ref = {}; + $data->{'virtualServer'} = $ref; + + foreach my $INDEX + ( $devdetails-> + getSnmpIndices( $dd->oiddef('4.x_virtualServerIp') ) ) + { + push( @{ $ref->{'indices'} }, $INDEX); + my $pool = $devdetails->snmpVar( + $dd->oiddef('4.x_virtualServerPool') . + '.' . $INDEX ); + my $ip = $devdetails->snmpVar( + $dd->oiddef('4.x_virtualServerIp') . + '.' . $INDEX ); + my $port = $devdetails->snmpVar( + $dd->oiddef('4.x_virtualServerPort') . + '.' . $INDEX ); + + my $param = {}; + $ref->{$INDEX}->{'param'} = $param; + + my $descr = "Virtual Server Pool: $pool IP: $ip Port: $port"; + my $nick = "VIP_${pool}_${ip}_${port}"; + $nick =~ s/\W/_/g; + $nick =~ s/_+/_/g; + + $param->{'INDEX'} = $INDEX; + $param->{'descr'} = $descr; + $param->{'nick'} = $nick; + $param->{'pool'} = $pool; + } + } + else + { + Debug("Virtual Servers Defined but not able to be configured"); + } + } + + my $sslProxyTable = $session->get_table( -baseoid => + $dd->oiddef('4.x_sslProxyTable') ); + + if( defined( $sslProxyTable ) ) + { + $devdetails->storeSnmpVars( $sslProxyTable ); + $devdetails->setCap('BigIp_4.x_sslProxyTable'); + + my $ref = {}; + $ref->{'indices'} = []; + $data->{'sslProxyTable'} = $ref; + + foreach my $INDEX ( $devdetails-> + getSnmpIndices( $dd->oiddef('4.x_sslProxyOrigIpAddress') ) ) + { + push( @{$ref->{'indices'}}, $INDEX ); + + my $origIp = $devdetails->snmpVar( + $dd->oiddef('4.x_sslProxyOrigIpAddress') + . '.' . $INDEX ); + + my $origPort = $devdetails->snmpVar( + $dd->oiddef('4.x_sslProxyOrigPort') + . '.' . $INDEX ); + + my $destIp = $devdetails->snmpVar( + $dd->oiddef('4.x_sslProxyDestIpAddress') + . '.' . $INDEX ); + + my $destPort = $devdetails->snmpVar( + $dd->oiddef('4.x_sslProxyDestPort') + . '.' . $INDEX ); + + my $connLimit = $devdetails->snmpVar( + $dd->oiddef('4.x_sslProxyConnLimit') + . '.' . $INDEX ); + + + + my $nick = $origIp . '_' . $origPort . '_' . $destIp . + '_' . $destPort; + + my $param = {}; + $ref->{$INDEX}->{'param'} = $param; + $param->{'nick'} = $nick; + $param->{'descr'} = "Stats for SSL Proxy Address: " . + "${origIp}:${origPort} -> ${destIp}:${destPort}"; + $param->{'INDEX'} = $INDEX; + $param->{'connLimit'} = $connLimit; + + } + + + } + + return 1; +} + + +sub buildConfig +{ + my $devdetails = shift; + my $cb = shift; + my $devNode = shift; + my $data = $devdetails->data(); + + + my $bigIpName = 'BigIp_Global_Stats'; + + my $bigIpParam = { + 'precedence' => '-100', + 'comment' => 'BigIp Global Stats', + 'rrd-create-dstype' => 'GAUGE', }; + + if( $devdetails->hasCap('BigIp_4.x') ) + { + my $bigIpStatsNode = $cb->addSubtree( $devNode, $bigIpName, + $bigIpParam, [ 'F5BigIp::BigIp_4.x' ]); + + if( $devdetails->hasCap('BigIp_ssl') ) + { + $cb->addTemplateApplication + ( $bigIpStatsNode , 'F5BigIp::BigIp_4.x_sslProxy_Global' ); + } + } + elsif( $devdetails->hasCap('BigIp_3.x') ) + { + $cb->addSubtree( $devNode, $bigIpName, $bigIpParam, + [ 'F5BigIp::BigIp_3.x' ]); + } + + my $virtName = 'BigIp_VirtualServers'; + + my $virtParam = { + 'precedence' => '-200', + 'comment' => 'Virtual Server(VIP) Stats', + }; + + my $virtTree; + + if( $devdetails->hasCap('BigIp_4.x_VirtualServer') ) + { + my @templates = + ( 'F5BigIp::BigIp_4.x_virtualServer-actvconn-overview' ); + # 'F5BigIp::BigIp_4.x_virtualServer-connrate-overview'); + + $virtTree = + $cb->addSubtree( $devNode, $virtName, $virtParam, \@templates ); + + my $ref = $data->{'virtualServer'}; + + foreach my $INDEX ( @{ $ref->{'indices'} } ) + { + my $server = $ref->{$INDEX}->{'param'}; + + $server->{'precedence'} = '-100'; + + $cb->addSubtree( $virtTree, $server->{'nick'}, $server, + [ 'F5BigIp::BigIp_4.x_virtualServer' ] ); + } + } + + my $poolName = 'BigIp_Pools'; + my $poolParam = { + 'precedence' => '-300', + 'comment' => 'Pool Stats', + }; + + my $poolTree; + + if( $devdetails->hasCap('BigIp_4.x_PoolTable') ) + { + $poolTree = + $cb->addSubtree( $devNode, $poolName, $poolParam, + ['F5BigIp::BigIp_4.x_pool-actvconn-overview']); + my $ref = $data->{'poolTable'}; + + foreach my $INDEX ( @{ $ref->{'indices'} } ) + { + my $pool = $ref->{$INDEX}->{'param'}; + + $pool->{'precedence'} = '-100'; + + $cb->addSubtree( $poolTree, $pool->{'pool'}, $pool, + [ 'F5BigIp::BigIp_4.x_pool' ] ); + } + + } + + my $poolMemberName = 'BigIp_Pool_Members'; + + my $poolMemberParam = { + 'precedence' => '-400', + 'comment' => 'Pool Member Stats', + }; + + my $poolMemberTree; + + if( $devdetails->hasCap('BigIp_4.x_PoolMemberTable') ) + { + $poolMemberTree = + $cb->addSubtree( $devNode, $poolMemberName, $poolMemberParam ); + my $ref = $data->{'poolMemberTable'}; + + foreach my $INDEX ( @{ $ref->{'indices'} } ) + { + my $poolMemberPoolTree; + my $lastPoolTree; + my $server = $ref->{$INDEX}->{'param'}; + + my $poolMemberPoolName = $server->{'pool'}; + my $poolMemberPoolParam = { + 'precidence' => '-100', + 'comment' => "Members of the $server->{'pool'} Pool", + }; + + + if( not defined( $lastPoolTree ) or + $poolMemberPoolName !~ /\b$lastPoolTree\b/ ) + { + my @templates = + ( 'F5BigIp::BigIp_4.x_poolMember-actvconn-overview' ); + $poolMemberPoolTree = + $cb->addSubtree( $poolMemberTree, $poolMemberPoolName, + $poolMemberPoolParam, \@templates ); + + $lastPoolTree = $poolMemberPoolName; + + $server->{'precedence'} = '-100'; + + $cb->addSubtree( $poolMemberPoolTree, $server->{'nick'}, $server, + [ 'F5BigIp::BigIp_4.x_poolMember' ] ); + } + } + } + + + # BigIP SSL Product Support + if( $devdetails->hasCap('BigIp_4.x_sslProxyTable') ) + { + + my $bigIpSSLProxies = 'BigIp_SSL_Proxies'; + + my $bigIpSSLParam = { + 'comment' => 'BigIp SSL Proxies', + 'rrd-create-dstype' => 'COUNTER', }; + + my $sslProxyTree = $cb->addSubtree( + $devNode, $bigIpSSLProxies, $bigIpSSLParam, + [ 'F5BigIp::BigIp_4.x_sslProxy-currconn-overview' ]); + + my $ref = $data->{'sslProxyTable'}; + + foreach my $INDEX ( @{ $ref->{'indices'} } ) + { + my $proxy = $ref->{$INDEX}->{'param'}; + + $cb->addSubtree( $sslProxyTree, $proxy->{'nick'}, $proxy, + [ 'F5BigIp::BigIp_4.x_sslProxy' ] ); + } + + } + +} + + +1; + + +# Local Variables: +# mode: perl +# indent-tabs-mode: nil +# perl-indent-level: 4 +# End: |
