Learn F5 Technologies, Get Answers & Share Community Solutions Join DevCentral

Filter by:
  • Solution
  • Technology
code share

PHP and iControl REST

Problem this snippet solves:

PHP and iControl REST interfaces

Here are a couple of ways to use PHP and iControlREST (iCR). iCR is lighter-weight than iControl SOAP but is only supported on >= v11.5.

When using these, check that the PHP implementation supports cURL using phpinfo() or check your php.ini file for 'extension=php_curl.dll' or the relevant name.

I have included two ways to do this - via functions and via a PHP class. In practise the class is the simplest way to do this but the function seems to be the more efficient way of doing it. (Tested by retrieving ~700 Virtual Servers from a remote BIG-IP).

Using the attached files you can save them and modify as required. Change the IP address 172.24.9.129 to be relevant to your setup. Note that the iCR class uses the default username/password admin/admin.

Feel free to PM me if you have any specific requirements or issues.

How to use this snippet:

Example Class Usage:

include("iCR_class.php");
$r = new iCR ("172.24.9.129");
echo "<html><body><pre>";
echo "<h2>Non-existent Virtual Server</h2><pre>";

print_r($r->get("/ltm/virtual/iCR_Test_VS"));
echo $r->code;

$vs = array('name'=>"iCR_Test_VS",'destination'=>'192.168.1.1:80','mask'=>'255.255.255.255','ipProtocol'=>'tcp');

echo "</pre><h2>Created Virtual Server</h2><pre>";
print_r($r->create("/ltm/virtual",$vs));

echo "</pre><h2>Edited Virtual Server</h2><pre>";
$description = array('description' => 'This is a modified Virtual Server');
# Use the PATCH method to update ( the true as the third variable )
print_r($r->modify("/ltm/virtual/iCR_Test_VS",$description,true));
echo "Modify HTTP Return Code: $r->code\n";

echo "</pre><h2>Deleted Virtual Server</h2><pre>";
print_r($r->delete("/ltm/virtual/iCR_Test_VS"));
echo "Delete HTTP Return Code: $r->code\n";
print_r($r->get("/ltm/virtual/iCR_Test_VS"));

echo "</pre></body></html>";
`</pre>

Example Function Usage:

include("iCR.php");
$hostname = "172.24.9.129";
$username = "admin";
$password = "admin";

$BIGIP_URL_BASE = "https://$hostname/mgmt/tm";
$url = $BIGIP_URL_BASE."/ltm/virtual";
$handle = curl_init();
echo "<html><body><h2><pre>";

echo "</pre><h2>Non-existent Virtual Server</h2><pre>";
print_r(iCR($handle,$username,$password,"GET",$url."/iCR_Test_VS"));

// Create a Virtual Server
echo "</pre><h2>Created Virtual Server</h2><pre>";

$vs = array('name'=>"iCR_Test_VS",'destination'=>'192.168.1.1:80','mask'=>'255.255.255.255','ipProtocol'=>'tcp');
print_r(iCR($handle,$username,$password,'POST',$url,$vs));

// Edit the Virtual Server
echo "</pre><h2>Edited Virtual Server</h2><pre>";
$description = array('description' => 'This is a modified Virtual Server');
print_r(iCR($handle,$username,$password,'PUT',$url."/iCR_Test_VS",$description));

// Delete the Virtual Server
echo "</pre><h2>Deleted Virtual Server</h2><pre>";
print_r(iCR($handle,$username,$password,"DELETE",$url."/iCR_Test_VS"));

echo "</pre><h2>Post-delete Virtual Server</h2><pre>";
print_r(iCR($handle,$username,$password,"GET",$url."/iCR_Test_VS"));

echo "</pre></body></html>";

Code attachment:


Comments on this Snippet
Comment made 23-Mar-2016 by DevBabu 662
Thanks Pete. This was highly helpful. But I get performance issues when I do multiple calls. My code works like. 1. First Call - > get the pool names (/mgmt/tm/ltm/pool) 2. Second Call -> Based on the pool names(path), get it's status. (mgmt/tm/ltm/pool/~pool~name/stats) 3. Third Call -> Based on the pool names(path), get it's pool members. (/mgmt/tm/ltm/pool/~pool~names/members) PHP CODE =================== <br> ` <?php include('./includes/iCR.php'); //Authentication Data $BASE_URL = "https://bigip/mgmt/tm"; $username = "admin"; $password = "admin"; //GET ALL THE POOLS $pool_data = iCR($username, $password, "GET", $BASE_URL."/ltm/pool/?\$select=name,fullPath", NULL); //echo $pool_data; foreach ($pool_data['items'] as $pools) { echo $pools['name'] . "<br>"; $tildaPath = str_replace("/", "~", $pools['fullPath']); //GET THE pool stats $pool_stats = iCR($username, $password, "GET", $BASE_URL."/ltm/pool/".$tildaPath."/stats/?\$select=status.availabilityState", NULL); echo $pool_stats["entries"]["status.availabilityState"]["description"] . "<br>"; //GET THE pool members $pool_members = iCR($username, $password, "GET", $BASE_URL."/ltm/pool/".$tildaPath."/members/?\$select=name,address,state", NULL); foreach ($pool_members['items'] as $members) { echo $members['name']." ".$members['address']." ". $members['state']."<br>"; } } ?> ` ============================CODE================================================ <br> So, when make first call, I get ~1200 pool. Second call, will degrade the performance. And third call even makes everything worse. I get execution time exceeded error. I increased it to 300s but still that's not enough. Do you have any thoughts on optimizing this code. I would appreciate any help. Thanks
0
Comment made 03-May-2016 by Pete White
Thanks DevBabu, glad you found it useful. I think the issue you have is related to the fact that you are performing an individual iControl request for each of these items. Each iControl request takes milliseconds to perform which is a long time so you are better to make few iControl calls that retrieve large amounts of data and loop through that data, than to make hundreds of individual iControl calls that retrieve a small amount of data. To give you an example here, you should do three iControl calls - retrieve all pools, all pools status and all pool members. Then loop through these arrays as required. This is generally true whether using SOAP or REST.
0
Comment made 27-Nov-2016 by Santosh 0

Hi Pete, I am trying to use similar code sent by you but to fetch pools. The output format is not what I expected, below is the snippet of the response :

stdClass Object ( [kind] => tm:ltm:pool:poolcollectionstate [selfLink] => https://localhost/mgmt/tm/ltm/pool?$select=name&ver=11.6.1 [items] => Array ( [0] => stdClass Object ( [name] => CTUSOPService_IAT )

        [1] => stdClass Object
            (
                [name] => adptlm
            )

And I expected it to be like below :

{ "kind":"tm:ltm:pool:poolcollectionstate", "selfLink":"https://localhost/mgmt/tm/ltm/pool?$select=name&ver=11.6.1", "items":[ { "name":"CTUSOPService_IAT" }, { "name":"adptlm" },

Any reason why this is happening..? My intention is to use JsonPath against the output to fetch the required fields. Eg : $.items[*].name

0
Comment made 28-Nov-2016 by Pete White

Hi Santosh, The functions and methods return PHP variables because I used the json_decode method on the returned JSON. So the returned data is an object that contains an array. Therefore you can manage the array by using foreach on the array eg:

$handle = curl_init();
$icr = iCR($handle,"admin","admin","GET","https://<BIGIP address>/mgmt/tm/ltm/pool")
foreach ($icr->items as $i=>$v) {
  echo "Pool name:$v->name </br>";
}

If you want to retrieve the JSON, I suggest you use json_encode or alternatively change the code of the methods to return the JSON, although I can't see what using the JSON instead of the standard PHP functions will give you.

0
Comment made 1 month ago by tgbauer 0

Hi Pete,

For F5 LTM ver=13, needed to change the "PUT" to a "PATCH" in the modify() function. Otherwise got error when PATCHing the transaction like: transaction failed:0107028c:3: The source (::) and destination addresses for virtual server must be be the same type (IPv4 or IPv6).

Hear the change was made in ver=12 Know that "PUT" worked in ver=11

Maybe worth updating so it checks which version is in use and then uses the appropriate CURLOPT_CUSTOMREQUEST ?

By the way, thank you for all the work you put into this!! It is getting lots and lots of good use :-)

0
Comment made 1 month ago by Pete White

Hi tgbauer,

Great to hear that it has use, it helped me out when I needed it.

You make a very good point - in my iCR Python module I added the ability to set PATCH in the modify method by setting PATCH=True. I'll look at doing the same with this, then you can decide for yourself whether to use PUT or PATCH.

Are you able to send me details of the modify that you are trying to do - ie the URL and the data

Pete

0
Comment made 1 month ago by Pete White

Updated to include the use of PATCH. Note that with class the modify method is updated to include the PATCH variable. Set this to true to use PATCH method. Remove it or set to false to use PUT. For function, I have added the PATCH variable to the other methods.

Example with class:

<?php
include("iCR_class.php");
$r = new iCR ("172.24.9.129");
$description = array('description' => 'This is a modified Virtual Server');
print_r($r->modify("/ltm/virtual/iCR_Test_VS",$description,true));
echo "Modify HTTP Return Code: $r->code\n";

Example with function:

<?php
include("iCR.php");
$hostname = "172.24.9.129";
$username = "admin";
$password = "admin";
$BIGIP_URL_BASE = "https://$hostname/mgmt/tm";
$url = $BIGIP_URL_BASE."/ltm/virtual";
$handle = curl_init();
$description = array('description' => 'This is a modified Virtual Server');
print_r(iCR($handle,$username,$password,'PATCH',$url."/iCR_Test_VS",$description));

Let me know if you feel there are any other useful features required

0
Comment made 1 month ago by tgbauer 0

Thank you!

0