Forum Discussion

Gordon_Johnston's avatar
Gordon_Johnston
Icon for Nimbostratus rankNimbostratus
Jun 29, 2005

Monitor instance status checking

Hi All,

 

 

Delurking here with a query I hope someone can assist with.

 

 

I'm writing a script to be used by our 24/7 team to give them a full overview of a BigIP from a single screen. One of the requirements is that the current monitor statuses for each pool member can be viewed. I.e. to show red/green for each monitor associated with an individual pool member.

 

 

I'm scratching my head on how to do this with iControl.

 

 

LocalLB.PoolMember.get_monitor_association returns the monitors by name that are assocated with a particular member. However this only returns the name of the monitor and nothing else to identify which instance of the monitor it is.

 

 

LocalLB.PoolMember.get_monitor_status returns the status of the member as an aggregation of all the associated monitors but not the individual monitors.

 

 

LocalLB.Pool.get_monitor_instance returns the full list of monitor instances, including the ip/port definition for each, however it does not return the nodes that these are assoicated with and it doesn't not appear to guarentee to return the results in the same order as LocalLB.PoolMember.get_monitor_association

 

 

I'm struggling as to how to link this data together. I could make queries to LocalLB.Monitor.get_instance_state but not until I know which instances belong to which pool member.

 

 

Any help appreciated.
  • what you want is the LocalLB::Pool::get_monitor_instance(). Per the documentation:

     

     

    LocalLB::Pool::get_monitor_instance()

     

    Gets the monitor instance information for the specified pools, i.e. the monitor instance information for the pool members of the specified pools.

     

     

    So, for a specified pool, it will return the instance information associated with all pool members. The ip/port definitions returned are those of the pool members.

     

     

    The only downside is that this method doesn't group the monitor instances for each member, but returns a list of how they are defined internally. This can be resolved in the application with a custom sort of the returned values.

     

     

    Here is a bit of sample code in perl that should get you going.

     

     

    !/usr/bin/perl 
     ---------------------------------------------------------------------------- 
      The contents of this file are subject to the "END USER LICENSE AGREEMENT 
      FOR F5 Software Development Kit for iControl"; you may not use this file 
      except in compliance with the License. The License is included in the 
      iControl Software Development Kit. 
      
      Software distributed under the License is distributed on an "AS IS" 
      basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See 
      the License for the specific language governing rights and limitations 
      under the License. 
      
      The Original Code is iControl Code and related documentation 
      distributed by F5. 
      
      The Initial Developer of the Original Code is F5 Networks, 
      Inc. Seattle, WA, USA. Portions created by F5 are Copyright (C) 1996-2005 
      F5 Networks, Inc. All Rights Reserved.  iControl (TM) is a registered 
      trademark of F5 Networks, Inc. 
      
      Alternatively, the contents of this file may be used under the terms 
      of the GNU General Public License (the "GPL"), in which case the 
      provisions of GPL are applicable instead of those above.  If you wish 
      to allow use of your version of this file only under the terms of the 
      GPL and not to allow others to use your version of this file under the 
      License, indicate your decision by deleting the provisions above and 
      replace them with the notice and other provisions required by the GPL. 
      If you do not delete the provisions above, a recipient may use your 
      version of this file under either the License or the GPL. 
     ---------------------------------------------------------------------------- 
      
     use SOAP::Lite + trace => qw(method debug); 
     use SOAP::Lite; 
     use MIME::Base64; 
      
     BEGIN {push (@INC, "..");} 
     use iControlTypeCast; 
      
     ---------------------------------------------------------------------------- 
      Validate Arguments 
     ---------------------------------------------------------------------------- 
     my $sHost = $ARGV[0]; 
     my $sPort = $ARGV[1]; 
     my $sUID = $ARGV[2]; 
     my $sPWD = $ARGV[3]; 
     my $sPool = $ARGV[4]; 
     my $sProtocol = "https"; 
      
     if ( ("80" eq $sPort) or ("8080" eq $sPort) ) 
     { 
         $sProtocol = "http"; 
     } 
      
     if ( ($sHost eq "") or ($sPort eq "") or ($sUID eq "") or ($sPWD eq "") ) 
     { 
         die ("Usage: LocalLBPoolMember.pl host port uid pwd [pool_name]\n"); 
     } 
      
     ---------------------------------------------------------------------------- 
      Transport Information 
     ---------------------------------------------------------------------------- 
     sub SOAP::Transport::HTTP::Client::get_basic_credentials 
     { 
         return "$sUID" => "$sPWD"; 
     } 
      
     $Pool = SOAP::Lite 
         -> uri('urn:iControl:LocalLB/Pool') 
         -> proxy("$sProtocol://$sHost:$sPort/iControl/iControlPortal.cgi"); 
     $Pool->transport->http_request->header 
     ( 
         'Authorization' =>  
             'Basic ' . MIME::Base64::encode("$sUID:$sPWD", '') 
     ); 
      
     if ( $sPool eq "" ) 
     { 
         &getAllPoolMemberMonitorInfo(); 
     } 
     else 
     { 
         &getPoolMemberMonitorInfo($sPool); 
     } 
      
     ---------------------------------------------------------------------------- 
      checkResponse 
     ---------------------------------------------------------------------------- 
     sub checkResponse() 
     { 
         my ($soapResponse) = (@_); 
         if ( $soapResponse->fault ) 
         { 
             print $soapResponse->faultcode, " ", $soapResponse->faultstring, "\n"; 
             exit(); 
         } 
     } 
      
     ---------------------------------------------------------------------------- 
      getAllPoolMemberMonitorInfo 
     ---------------------------------------------------------------------------- 
     sub getAllPoolMemberMonitorInfo() 
     { 
         $soapResponse = $Pool->get_list(); 
         &checkResponse($soapResponse); 
         my @pool_list = @{$soapResponse->result}; 
      
         &getPoolMemberMonitorInfo(@pool_list); 
     } 
      
     ---------------------------------------------------------------------------- 
      getAddress() 
     ---------------------------------------------------------------------------- 
     sub getAddress() 
     { 
         ($MonitorInstance) = (@_); 
         $instance = $MonitorInstance->{"instance"}; 
         $template_name = $instance->{"template_name"}; 
         $instance_definition = $instance->{"instance_definition"}; 
         $ipport = $instance_definition->{"ipport"}; 
         $address = $ipport->{"address"}; 
         $port = $ipport->{"port"}; 
      
         return "$address:$port"; 
     } 
      
     ---------------------------------------------------------------------------- 
      sort_by_member 
     ---------------------------------------------------------------------------- 
     sub sort_by_member { 
         return &getAddress($a) cmp &getAddress($b); 
     } 
      
      
     ---------------------------------------------------------------------------- 
      getPoolMemberMonitorInfo 
     ---------------------------------------------------------------------------- 
     sub getPoolMemberMonitorInfo() 
     { 
         my @pool_list = @_; 
      
         my $last_member = ""; 
      
          Get Member List 
         $soapResponse = $Pool->get_monitor_instance 
         ( 
             SOAP::Data->name(pool_names => [@pool_list]) 
         ); 
         &checkResponse($soapResponse); 
         my @MonitorInstanceStateAofA = @{$soapResponse->result}; 
         for $i (0 .. $MonitorInstanceStateAofA) 
         { 
             print "Pool $pool_list[$i] {\n"; 
             $MonitorInstanceStateList = $MonitorInstanceStateAofA[$i]; 
      
             foreach $MonitorInstance 
             ( 
                 sort sort_by_member @{$MonitorInstanceStateList} 
             ) 
             { 
                 $instance = $MonitorInstance->{"instance"}; 
                 $template_name = $instance->{"template_name"}; 
                 $instance_definition = $instance->{"instance_definition"}; 
                 $address_type = $instance_definition->{"address_type"}; 
                 $ipport = $instance_definition->{"ipport"}; 
                 $address = $ipport->{"address"}; 
                 $port = $ipport->{"port"}; 
                 $instance_state = $MonitorInstance->{"instance_state"}; 
                 $enabled_state = $MonitorInstance->{"enabled_state"}; 
      
                 $current_member = "$address:$port"; 
                 if ( $current_member ne $last_member )  
                 { 
                      New member so print header 
                     $last_member = $current_member; 
                     print "  Member   : $current_member\n"; 
                 } 
                  
                 print "    Template : $template_name\n"; 
                 print "               Address Type  : $address_type\n"; 
                 print "               Instance State: $instance_state\n"; 
                 print "               Enabled State :"; 
                 if ( 0 == $enabled_state ) 
                 { 
                     print "Disabled"; 
                 } 
                 else  
                 { 
                     print "Enabled"; 
                 } 
                 print "\n"; 
             } 
             print "}\n"; 
         } 
     }

     

     

    Here's some sample output:

     

    >LocalLBPoolMember.pl bigip_address 443 username password test_pool

     

    Pool test_pool {

     

    Member : 10.10.10.123:0

     

    Template : gateway_icmp

     

    Address Type : ATYPE_EXPLICIT_ADDRESS_EXPLICIT_PORT

     

    Instance State: INSTANCE_STATE_UP

     

    Enabled State :Enabled

     

    Member : 10.10.10.123:80

     

    Template : http

     

    Address Type : ATYPE_EXPLICIT_ADDRESS_EXPLICIT_PORT

     

    Instance State: INSTANCE_STATE_DOWN

     

    Enabled State :Enabled

     

    Template : tcp

     

    Address Type : ATYPE_EXPLICIT_ADDRESS_EXPLICIT_PORT

     

    Instance State: INSTANCE_STATE_UP

     

    Enabled State :Enabled

     

    Member : 10.10.10.124:0

     

    Template : gateway_icmp

     

    Address Type : ATYPE_EXPLICIT_ADDRESS_EXPLICIT_PORT

     

    Instance State: INSTANCE_STATE_UP

     

    Enabled State :Enabled

     

    }

     

     

    -Joe
  • On second thoughts unfortunatly that still doesn't get what I need.

    Here's an example output for a test pool:

     
     Pool gj_pool { 
       Member   : 192.168.123.123:1234 
         Template : http 
                    Address Type  : ATYPE_EXPLICIT_ADDRESS_EXPLICIT_PORT 
                    Instance State: INSTANCE_STATE_DOWN 
                    Enabled State :Enabled 
       Member   : 192.168.222.222:80 
         Template : gj_specific_port_specific_addr 
                    Address Type  : ATYPE_EXPLICIT_ADDRESS_EXPLICIT_PORT 
                    Instance State: INSTANCE_STATE_DOWN 
                    Enabled State :Enabled 
         Template : gj_specific_port_specific_addr 
                    Address Type  : ATYPE_EXPLICIT_ADDRESS_EXPLICIT_PORT 
                    Instance State: INSTANCE_STATE_DOWN 
                    Enabled State :Enabled 
         Template : gj_specific_port_specific_addr 
                    Address Type  : ATYPE_EXPLICIT_ADDRESS_EXPLICIT_PORT 
                    Instance State: INSTANCE_STATE_DOWN 
                    Enabled State :Enabled 
       Member   : 192.168.230.133:80 
         Template : http 
                    Address Type  : ATYPE_EXPLICIT_ADDRESS_EXPLICIT_PORT 
                    Instance State: INSTANCE_STATE_UP 
                    Enabled State :Enabled 
       Member   : 192.168.230.161:80 
         Template : http 
                    Address Type  : ATYPE_EXPLICIT_ADDRESS_EXPLICIT_PORT 
                    Instance State: INSTANCE_STATE_UP 
                    Enabled State :Enabled 
     } 
     

    There are 3 nodes in this pool, namely 192.168.230.133:80, 192.168.230.161:80, and 192.168.123.123:1234. The pool has the 'http' and 'gj_specific_port_specific_addr' monitors associated with it.

    The 'gj_specific_port_specific_addr' as its name implies has a specified destination and port for the monitor and this is not one of the monitored nodes.

    I need the output to be like this:

     
     Pool gj_pool { 
       Member   : 192.168.123.123:1234 
         Template : http 
                    Address Type  : ATYPE_EXPLICIT_ADDRESS_EXPLICIT_PORT 
                    Instance State: INSTANCE_STATE_DOWN 
                    Enabled State :Enabled 
         Template : gj_specific_port_specific_addr 
                    Address Type  : ATYPE_EXPLICIT_ADDRESS_EXPLICIT_PORT 
                    Instance State: INSTANCE_STATE_DOWN 
                    Enabled State :Enabled 
       Member   : 192.168.230.133:80 
         Template : http 
                    Address Type  : ATYPE_EXPLICIT_ADDRESS_EXPLICIT_PORT 
                    Instance State: INSTANCE_STATE_UP 
                    Enabled State :Enabled 
         Template : gj_specific_port_specific_addr 
                    Address Type  : ATYPE_EXPLICIT_ADDRESS_EXPLICIT_PORT 
                    Instance State: INSTANCE_STATE_DOWN 
                    Enabled State :Enabled 
       Member   : 192.168.230.161:80 
         Template : http 
                    Address Type  : ATYPE_EXPLICIT_ADDRESS_EXPLICIT_PORT 
                    Instance State: INSTANCE_STATE_UP 
                    Enabled State :Enabled 
         Template : gj_specific_port_specific_addr 
                    Address Type  : ATYPE_EXPLICIT_ADDRESS_EXPLICIT_PORT 
                    Instance State: INSTANCE_STATE_DOWN 
                    Enabled State :Enabled 
     } 
     

    Thus mirroring the output you get when you click a pool member in the 'members' tab in the 'pools' section in the web interface.

    Is the output from LocalLB::Pool::get_monitor_instance() sorted in the same order as LocalLB::Pool::get_member()? I think when I tested it it isn't guarenteed to match but I could be going wrong.

  • Thanks for your time Joe, it does appear that PoolMember::get_monitor_instance() is what's needed. I'll keep an eye out for it in a future release.

     

     

    I'm wondering if it's possible to derive the information given that the same set of monitors apply to each node. Monitors that have a specified port / address can perhaps be tallied up against the memebers of the pool. I'll have a go soon and see if I can get anything together.
  • The same monitors may well apply to each of the nodes, but there is a separate instance of each one running for each node. So, you could look at all instances of that specific monitor, but there is no way to be sure that all 3 of them are in the same state that the GUI or CLI will represent. Give it a shot though and let us know what you find out.

     

     

    -Joe
  • Raising the dead here, but just wondering if "LocalLB::PoolMember::get_monitor_instance()" made it into 9.2?

     

     

    Also is an updated SDK available for 9.2?

     

     

    Cheers
  • Loc_Pham_101863's avatar
    Loc_Pham_101863
    Historic F5 Account
    Yes, LocalLB.PoolMember.get_monitor_instance method has been added to 9.2.0.

     

    Since we haven't formally released a 9.2 iControl SDK, please use the following for reference:

     

     

    MemberMonitorInstanceState[][] get_monitor_instance(

     

    in String[] pool_names

     

    );

     

     

    where MemberMonitorInstanceState is defined as:

     

     

    struct MemberMonitorInstanceState

     

    {

     

    IPPortDefinition member;

     

    MonitorInstanceState[] monitor_instances;

     

    };

     

     

    Hope that helps.

     

    Loc
  • Yes, LocalLB::PoolMember::get_monitor_instance() was added in 9.2. Here are the specs for it (and are also defined in the WSDL included in the BIG-IP v9.2 release).

    
    struct IPPortDefinition {
       string address;
       long port;
    };
    enum AddressType {
       ATYPE_UNSET = 0,
       ATYPE_STAR_ADDRESS_STAR_PORT = 1,
       ATYPE_STAR_ADDRESS_EXPLICIT_PORT = 2,
       ATYPE_EXPLICIT_ADDRESS_EXPLICIT_PORT = 3,
       ATYPE_STAR_ADDRESS = 4,
       ATYPE_EXPLICIT_ADDRESS = 5
    };
    struct MonitorIPPort {
       AddressType ip_address;
       IPPortDefinition ipport;
    };
    struct MonitorInstance {
       String instance_name;
       MonitorIPPort instance_definition;
    };
    enum MonitorInstanceStateType {
       INSTANCE_STATE_UNCHECKED = 0,
       INSTANCE_STATE_CHECKING = 1,
       INSTANCE_STATE_UP = 2,
       INSTANCE_STATE_DOWN = 3,
       INSTANCE_STATE_FORCED_DOWN = 4,
       INSTANCE_STATE_DISABLED = 5
    };
    struct MonitorInstanceState {
       MonitorInstance instance;
       MonitorInstanceStateType instance_state;
       boolean enabled_state;
    };
    struct MemberMonitorInstanceState {
       IPPortDefinition member;
       MonitorInstanceState[] monitor_instances
    };
    MemberMonitorInstanceState[][] 
    LocalLB::PoolMemberget_monitor_instance(
        in String[] pool_names
    );

    Whewww...

    As for the SDK, we originally planned to release the next one with the release of our GTM features (aka 3-DNS) but that was taking out of 9.2 and pushed to the next release.

    Typically it is our policy to re-release the SDK when we add significant new features. We figure that in point releases all the new methods are defined in the WSDL included with the products. You can use your dev tools to import these WSDLs (all the documentation that is in the SDK is also included in the WSDL source files).

    If you are in need of an updated SDK for v9.2, then let me know and I'll see what I can do to get one rolled up.

    -Joe