jgillman's Liquid Web Update Unofficial tips, tricks, and happenings from a Liquid Web sales engineer

21Aug/120

Utilizing the Stingray API

One of the benefits that a Managed Dedicated Load Balancing cluster provides is the ability to interact with it programmatically via a SOAP compliant API.

30Apr/120

Interactive Storm API Testing Script

What happens when I get bored? I code apparently.

Here's a piece of PHP code that runs purely command line. What it does is allow you to interactively work with the StormOnDemand API.

Although the output is just a straight print_r() of the returned data set, it does provide a nice easy way if you want to see the returns from various methods (or while feeding the same method different parameter/value pairs) in an expedient manner - all without having to write/replace code in a static script.

Enjoy!

 PHP | 
 
 copy code |
?

01
02
<?php
03
	/*
04
	 * Author: Jason Gillman Jr.
05
	 * Description: My attempt at writing a simple interactive CLI script for dumping raw data from Storm API returns.
06
	 * 				All you are going to get is print_r() of the returned array.
07
	 * 				Hope it's useful!
08
	 */
09
 
10
	require_once('StormAPI.class.php');
11
 
12
	// Initial information
13
	echo "\nAPI Username: "; $api_user = trim(fgets(STDIN));
14
	echo "Password: "; $api_pass = trim(fgets(STDIN));
15
	echo "Initial Method: "; $api_method = trim(fgets(STDIN));
16
 
17
	$storm = new StormAPI($api_user, $api_pass, $api_method);
18
 
19
	// Menu
20
	while(!isset($stop))
21
	{
22
		echo "\n\nPick your poison... \n";
23
		echo "1. Change method (will clear params) \n";
24
		echo "2. Add parameter \n";
25
		echo "3. Clear parameters \n";
26
		echo "4. Execute request and display \n";
27
		echo "5. Get me out of here \n";
28
		echo "Enter a number: "; fscanf(STDIN, "%d\n", $choice); // Get the choice
29
 
30
		switch($choice)
31
		{
32
			case 1:
33
				echo "\nEnter your new method: "; $api_method = trim(fgets(STDIN));
34
				$storm->new_method($api_method);
35
				break;
36
			case 2:
37
				echo "\nEnter the parameter: "; $parameter = trim(fgets(STDIN));
38
				echo "\nEnter the value: "; $value = trim(fgets(STDIN));
39
				$storm->add_param($parameter, $value);
40
				unset($parameter, $value);
41
				break;
42
			case 3:
43
				$storm->clear_params();
44
				break;
45
			case 4:
46
				print_r($storm->request());
47
				break;
48
			case 5:
49
				echo "\n\n";
50
				$stop = TRUE;
51
				break;
52
			default:
53
				echo "Really? How about you enter a valid value?";
54
				break;
55
		}
56
	}
57
?>
58

30Apr/120

StormOnDemand API Class update

I've yet again updated my StormOnDemand API PHP class.

For those who don't want to go to the PHP Classes site (which I highly recommend you do if you code OOP PHP - it's got a great collection of various PHP Classes), here is the source:

 PHP | 
 
 copy code |
?

01
02
<?php
03
	/*
04
	 * Author: Jason Gillman Jr.
05
	 * Description: This is my attempt at writing a PHP wrapper that will ease Storm API calls with PHP
06
	 * 				It will be designed to use the JSON format for talking with the API server.
07
	 * 				$api_method is as described in docs (Case doesn't matter)
08
	 * 				request() method returns an array generated from the API return
09
	 */
10
	class StormAPI
11
	{
12
		// Let's define attributes
13
		private $api_user, $api_pass, $base_url, $api_format, $api_full_uri, $api_request;
14
		private $api_request_body, $api_method, $api_params, $api_return; 
15
 
16
		function __construct($api_user, $api_pass, $api_method)
17
		{	
18
			$this->api_user = $api_user;
19
			$this->api_pass = $api_pass;
20
			$this->api_method = $api_method;
21
			$this->base_url = 'https://api.stormondemand.com/';
22
			$this->api_format = 'json';
23
 
24
			$this->api_full_uri = $this->base_url . $this->api_method . "." .$this->api_format;
25
			$this->api_request = curl_init($this->api_full_uri); // Instantiate
26
			curl_setopt($this->api_request, CURLOPT_RETURNTRANSFER, TRUE); // Don't dump directly to output
27
			curl_setopt($this->api_request, CURLOPT_SSL_VERIFYPEER, TRUE); // It does look like verification works now.
28
			curl_setopt($this->api_request, CURLOPT_USERPWD, "$this->api_user:$this->api_pass"); // Pass the creds
29
		}
30
 
31
		function add_param($parameter, $value)
32
		{
33
			$this->api_request_body['params'][$parameter] = $value;
34
		}
35
 
36
		function clear_params()
37
		{
38
			unset($this->api_request_body);
39
			curl_setopt($this->api_request, CURLOPT_HTTPGET, TRUE); //If the request was previously run with params, this cleans those out. Otherwise they go back with the request
40
		}
41
 
42
		function new_method($api_method, $clearparams = TRUE) // Clears out parameters by default, since they may not apply now
43
		{
44
			if($clearparams = TRUE)
45
			{
46
				unset($this->api_request_body);
47
				curl_setopt($this->api_request, CURLOPT_HTTPGET, TRUE); //If the request was previously run with params, this cleans those out. Otherwise they go back with the request
48
			}
49
 
50
			$this->api_method = $api_method; // New method, coming right up!
51
			$this->api_full_uri = $this->base_url . $this->api_method . "." .$this->api_format; // New URI since method change
52
			curl_setopt($this->api_request, CURLOPT_URL, $this->api_full_uri);
53
 
54
		}
55
 
56
		function request()
57
		{
58
			if(is_array($this->api_request_body)) // We have params
59
			{
60
				curl_setopt($this->api_request, CURLOPT_POST, TRUE); //POST method since we'll be feeding params
61
				curl_setopt($this->api_request, CURLOPT_HTTPHEADER, Array('Content-type: application/json')); // Since we'll be using JSON
62
				curl_setopt($this->api_request, CURLOPT_POSTFIELDS, json_encode($this->api_request_body)); // Insert the parameters
63
			}
64
 
65
			// Now send the request and get the return on investment
66
			try
67
			{
68
				return json_decode(curl_exec($this->api_request), TRUE); // Pull the trigger and get nice pretty arrays of returned data
69
			}
70
			catch (HTTP_Request2_Exception $e)
71
			{
72
				echo 'Error: ' . $e->getMessage();
73
			}
74
		}
75
	}
76
?>
77

Essentially, I added two new methods: clear_params() and new_method(). Both of these do what you might think - clearing existing set parameters and choosing a different API method.

Also, if you're so inclined, I believe you should be able to track updates to the PHP Classes project that I have with this RSS link. I've also added it to the right side of the page.

3Apr/120

Updated Storm On Demand API PHP Class

I just wanted to put out that I've updated my API class to use cURL instead of HTTP_REQUEST2 in my initial post.

Although it still utilizes YAML, this is my first move at getting away from third party packages.

Enjoy!

 PHP | 
 
 copy code |
?

01
02
<?php
03
	/*
04
	 * Author: Jason Gillman Jr.
05
	 * Description: This is my attempt at writing a PHP wrapper that will ease Storm API calls with PHP
06
	 * 				It will be designed to use the YAML format for talking with the API server.
07
	 * 				$api_method is as described in docs (Case matters)
08
	 * 				request() method returns an array generated from the API return
09
	 */
10
	class StormAPI
11
	{
12
		// Let's define attributes
13
		private $api_user, $api_pass, $base_url, $api_format, $api_full_uri, $api_request;
14
		private $api_request_body, $api_method, $api_params, $api_return; 
15
 
16
		function __construct($api_user, $api_pass, $api_method)
17
		{	
18
			$this->api_user = $api_user;
19
			$this->api_pass = $api_pass;
20
			$this->api_method = $api_method;
21
			$this->base_url = 'https://api.stormondemand.com/';
22
			$this->api_format = 'yaml';
23
 
24
			$this->api_full_uri = $this->base_url . $this->api_method . "." .$this->api_format;
25
			$this->api_request = curl_init($this->api_full_uri); // Instantiate
26
			curl_setopt($this->api_request, CURLOPT_RETURNTRANSFER, TRUE); // Don't dump directly to output
27
			curl_setopt($this->api_request, CURLOPT_SSL_VERIFYPEER, FALSE); // Apparently verification doesn't work with the API?
28
			curl_setopt($this->api_request, CURLOPT_USERPWD, "$this->api_user:$this->api_pass"); // Pass the creds
29
		}
30
 
31
		function add_param($parameter, $value)
32
		{
33
			$this->api_request_body['params'][$parameter] = $value;
34
		}
35
 
36
		function request()
37
		{
38
			if(isset($this->api_request_body)) // We have params
39
			{
40
				curl_setopt($this->api_request, CURLOPT_POST, TRUE); //POST method since we'll be feeding params
41
				curl_setopt($this->api_request, CURLOPT_HTTPHEADER, Array('Content-type: application/yaml')); // Since we'll be using YAML
42
				curl_setopt($this->api_request, CURLOPT_POSTFIELDS, yaml_emit($this->api_request_body)); // Insert the parameters
43
			}
44
 
45
			// Now send the request and get the return on investment
46
			try
47
			{
48
				return yaml_parse(curl_exec($this->api_request)); // Pull the trigger and get nice pretty arrays of returned data
49
			}
50
			catch (HTTP_Request2_Exception $e)
51
			{
52
				echo 'Error: ' . $e->getMessage();
53
			}
54
		}
55
	}
56
?>
57

Update on 4Apr12 @ 1300EDT
I have updated the class to utilize JSON instead of YAML. Code change was actually pretty straight forward. It is shown below:

 PHP | 
 
 copy code |
?

01
02
<?php
03
	/*
04
	 * Author: Jason Gillman Jr.
05
	 * Description: This is my attempt at writing a PHP wrapper that will ease Storm API calls with PHP
06
	 * 				It will be designed to use the YAML format for talking with the API server.
07
	 * 				$api_method is as described in docs (Case matters)
08
	 * 				request() method returns an array generated from the API return
09
	 */
10
	class StormAPI
11
	{
12
		// Let's define attributes
13
		private $api_user, $api_pass, $base_url, $api_format, $api_full_uri, $api_request;
14
		private $api_request_body, $api_method, $api_params, $api_return; 
15
 
16
		function __construct($api_user, $api_pass, $api_method)
17
		{	
18
			$this->api_user = $api_user;
19
			$this->api_pass = $api_pass;
20
			$this->api_method = $api_method;
21
			$this->base_url = 'https://api.stormondemand.com/';
22
			$this->api_format = 'json';
23
 
24
			$this->api_full_uri = $this->base_url . $this->api_method . "." .$this->api_format;
25
			$this->api_request = curl_init($this->api_full_uri); // Instantiate
26
			curl_setopt($this->api_request, CURLOPT_RETURNTRANSFER, TRUE); // Don't dump directly to output
27
			curl_setopt($this->api_request, CURLOPT_SSL_VERIFYPEER, FALSE); // Apparently verification doesn't work with the API?
28
			curl_setopt($this->api_request, CURLOPT_USERPWD, "$this->api_user:$this->api_pass"); // Pass the creds
29
		}
30
 
31
		function add_param($parameter, $value)
32
		{
33
			$this->api_request_body['params'][$parameter] = $value;
34
		}
35
 
36
		function request()
37
		{
38
			if(isset($this->api_request_body)) // We have params
39
			{
40
				curl_setopt($this->api_request, CURLOPT_POST, TRUE); //POST method since we'll be feeding params
41
				curl_setopt($this->api_request, CURLOPT_HTTPHEADER, Array('Content-type: application/json')); // Since we'll be using JSON
42
				curl_setopt($this->api_request, CURLOPT_POSTFIELDS, json_encode($this->api_request_body)); // Insert the parameters
43
			}
44
 
45
			// Now send the request and get the return on investment
46
			try
47
			{
48
				return json_decode(curl_exec($this->api_request), TRUE); // Pull the trigger and get nice pretty arrays of returned data
49
			}
50
			catch (HTTP_Request2_Exception $e)
51
			{
52
				echo 'Error: ' . $e->getMessage();
53
			}
54
		}
55
	}
56
?>
57

18Jul/114

Utilizing the Storm API with PHP

One of most powerful features of StormOnDemand is the API.

With the API, you can do anything with your Storm account programmaticaly that you can in the regular web based interface. It's a powerful tool that would allow for things such as automatic instance resizing based on load, emailed load reports, etc. However, I think that the API isn't utilized as much because people might not know how to work with it. What follows is a primer for utilizing PHP to interface with the API (I know PHP much, much, much more than Perl).

Although the documentation might seem a little terse in regards to making calls to the API, it essentially boils down to HTTP POST methods utilizing one of the supported encodings, which are currently JSON, YAML, and XML. Making these calls procedurally can quickly turn your code into something that resembles Italian cuisine, which is why I cobbled together a class to take a more object oriented approach.

The class utilizes the YAML encoding method, as well as the HTTP_REQUEST2 PEAR package. Again, this is just something that I put together, and there are probably much better ways to approach this. But it works. Here is the source:

 PHP | 
 
 copy code |
?

01
<?php
02
	/*
03
	 * Author: Jason Gillman Jr.
04
	 * Description: This is my attempt at writing a PHP wrapper that will ease Storm API calls with PHP
05
	 * 				It will be designed to use the YAML format for talking with the API server.
06
	 * 				$api_method is as described in docs (Case matters)
07
	 * 				request() method returns an array generated from the API return
08
	 */
09
	class StormAPI
10
	{
11
		// Let's define attributes
12
		private $api_user, $api_pass, $base_url, $api_format, $api_full_uri, $api_request;
13
		private $api_request_body, $api_method, $api_params, $api_return; 
14
 
15
		function __construct($api_user, $api_pass, $api_method)
16
		{
17
			// Requires PEAR Package HTTP_Request2
18
			require_once('HTTP/Request2.php');
19
 
20
			$this->api_user = $api_user;
21
			$this->api_pass = $api_pass;
22
			$this->api_method = $api_method;
23
			$this->base_url = 'https://api.stormondemand.com/';
24
			$this->api_format = 'yaml';
25
 
26
			$this->api_full_uri = $this->base_url . $this->api_method . "." .$this->api_format;
27
		}
28
 
29
		function add_param($parameter, $value)
30
		{
31
			$this->api_request_body['params'][$parameter] = $value;
32
		}
33
 
34
		function request()
35
		{
36
			// HTTP Request goodness
37
			if(isset($this->api_request_body)) // We have params
38
			{
39
				$api_request = new HTTP_Request2($this->api_full_uri, HTTP_Request2::METHOD_POST); // Instantiate with POST method since we'll be feeding params
40
				$api_request->setHeader('Content-type: application/yaml'); // Specify what you're feeding it
41
				$api_request->setBody(yaml_emit($this->api_request_body));
42
			}
43
			else // No params
44
			{
45
				$api_request = new HTTP_Request2($this->api_full_uri, HTTP_Request2::METHOD_GET); // Instantiate with GET method since no params
46
			}
47
			$api_request->setAuth($this->api_user, $this->api_pass, HTTP_Request2::AUTH_BASIC); // Auth stuff
48
			$api_request->setConfig('ssl_verify_peer', FALSE); // This is needed, otherwise HTTP_Request errors last I checked
49
 
50
			// Now send the request and get the return on investment
51
			try
52
			{
53
				$api_return = $api_request->send();
54
				return yaml_parse($api_return->getBody()); // We now have a nice array of all the returned data
55
			}
56
			catch (HTTP_Request2_Exception $e)
57
			{
58
				echo 'Error: ' . $e->getMessage();
59
			}
60
		}
61
	}
62
?>

One thing that I should mention before continuing is that you need to create an API user. This is done in the interface through Account >> Users

Essentially, you instantiate the class by passing the API username, password, and the API method you are going to be using. The API method comes in the format "First/Second/third" or "First/second" depending on the method you want to use. You don't include the leading slash, and the methods as far as I know are case sensitive.

Once you instantiate the object, you would use the add_param() method in the format of (parameter, value).

Once you add all the parameters (if any), just run the request() method, which will return an array containing the data.

So let's look at a real simple example scenario where you wanted to get the Five Minute load average for a particular server with a uniq_id of '123ABC':

 PHP | 
 
 copy code |
?

01
<?php
02
 
03
require_once(StormAPI.class.php); // Assuming we put the class in this file
04
 
05
$api_user = 'user';
06
$api_pass = 'pass';
07
$api_method = 'Monitoring/Load/stats';
08
 
09
$get_load = new StormAPI($api_user, $api_pass, $api_method);
10
$get_load->add_param('uniq_id', '123ABC'); // Where we pass our uniq_id
11
$results = $get_load->request(); // Initial array grab
12
 
13
// Now to get the five minute load
14
echo "Five Minute Load Average is: " . $results['loadavg']['five'];
15
 
16
//Done
17
?>

That's it. Relatively simple if you have a nice class to use. In order to get the uniq_id for a server, you would use the Server/list method.

Of course you can do this either via a web based application, or a CLI ran PHP script, for example, that might belong in a cron job (for checking load every so often for example).

Hopefully this gives a good starting point for working with the API. If you have questions, just leave a comment!

Updated as of April 2012: The class has been updated to utilize cURL and JSON

   
FireStats icon Powered by FireStats
Optimization WordPress Plugins & Solutions by W3 EDGE