iControl & PHP

 By Lori MacVittie, Technical Marketing Manager

What you’ll need:

1.     The PEAR::SOAP package 0.10.1

2.     The iControl SDK

3.     A six-pack of Mountain Dew

The Mountain Dew is optional, though highly recommended.

Install PEAR::SOAP

If the required PEAR packages aren’t already up to date, get them updated and upgraded.

At a minimum you’ll need the following packages:

1.     SOAP 0.10.1

2.     Net_URL

3.     HTTP_Request

4.     Net_Socket

Also note that the SOAP package is still beta, so you’ll have to force the installation:         pear –f install SOAP.

iControl Preparation

You’ll want to download iControl if you haven’t already, and then place the wsdl files (in the /iControl/sdk/wsdl/ directory) in an accessible location on a web server. If you know ahead of time which WSDL documents you’ll need, only copy those.

You’ll also have to modify each of the WSDL documents you’ll be using with the appropriate endpoint address. Now, if you’re tricky, you’ll put the WSDL files on a server behind your BIG-IP and then either create or have someone create an iRule that automatically updates the endpoint address for you. J But if that’s not feasible just find the endpoint address and update it appropriately.

<soap:address 
location="https://my_server/iControl/iControlPortal.cgi"/>


The PHP Code

The PHP code required to setup and invoke an iControl operation is pretty straight-forward. We’re going to actually make several calls, first to retrieve the list of pools configured on the BIG-IP, then two additional calls that retrieve the status of each pool and its associated members.

 <?require_once 'SOAP/Client.php';
 $soapoptions = array('namespace' => 'urn:iControl'); 
 $wsdl_url = 'http://myserver/bigip/iControl/sdk/wsdl/LocalLB.Pool.wsdl'; 
 $proxy_parms = array( 'user' => $username, 'pass' => $password);
 $params = array(); 
 $client = new SOAP_Client($wsdl_url, true, '', $proxy_parms );  

The code in yellow highlights specific variables that need to be supplied you. The code here loads the WSDL containing the get_list operation that will return a list of all pools defined on the BIG-IP, and sets our HTTP Basic-AUTH credentials to be passed to BIG-IP.

The biggest problem you’ll run into is due to the need to transport SOAP over HTTPS, as in some cases the BIG-IP uses a self-signed certificate. That makes PEAR unhappy, but we can get around that by setting a couple of cUrl options:

     $client->setOpt('curl', CURLOPT_SSL_VERIFYPEER, 0); 
     $client->setOpt('curl', CURLOPT_SSL_VERIFYHOST, 0); 


That’s it! Now we can make a call to the get_list operation. It requires no parameters, hence the empty array assigned to the $params variable.

     $response    = $client->call('get_list', $params, $soapoptions);

Now you’re ready to parse out the response. First, don’t forget to check if there was an error.

     if (PEAR::isError($response)) {        
          print "an error occurred in the call " . $response;
     }

As we iterate through the pool list, we want to make additional calls to get information about each one. But because the definition of a pool is in a different namespace, we’ll set up a second client before we start looping through the pools. There are quite a number of other calls you can make to retrieve information about a pool, we’ve chosen the status and list of members to keep things simple. Almost all the iControl operations take as input an array of something, usually a string, and conversely they return a lot of arrays so if you haven’t used the array manipulation functions in PHP in a while you’ll want to brush up on your PHP array iteration techniques.

     else {
          $soapoptions = array('namespace' => 'urn:iControl:LocalLB/Pool');
          $wsdl_url = 'http://myserver/bigip/iControl/sdk/wsdl/LocalLB.Pool.wsdl';
          $client2 = new SOAP_Client($wsdl_url, true, '', $proxy_parms );
          $client2->setOpt('curl', CURLOPT_SSL_VERIFYPEER, 0); 
          $client2->setOpt('curl', CURLOPT_SSL_VERIFYHOST, 0); 
          foreach ($response as $pool) {   
               $poolname = array($pool);        
               $params = array( 'pool_names' => $poolname );        
               $memberlist=$client2->call('get_member',$params,$soapoptions);
               $poolstatus=$client2->call('get_object_status',
                                       $params,$soapoptions);        
               if ($poolstatus[0]->availability_status == 
                                     'AVAILABILITY_STATUS_GREEN') {               
                       $color = "green";
                       $text = "white";        
               }        else {               
                       $color = "gray";               
                       $text = "black";        
               }               
               echo "<div style=\"clear:left; width: 300px; padding:5px;
 margin:5px; background:$color; color: $text;\">";         
               echo "<b>$pool</b><br/>";        
               foreach ($memberlist as $member) {               
                    foreach ($member as $item) {
                    echo "<div style=\"clear:left; width: 300px;                                
                                left: 50px; padding:5px; margin: 5px;
                                color: black; background: yellow;\">";
                    echo "<b>$item->address:$item->port</b><br/>”;
                    echo “ </div> ";
               }
               echo "</div>";
         }    
  } 
}
?> 

Hey, no one said the code had to be pretty, just that it should work.

 
In any case, the iterations and the associated HTML result in a list of pools appropriately colored by status (and no comments about the naming of my servers, got it?)


That’s it, that’s all there is to it. Of course, if you want to make this real time, a little bit of AJAX magic, another six pack of Dew, and you’ll have your own customized BIG-IP dashboard.