interfacelab

Avatar

Slicehost API Notes for the Non-Rails Posse

I just want to start out by stating that I, in fact, am a big fan of Slicehost and constantly recommend them to friends setting up anything more serious than blogs. They have a truly great offering and their customer service has only been rivaled, in my experience, by the support team from DataPipe – whom I whole heartedly recommend for any colo or managed hosting.

One thing that is truly great about Slicehost is that they offer an awesome API that allows you to do most everything you can do in their management console, but instead through web services. You can create new slices, reboot them, change and add DNS, as well as rebuild or destroy slices.

The only problem is that the API follows a “standard ActiveResource pattern” that comes straight from the bowels of Rails and is way too convoluted for something this simple.

My biggest complaint is that instead of POSTing standard post variables, you POST XML, but none of the data being posted approaches any kind of structural complexity that warrants it’s usage. It just a layer of crap that doesn’t need to be there. Every modern language has some sort of HTTP request mechanism that handles all this stuff without some arbitrary object model forced on top of it.

Curiously, there appears to be another way where you can POST regular form data, but the variable names are in the form “resource[field]” which, again, seems completely unnecessary. I also couldn’t get it to work reliably.

As a point of reference, I was able to implement S3, EC2 and SQS API’s from amazon in just under 6 hours. It took me two days to figure out the Slicehost API. The ActiveResource pattern is a failure in my estimation.

The following are my notes on implementing the slicehost API. Hope you find it useful.

NOTE: This post doesn’t cover their DNS API as I don’t have a particular need for it. I will be posting the PHP library I wrote for the Slicehost API to github over the weekend. Perhaps someone can build on top of that…

Authentication

I actually had a bit of a bitch with this. The docs and ruby samples specify that you put your API key in the url, like this:

https://APIKEY@api.slicehost.com

Problem is that I just could not get it to work. Even the ruby samples in their docs didn’t run without authentication errors. Copying and pasting the URLs into Safari didn’t work either (simply pasting your API key into the user input when the Basic Authentication popup shows does work though).

So, make sure you always set the USER part of Basic Auth with your API key. In PHP it looks like this (using PEAR’s HTTP_Request object):

$request->basic_auth(YOUR_API_KEY,’’);

 

Dealing With Slices

This is the part that drove me nuts. I ended up having to debug their ruby examples through Charles, after patching activeresource.rb to support proxies. And even then, their examples didn’t work due to a typo and another error I couldn’t sort out.

Listing Slices

This is easy as pie. Simply make a GET request to:

https://api.slicehost.com/slices.xml

You will get back an XML document as a response:

<?xml version="1.0" encoding="UTF-8"?>
<slices type="array">
	<slice>
		<name>slicename</name>
		<status>active</status>
		<addresses type="array">
			<address>XXX.XXX.XXX.XXX</address>
			<address>XXX.XXX.XXX.XXX</address>
		</addresses>
		<id type="integer">666</id>
		<progress type="integer">100</progress>
		<bw-out type="float">0.0</bw-out>
		<bw-in type="float">0.0</bw-in>
		<image-id type="integer">10</image-id>
		<ip-address>XXX.XXX.XXX.XXX</ip-address>
		<flavor-id type="integer">2</flavor-id>
	</slice>
</slices>

The one issue I have with this is that the <address> element doesn’t specify if the address is internal or external. Right now, you can only make the assumption that the first address is external and the second one is internal. Not a big deal though.

Also, note the .xml extension. I believe this is arbitrary, but it would be dope if you could specify .json or .yaml or some other format. Again, not a big deal.

Getting Slice Info

This is equally as simple:

https://api.slicehost.com/slices/666.xml

Where 666 is the ID of the slice you want to get info about. You get another XML document in return containing a <slice> element as above.

Creating a Slice From an Image

This is relatively simple, but there are a couple of steps to it.

First you need a list of the images that Slicehost offers. Easy enough. GET request to :

https://api.slicehost.com/images

Will return an XML document that looks like this:

<images type="array">
	<image>
		<name>CentOS 5.2</name>
		<id type="integer">2</id>
	</image>
	<image>
		<name>Gentoo 2008.0</name>
		<id type="integer">3</id>
	</image>
	<image>
		<name>Debian 5.0 (lenny)</name>
		<id type="integer">4</id>
	</image>
	{ .. and so on .. }
</images>

Once you have this list, you’ll have need to figure out what flavors of slices you can create. Do this by sending another GET request to:

https://api.slicehost.com/flavors

Again, you’ll get another list that looks like this:

<flavors type="array">
	<flavor>
		<id type="integer">1</id>
		<name>256 slice</name>
		<price type="integer">2000</price>
		<ram type="integer">256</ram>
	</flavor>
	<flavor>
		<id type="integer">2</id>
		<name>512 slice</name>
		<price type="integer">3800</price>
		<ram type="integer">512</ram>
	</flavor>
	<flavor>
		<id type="integer">3</id>
		<name>1GB slice</name>
		<price type="integer">7000</price>
		<ram type="integer">1024</ram>
	</flavor>
	{ ... and so on ... }
</flavors>

So now we know the ID for the image and the ID for flavor of slice. Let’s keep going!

This next bit took me awhile to get going. When I tried to go through the method of posting good old post data, I would get back really obscure errors. So debugging the HTTP traffic of the ruby examples, I unearthed the secret sauce.

To create the slice with the image of your choosing, POST an XML document to:

https://api.slicehost.com/slices/

But, make absolutely sure that you have set the “Content-Type” of your request to “text/xml” otherwise it no worky. Your XML document will look like:

<slice>
	<name>NAME OF YOUR SLICE</name>
	<flavor-id type="integer">1</flavor-id>
	<image-id type="integer">2</image-id>
</slice>

The <image-id> must be a valid ID from the list above, of course. Their API docs have a typo where the sample code to create a slice uses an ID of 1, which doesn’t exist. A little hair pulling on that one, even though the bug was so obvious. The same thing goes for the <flavor-id>.

The response you receive will be information about you slice, including the root password. You only get this root password once, so make sure you take note of it. The response looks like:

<slice>
	<status>build</status>
	<name>SLICE NAME</name>
	<addresses type="array">
		<address>XXX.XXX.XXX.XXX</address>
		<address>XXX.XXX.XXX.XXX</address>
	</addresses>
	<id type="integer">666</id>
	<root-password>ROOT PASSWORD</root-password>
	<progress type="integer">0</progress>
	<bw-out type="float">0.0</bw-out>
	<bw-in type="float">0.0</bw-in>
	<image-id type="integer">2</image-id>
	<ip-address>XXX.XXX.XXX.XXX</ip-address>
	<flavor-id type="integer">1</flavor-id>
</slice>

And that’s it, you’ve created your slice!

Creating a Slice From a Backup

This is nearly the same as creating from an image, but this time we’ll need a list of available backups. Backups are things you create through the Slicehost management interface. What I like to do is build a base system and then take a snapshot. With that snapshot I can create new slices based on it.

To grab a list of backups, send a GET request to:

https://api.slicehost.com/backups

You will receive a list (if you have any backups):

<backups type="array">
	<backup>
		<id>3-666</id>
		<slice_id>666</slice_id>
		<name>daily</name>
		<date>Sat May 09 04:15:05 UTC 2009</date>
	</backup>
	<backup>
		<id>3-667</id>
		<slice_id>666</slice_id>
		<name>webserver_snapshot</name>
		<date>Sat May 09 04:15:05 UTC 2009</date>
	</backup>
</backups>

And, then, in the XML document you POST:

<slice>
	<name>NAME OF YOUR SLICE</name>
	<flavor-id type="integer">1</flavor-id>
	<backup-id type="integer">3-666</backup-id>
</slice>

Everything else is the same as creating a slice from an image.

Updating a Slice

The only thing you can update with your slice is it’s name. This is accomplished by PUTing an XML document to:

https://api.slicehost.com/slices

The XML doc looks like:

<slice>
	<id type="integer">666</id>
	<name>NAME OF YOUR SLICE</name>
</slice>

All you need is the ID of the slice and it’s new name. The response will be an XML document with a <slice> node.

Deleting a Slice

Delete a slice by sending an XML document using the DELETE HTTP verb:

<slice>
	<id type="integer">666</id>
</slice>

NOTE: You will have to have this option enabled in the API settings on your account. You can edit those settings at: https://manage.slicehost.com/api/

Rebooting Your Slices

To reboot your slice with a hard reset, send a PUT request to:

https://api.slicehost.com/slices/YOUR SLICE ID/hard_reboot.xml

To do a soft reboot, a PUT request to:

https://api.slicehost.com/slices/YOUR SLICE ID/reboot.xml

Rebuilding Your Slices

To rebuild your slice, you’ll need to use an image ID or a backup ID. Once you’ve picked one, send a PUT request to:

https://api.slicehost.com/slices/YOUR SLICE ID/rebuild.xml?image_id=X

or:

https://api.slicehost.com/slices/YOUR SLICE ID/rebuild.xml?backup_id=X

Conclusion

So that’s all I know. As you can see the API is pretty simple, but not as simple as it could be, nor are the documents even remotely near as useful as they should be. But, it’s awesome they have this API in the first place so I’ll stop bitching now!

Again, thanks to Slicehost for making awesome. The world sure does need it.

[Slashdot] [Digg] [Reddit] [del.icio.us] [Facebook] [Technorati] [Google] [StumbleUpon]
1 Star2 Stars3 Stars4 Stars5 Stars (5 votes, average: 5 out of 5)
Loading ... Loading ...