Archive for the 'Implementations' Category

Something new for your API Toolbox

An interesting facet of the development and systems administration business is the number of 80% projects that build up over time. An 80% project is that awesome library, script, rewrite, new system, or what have you that’s cooling on your back burner. It’s almost done but it’s missing the finishing touches. Maybe it needs a few code tweaks. Maybe it needs a little more documentation. Maybe you’re still finalizing settings and playing with patches. Don’t lie; we know you’ve got these projects hanging around. I’ve got a list of 80% projects as long as my arm.

It’s time to check something off my 80% projects list. I’ve finally finished documenting and am happy to release the SoftLayer API Perl client library! This module will make Perl API hackers’ lives a whole lot easier. Previously you had to build SOAP API calls manually using the SOAP::Lite module and parse the response into something easier to handle. Now you can accomplish the same thing with a series of easy to use helper methods. Functionality is very similar to our PHP client but with a Perl twist. For instance, you can do clever one liners!

use SoftLayer::API::SOAP;

# Grab my account information.
my $account = SoftLayer::API::SOAP->new(
    'SoftLayer_Account',
    undef,
    'my API username',
    'my API key')->getObject();

Check out our README for many and more comprehensive examples. Download the library from our github page at:

 

http://github.com/softlayer/softlayer-api-perl-client

 

As with all of our projects we’re very open to feedback, so please comment or post on our forums and let us know what you think. I can’t wait knock a few more 80% projects off the ol’ list. You’re going to love them. :) See y’all next time!

No comments

Object Masks and Filters in C Sharp

Object Masks, Filters, and Other V3 Black Magic

Everyone has heard the age old saying for any given job you need to have the right tool. Just as most of us have tried to use the flat rounded edge of a butter knife a time or two when what we desperately needed was a screw driver. Does that mean you weren’t able to open that little compartment on whatever gizmo and replace the batteries? Probably not. In most cases it is possible to use a butter knife when a screw driver is the tool of choice; it’s just more painful and a lot less effective.

The same can said of the SoftLayer API (SLAPI). It’s a toolset. A very flexible set of tools allowing a developer to manage every aspect of dedicated hosting from accounting and billing to physical status of remote hardware. And yet there are so many tools in the V3 API toolbox, a number of them only subtlety different from their binary brethren ( at least on the surface), it’s tempting just to reach your hand into the bag, find the first thing that resembles a screw driver, and begin turning.

I know. I’m speaking from my own experiences. As a developer who largely works on SoftLayer’s back end systems, somewhere between the bottom of TCP/IP stack and the top edge of the kernel, recently getting to do production user portal code was a new experience for me. Sure I wrote some demos, dabbled a little here and there, but when I started doing my first “real” V3/SLAPI intensive project I realized my prior attempts had entirely missed the true power and elegance of SLAPI. The magic if you will. A little something called ORM.

Those of you who spend your days toiling in the world or relational databases are probably fairly familiar with the term ORM. But for someone like me who usually comes no closer to a database than reading an I/O address from the Windows registry, I was only vaguely aware of what the acronym even stood for. I turned to Webopedia. There I discovered the following. “Short for object role modeling, ORM is a conceptual database design methodology that allows the user to express information as an object and explore how it relates to other information objects”.

So there we have it. Database. Objects. Relations. I learn hands on—so none of that amounts to a hill of beans without some real code I can see and type and run for myself. So rather than regurgitate the SLDN documentation, I will just share a simple yet real life example. Then, in the second part of the article, we can expand that example to show some of the more powerful and less documented features of the V3 SLAPI.

The code that follows is written in Microsoft C Sharp using Visual Studio 2008 Professional Edition. I am not going to step through the basics of connecting a WSDL and generating a SOAP wrapper in this article. If you need help with that, there is an SLDN blog I did a while back which covers those steps entitled, “Dot Net? You Bet!”. It is still available under the implementations section of the SLDN website. True to my MO, I am not a big GUI guy so the code I am presenting runs as a Windows console application.

For the sake of making the example clear, I am going to simplify my task. In the example in both this article, and the next in the series, we will be playing the role of a developer who needs to count how many of his or her servers are running the Microsoft Windows operating system, as opposed to one of the many Linux variants SoftLayer also offers its customers. For our first code sample, we require two WSDLs: the SoftLayer_Account service as well as the SoftLayer_Hardware_Server service. The console program below will get us connected to the SoftLayer application servers, as well as provide us some timing metrics.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace SLDN_Magic
{
   class Program
   {
       static void Main(string[] args)
       {
           //global timing vars
           DateTime stopwatch;
           TimeSpan elapsed;

           //replace with your username and api key
           string user_name = "Replace With Your User Name";
           string api_key = "Replace With Your API Key";

           Console.Write("Establishing connection to SLDN service...");

           //time it
           stopwatch = DateTime.Now;
           //declare the services
           SLDN_ACCT.SoftLayer_AccountService acct = new
               SLDN_ACCT.SoftLayer_AccountService();
           SLDN_SVR.SoftLayer_Hardware_ServerService svr = new
               SLDN_SVR.SoftLayer_Hardware_ServerService(); 

           //create an authentification object for each
           SLDN_ACCT.authenticate credentials_a = new
               SLDN_ACCT.authenticate();
           SLDN_SVR.authenticate credentials_b = new
               SLDN_SVR.authenticate();

           //assign credentials
           credentials_a.username = credentials_b.username = user_name;
           credentials_a.apiKey = credentials_b.apiKey = api_key;

           //authenticate
           acct.authenticateValue = credentials_a;
           svr.authenticateValue = credentials_b;

           elapsed = DateTime.Now.Subtract(stopwatch);
           Console.WriteLine("done (" +  elapsed.TotalSeconds.ToString() + " seconds)");

           Console.WriteLine("\nPress  to exit.");
           Console.ReadLine();
       }
   }
}

At this point, we can go ahead and run our code. It doesn’t really do anything all that useful. But never the less you should get an output similar to this.

While writing this article I connected to the SoftLayer API servers numerous times from my home. My connection times were pretty consistent. It took somewhere in the neighborhood of 20 seconds to get everything set up. That seems like a lot. But keep in mind that you only incur the overhead of connecting your services one time. Plus as we get a little further along in this article I will show you how we can use ORM to get rid of one of the references entirely. For now though, let’s move on.

For someone of my background and mindset, what seemed the most straight-forward and correct way to find out which servers were running MS Windows was to access the public method “isWindowsServer()“. This is a method off the server class. That’s why we needed to import the SoftLayer_Hardware_Server service. But we don’t want to check the OS on a single server. We want to recurse through all the servers for an account. Which is why we brought in the SoftLayer_Account service and its attractive public offering “getAllHardware()“.

Keeping this plan in mind, let’s go ahead and implement it in our console application.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace SLDN_Magic
{
   class Program
   {
       static void Main(string[] args)
       {
           //global timing vars
           DateTime stopwatch;
           TimeSpan elapsed;

           //global container
           SLDN_ACCT.SoftLayer_Hardware[] hw;

           //replace with your username and api key
           string user_name = "Replace With Your User Name";
           string api_key = "Replace With Your API Key";

           Console.Write("Establishing connection to SLDN service...");

           //time it
           stopwatch = DateTime.Now;

           //declare the services
           SLDN_ACCT.SoftLayer_AccountService acct = new
               SLDN_ACCT.SoftLayer_AccountService();
           SLDN_SVR.SoftLayer_Hardware_ServerService svr = new
               SLDN_SVR.SoftLayer_Hardware_ServerService(); 

           //create an authentification object for each
           SLDN_ACCT.authenticate credentials_a = new
               SLDN_ACCT.authenticate();
           SLDN_SVR.authenticate credentials_b = new
               SLDN_SVR.authenticate();

           //assign credentials
           credentials_a.username = credentials_b.username = user_name;
           credentials_a.apiKey = credentials_b.apiKey = api_key;

           //authenticate
           acct.authenticateValue = credentials_a;
           svr.authenticateValue = credentials_b;

           elapsed = DateTime.Now.Subtract(stopwatch);
           Console.WriteLine("done (" + elapsed.TotalSeconds.ToString() + " seconds)");

           //butter knife method

           Console.Write("Retrieving hardware using method 1...");

           //get time stamp
           stopwatch = DateTime.Now;

           hw = null;
           try
           {
               hw = acct.getHardware();
           }
           catch (Exception e)
           {
               Console.WriteLine("Exception encountered [" + e.Message + "]");
               hw = null;
           }

           int cnt = 0;

           foreach (SLDN_ACCT.SoftLayer_Hardware server in hw)
           {
               try
               {
                   SLDN_SVR.SoftLayer_Hardware_ServerInitParameters box = new
                       SLDN_SVR.SoftLayer_Hardware_ServerInitParameters();
                   box.id = (int)server.id;
                   svr.SoftLayer_Hardware_ServerInitParametersValue = box;
                   if (svr.isWindowsServer())
                   {
                       cnt++;
                   }
               }
               catch (NullReferenceException)
               {
                   //ignore...this server has not had the
                   //OS loaded on it yet!
               }
           }

           elapsed = DateTime.Now.Subtract(stopwatch);

           Console.WriteLine("done (" + elapsed.TotalSeconds.ToString() + " seconds)");
           Console.WriteLine("counted " + cnt.ToString() + " MS Windows licenses");
           Console.WriteLine("\nPress  to exit.");
           Console.ReadLine();
       }
   }
}

That’s it. Pretty straight forward stuff possibly with the exception of the way SLAPI allows you to reinitialize the server (or any object) on the fly by use of:”SoftLayer_Hardware_ServerInitParameters”. If this confuses you, again I’ll refer you to the blog “Dot Net? You Bet!”. At this point, I think we are ready for another test run.

Once again we find ourselves in the twenty second range both for connecting the services and counting the hardware. What you can’t tell from looking at this output is that the account I was using for testing had about 100 servers on it. So basically we are talking 1/5 of a second per server. It’s certainly doable with a handful of servers, but this would obviously never work if you were trying to present this information real time to users if you managed 500 or 5,000 or 50,000 servers. So you are probably asking yourself the same thing I did. What gives? If SoftLayer wishes its customers success on an enterprise level, why create an API that comes to its knees when you start trying to manage more than a few hundred servers?

Luckily, the architects of SLAPI were a lot more web / database savvy than me. The above implementation, while correct syntactically, is a gross misuse of the SLAPI. It’s the butter knife, when what we really need is the screwdriver. What we need are object masks. But exactly what are object masks and how do they relate to ORM?

The best way I have found to understand ORM and object masks, is to think of the SLAPI data objects, as a self supporting entities. Each object provides its own methods and exposes some properties specific to that object. Yet thanks to ORM, most objects can actually get to properties in related objects, through a process called tapping. You simply tap each object down the chain until you find the property or properties you are interested in, prior to retrieving an instance or instances of the object. Then the set of objects returned will expose any relevant properties in the same manner you tapped them.

For example in our case the SLDN architecture relates a server to an operating system in the following manner.

The diagram shows us that essentially, as long as we can get a hardware object, we can tap all the way down to the software description — which as the SLDN documentation states has a “name” property. There by we eliminate two of our most time consuming tasks from our original application. First off we no longer need to instantiate the SoftLayer_Hardware_Server service, since we can get to server from hardware and hardware can be retrieved via the account class. Secondly, if when we return the hardware it already contains the name of the operating system, we no longer have a need to call the “isWindows()” method. Take a look.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace SLDN_Magic
{
   class Program
   {
       static void Main(string[] args)
       {
           //global timing vars
           DateTime stopwatch;
           TimeSpan elapsed;

           //global container
           SLDN_ACCT.SoftLayer_Hardware[] hw;

           //replace with your username and api key
           string user_name = "Your User Name Here";
           string api_key = "Your Api Key Here";

           Console.Write("Establishing connection to SLDN service...");

           //time it
           stopwatch = DateTime.Now;

           //declare the services
           SLDN_ACCT.SoftLayer_AccountService acct = new
               SLDN_ACCT.SoftLayer_AccountService();

           //create an authentification object
           SLDN_ACCT.authenticate credentials_a = new
               SLDN_ACCT.authenticate();

           //assign credentials
           credentials_a.username = user_name;
           credentials_a.apiKey = api_key;

           //authenticate
           acct.authenticateValue = credentials_a;

           elapsed = DateTime.Now.Subtract(stopwatch);
           Console.WriteLine("done (" + elapsed.TotalSeconds.ToString() + " seconds)");

           //method 2
           Console.Write("Retrieving hardware using method 2...");

           //get time stamp
           stopwatch = DateTime.Now;

           hw = null;
           //attempt to pull a hardware list for this user
           try
           {
               acct.SoftLayer_AccountObjectMaskValue = new
                   SLDN_ACCT.SoftLayer_AccountObjectMask();
               acct.SoftLayer_AccountObjectMaskValue.mask = new
                   SLDN_ACCT.SoftLayer_Account();
               acct.SoftLayer_AccountObjectMaskValue.mask.hardware = new
                   SLDN_ACCT.SoftLayer_Hardware_Server[1];
               acct.SoftLayer_AccountObjectMaskValue.mask.hardware[0] = new
                   SLDN_ACCT.SoftLayer_Hardware_Server();
               acct.SoftLayer_AccountObjectMaskValue.mask.hardware[0].operatingSystem = new
                   SLDN_ACCT.SoftLayer_Software_Component();
               acct.SoftLayer_AccountObjectMaskValue.mask.hardware[0].operatingSystem.softwareLicense = new
                   SLDN_ACCT.SoftLayer_Software_License();
               acct.SoftLayer_AccountObjectMaskValue.mask.hardware[0].operatingSystem.softwareLicense.softwareDescription = new
                   SLDN_ACCT.SoftLayer_Software_Description();
               hw = acct.getHardware();
           }
           catch (Exception e)
           {
               Console.WriteLine("Exception encountered [" + e.Message + "]");
               hw = null;
           }

           cnt = 0;

           foreach (SLDN_ACCT.SoftLayer_Hardware server in hw)
           {
               try
               {
                   if (server.operatingSystem.softwareLicense.
                                   softwareDescription.name.ToLower().
                                   Contains("windows"))
                   {
                       cnt++;
                   }
               }
               catch (NullReferenceException)
               {
                   //ignore...this server has not
                   //had the OS loaded on it yet!!!
               }
           }

           elapsed = DateTime.Now.Subtract(stopwatch);

           Console.WriteLine("done ("+ elapsed.TotalSeconds.ToString()+" seconds)");
           Console.WriteLine("counted " + cnt.ToString() + " MS Windows licenses");

           Console.WriteLine("\nPress  to exit.");
           Console.ReadLine();
       }
   }
}

You should notice right away all the references to SoftLayer_AccountObjectMaskValue prior to calling the “getHardware()” method. This is the object mask. Essentially we must create a new instance of each entity we want to include down the chain. Then when the target object is retrieved, in our case the hardware, all related objects which we have made room for will get created for that specific instance of hardware, assuming of course a record exists. You must instantiate each object down the chain. If you skip any link your result set will not conatain the property or method you were trying to get to. Some less structured langagues, like PHP, do not have this requirement. But with V3 and dot NET there is no getting around it. You’re probably thinking this version of the code looks far more cluttered and is not as straight-forward to read. You’re right. But I contend this is the electric screwdriver in the SLDN toolbox. See for yourself.

As you can see the connection overhead dropped in half, which is to be expected since we are only authenticating to half the number of services. But take a look at the second number, the number of seconds it takes to count the servers with Windows installed. It dropped from 20 seconds, to under 2 seconds. That’s a 10 times speed gain. And wait there’s more– because we are only making one call to the SLDN application servers to retrieve those records what you see is what you get. Meaning you should not expect that time to increase noticeably whether you have a hundred servers or a hundred thousand servers! That my friend is the magic of V3. The power of ORM.

Following this article I will include the entire code base, in a combined application that lets you run the tests sequentially so you can see the amazing difference object masks make for yourself. In the second part to this article, we’ll continue with the sample so if you download it keep it handy. In part two I’ll discuss the next best thing to object masks—object filters. With object filters we’ll be able to streamline this code even more. Until then…happy SLDNing!

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace SLDN_Magic
{
   class Program
   {
       static void Main(string[] args)
       {
           //global timing vars
           DateTime stopwatch;
           TimeSpan elapsed;

           //global container
           SLDN_ACCT.SoftLayer_Hardware[] hw;

           //replace with your username and api key
           string user_name = "";
           string api_key = "";

           Console.Write("Establishing connection to SLDN service...");

           //time it
           stopwatch = DateTime.Now;

           //declare the services
           SLDN_ACCT.SoftLayer_AccountService acct = new SLDN_ACCT.SoftLayer_AccountService();
           SLDN_SVR.SoftLayer_Hardware_ServerService svr = new SLDN_SVR.SoftLayer_Hardware_ServerService(); 

           //create an authentification object for each
           SLDN_ACCT.authenticate credentials_a = new SLDN_ACCT.authenticate();
           SLDN_SVR.authenticate credentials_b = new SLDN_SVR.authenticate();

           //assign credentials
           credentials_a.username = credentials_b.username = user_name;
           credentials_a.apiKey = credentials_b.apiKey = api_key;

           //authenticate
           acct.authenticateValue = credentials_a;
           svr.authenticateValue = credentials_b;

           elapsed = DateTime.Now.Subtract(stopwatch);
           Console.WriteLine("done (" + elapsed.TotalSeconds.ToString() + " seconds)");

           //method 1

           Console.Write("Retrieving hardware using method 1...");

           //get time stamp
           stopwatch = DateTime.Now;

           hw = null;
           try
           {
               hw = acct.getHardware();
           }
           catch (Exception e)
           {
               Console.WriteLine("Exception encountered [" + e.Message + "]");
               hw = null;
           }

           int cnt = 0;

           foreach (SLDN_ACCT.SoftLayer_Hardware server in hw)
           {
               try
               {
                   SLDN_SVR.SoftLayer_Hardware_ServerInitParameters box = new SLDN_SVR.SoftLayer_Hardware_ServerInitParameters();
                   box.id = (int)server.id;
                   svr.SoftLayer_Hardware_ServerInitParametersValue = box;
                   if (svr.isWindowsServer())
                   {
                       cnt++;
                   }
               }
               catch (NullReferenceException)
               {
                   //ignore...this server has not had the OS loaded on it yet
               }
           }

           elapsed = DateTime.Now.Subtract(stopwatch);

           Console.WriteLine("done (" + elapsed.TotalSeconds.ToString() + " seconds)");
           Console.WriteLine("counted " + cnt.ToString() + " MS Windows licenses");

           //method 2
           Console.Write("Retrieving hardware using method 2...");

           //get time stamp
           stopwatch = DateTime.Now;

           hw = null;
           //attempt to pull a hardware list for this user
           try
           {
               acct.SoftLayer_AccountObjectMaskValue = new SLDN_ACCT.SoftLayer_AccountObjectMask();
               acct.SoftLayer_AccountObjectMaskValue.mask = new SLDN_ACCT.SoftLayer_Account();
               acct.SoftLayer_AccountObjectMaskValue.mask.hardware = new SLDN_ACCT.SoftLayer_Hardware_Server[1];
               acct.SoftLayer_AccountObjectMaskValue.mask.hardware[0] = new SLDN_ACCT.SoftLayer_Hardware_Server();
               acct.SoftLayer_AccountObjectMaskValue.mask.hardware[0].operatingSystem = new SLDN_ACCT.SoftLayer_Software_Component();
               acct.SoftLayer_AccountObjectMaskValue.mask.hardware[0].operatingSystem.softwareLicense = new SLDN_ACCT.SoftLayer_Software_License();
               acct.SoftLayer_AccountObjectMaskValue.mask.hardware[0].operatingSystem.softwareLicense.softwareDescription = new SLDN_ACCT.SoftLayer_Software_Description();
               hw = acct.getHardware();
           }
           catch (Exception e)
           {
               Console.WriteLine("Exception encountered [" + e.Message + "]");
               hw = null;
           }

           cnt = 0;

           foreach (SLDN_ACCT.SoftLayer_Hardware server in hw)
           {
               try
               {
                   if (server.operatingSystem.softwareLicense.softwareDescription.name.ToLower().Contains("windows"))
                   {
                       cnt++;
                   }
               }
               catch (NullReferenceException)
               {
                   //ignore...this server has not had the OS loaded on it yet
               }
           }

           elapsed = DateTime.Now.Subtract(stopwatch);

           Console.WriteLine("done ("+elapsed.TotalSeconds.ToString()+" seconds)");
           Console.WriteLine("counted " + cnt.ToString() + " MS Windows licenses");

           Console.WriteLine("\nPress  to exit.");
           Console.ReadLine();
       }
   }
}
No comments

Using CURL to access CloudLayer Storage

CloudLayer Storage is billed as providing “anytime, anywhere access to your data”. This isn’t just referring to human interfaces, but also includes automated interfaces.

One easy way to automate access to CloudLayer Storage is through curl. Curl is available as a command-line tool in most every operating system and is typically used for transferring files. In this post I’ll show some examples on how to use curl to add, get, delete, or otherwise manipulate files in CloudLayer Storage. Note that this isn’t using the SoftLayer API, but instead interfaces directly with CloudLayer Storage.

Upload a file named “DSC1012.jpg” to an account owned by username “user@example.com” with a password of “PaSsWoRd”:

# curl –F filename=@DSC1012.jpg –u user@example.com:PaSsWoRd \
https://storage.cloudlayer.com/v1/files/

The command will return some XML tags. The items of interest are “FileID” and “lockID”. These values are important for future operations on the file.


<fileID>102C9C28-65C3-11DE-1234-2BE68BA216C2</fileID>
<lockID>6CDCEEB2-6B38-11DE-A510-123F439A2728</lockID>
<lockDuration>120</lockDuration>

The lock is to protect a file form reading or being manipulated during the upload process. The lock will expire in “lockDuration” seconds or the user can disable the lock manually.

Here is how to disable the lock using the lockID and the fileID generated from the upload operation:

# curl –d \
'action=unlock&lockid=6CDCEEB2-6B38-11DE-A510-123F439A2728' \
–u user@example.com:PaSsWoRd \
https://storage.cloudlayer.com/v1/files/102C9C28-65C3-11DE-1234-2BE68BA216C2/lock

If you ever lose track of the FileID, you can use this command to retrieve a listing of the files and containers (directories) in an account along with the FileIDs which are listed as an “oid” XML tag.

# curl –u user@example.com:PaSsWoRd \
https://storage.cloudlayer.com/v1/files/list

To get the list of files in a container, just append the container oid to the URL.

# curl –u user@example.com:PaSsWoRd \
https://storage.cloudlayer.com/v1/files/list?oid=37D0F2AC-08FC-11DE-1234-3FA3A91CD1B4

To retrieve the file from CloudLayer Storage, use the FileID to retrieve it.

# curl -u user@example.com:PaSsWoRd \
https://storage.cloudlayer.com/v1/files/37D0F2AC-08FC-11DE-1234-3FA3A91CD1B4/ -o outputfilename

Alternatively, you could use “wget” to retrieve the file

# wget –http-user=user@example.com -–http-password=PaSsWoRd \
https://storage.cloudlayer.com/v1/files/37D0F2AC-08FC-11DE-1234-3FA3A91CD1B4/ -O outputfilename

To delete a file just add the POST form variable “action” with the value “delete”.

# curl –d 'action=delete' –u user@example.com:PaSsWoRd \
https://storage.cloudlayer.com/v1/files/37D0F2AC-08FC-11DE-1234-3FA3A91CD1B4/

Each of the commands listed above return data in XML format. If you would prefer json format, add a query parameter “output=json” to the query string.

# curl –u user@example.com:PaSsWoRd \
https://storage.cloudlayer.com/v1/files/list?output=json

In order to create a public URL for a file, just send a POST variable of “action=create” to the “token” endpoint.

# curl -d 'action=create' -u user@example.com:PaSsWoRd \
https://storage.cloudlayer.com/v1/files/37D0F2AC-08FC-11DE-1234-3FA3A91CD1B4/token/

The long string “37D0F2…” is the oid (a.k.a FileID) of the file that you can get from the XML returned when the file was uploaded, or retrived using the file listing example above.

In the XML (or JSON) data that is returned, there will be a “token”.

<token>B2891F7B054EF2DF764801E1CFF0079057291234</token>

That token can be combined with the oid to create a URL that anyone can use to retrieve the file.

The URL looks like this:
https://storage.cloudlayer.com/v1/public/{oid}/{token}

In our example it would be:
https://storage.cloudlayer.com/v1/public/37D0F2AC-08FC-11DE-1234-3FA3A91CD1B4/B2891F7B054EF2DF764801E1CFF0079057291234

If you are accessing CloudLayer Storage from inside a SoftLayer datacenter, you can access the storage over the SoftLayer private network (no bandwidth fees!). Just use “scs.service.softlayer.com” instead of “storage.cloudlayer.com”.

You can use the information above in conjunction with the curl libraries in PHP, C++, or one of many other programming languages with curl bindings.

1 comment

The start of something good

I’ve been working with quite a few PHP users on our forums over the past few months. One thing I love is the sheer variety of tasks you guys are accomplishing. One thing I don’t really love is how y’all use the sample code we provided when we launched our new API last year. Our examples work great for API v1 to API v3 migrations, but those simple functions don’t really do our current API justice.

To that end I’ve written a new PHP API client. This small library will let you take real advantage of the features our API has to offer (like object masks, result limits, proper exception catching, and the like) in both SOAP and XML-RPC. Please download it from our new presence on the github social code hosting site. Come check us out at:

http://github.com/softlayer/

Right now all that’s up there is our PHP API client. We’ll put more client libraries and projects up as we make them. We’ve got a a few in the works right now. If you’ve already got a github account come find us! We love to meet those who want to use and modify our work. If you have a favorite language that you want to see a client library for please let us know and we’ll see what we can do. The next language on my hit list is Python 2.6. See y’all next time!

No comments

Dot Net? You Bet!

Greetings fellow SLAPI enthusiasts! When the call went out for examples I figured why not cowboy up and try my hand at with a .NET example. After all, being an MCP in a largely PHP shop makes me as qualified as anyone. Plus I am constantly pushing the Microsoft Kool-Aid around the office so this was a chance to put my money where my mouth is.

Unfortunately, there was just one catch—I’m not a .NET programmer. I’ve got 10 years of experience writing drivers, protocol suites, and firmware. In other words, C/C++ with a little bit of assembler thrown in when push comes to shove. Sure I can write a c-sharp application, but I’m pretty green at it and until a month ago if someone had told me they had a problem with their WSDL (pronounced wiz’duhl) I would have wondered why they were telling me instead of their urologist!

That said, what follows is a pretty basic SLAPI example, done in both C# and VB.NET (because I’m ambi-dot-dextrous). Don’t expect anything more than a DOS-style command console for the UI. I’m used to letting the Microsoft’s control panel give the user any feedback and usually consider my code to be ready to ship if it can run for 24 hours without blue-screening the box!

My chops are on display at the SLDN API Wiki. Let me know what you think!

No comments

Perls of Wisdom

It’s been a little over a week since our API launch. I haven’t heard from anyone who doesn’t like it, so that must mean we’re doing it right. We’ve been spending time lately catching up on little quirks and documentation bugs. Our first example is up. Its for you Perl jockeys, and really exemplifies the flexibility and power of object masks in your API handling code. We’ve got a .NET one coming up soon. You guys are going to love how easy it is to use this in Visual Studio. We’ve got plans for PHP and Java coming up too. If there’s a language or implementation you want to see please let us know!

In other news, SoftLayer has recently launched a shiny new Facebook group. Sign in and join up to talk with us and get your hands-on exclusive content (which currently is videos of me rambling about the API). As always, we’re here if you have questions, concerns, or just want to chat. See you next time!

No comments

Time for some morning Java

(This post refers to SoftLayer API version 1. Check out API version 3 for our latest updates.)

We’ve put a Java SOAP example up on our downloads page. This was written in Eclipse 3.2.2, and for your convenience the example package contains our Eclipse project files. The code should run on JVM version 1.4 and above. We’d love to hear your feedback on this example. Reply here or post on our forums and let us know what you think. See ya’ll later!

No comments

API Hacking Fun With Python

(This post refers to SoftLayer API version 1. Check out API version 3 for our latest updates.)

Hello! I’m Shawn, one of new “Code Writing Professionals” at SoftLayer. When a call went out for examples using SoftLayer’s new API, I immediately signed up to write the INTERCAL, Prolog, and Apollo Guidance Computer modules. I was told to make those low priority projects, and to perhaps focus on hacking with Python instead. If you just want to see the finished code without all the Python evangelization, skip to the end of the post. For those of you who haven’t hacked with Python yet, follow along for the ride!

In case you don’t know, Python is an incredibly simple and clean looking programming language. Many people have picked it up in just a few minutes! If you already program in another programming language (like C, Java, PHP, SH, or Perl (shiver)), Python may look a bit strange. But it’s not too strange at all. In fact, the only “strange” bits in Python are it’s reliance on whitespace (you have to line up your code) and the lack of braces.

Any good FORTRAN coder will tell you that whitespace is good.

If you run a flavor of UNIX, Linux, or BSD, you most likely have Python already installed. If you are running Windows or if your distribution doesn’t come with a recent Python package installed you will need to install Python. You Linux guys can install it with your favorite package manager (it’s usually named python). Windows users (or UNIX haxxors who prefer tarballs), pick up the latest version of Python from ActiveState. (You will also want to check out ActiveState’s free(!) Komodo Edit)

Install Python and we are ready to go!

Open up a UNIX Terminal or the Windows command line (Start->Run… type CMD {enter}), then type “python”. This boots up the Interactive Python Interpreter. One of the cool things about Python is that you can whip up a Python Interpreter and just start typing in program fragments. It’s like the “immediate” mode in QBASIC for DOS, but neater. You should see something like this:
 

 
The first step is to import the XML-RPC library for Python. In keeping with Python’s “Batteries Included” approach, the most useful libraries come standard with any complete download of the Python interpreter, and this includes the standard XML-RPC library. To do this, type:
 

import xmlrpclib

 
Now Python has all the functionality needed to make and receive XML-RPC calls loaded into the interpreter. Let’s set up some variables to make hacking with the library much easier. In the interpreter, type:
 

url = "http://api.service.softlayer.com/xmlrpc/v1/SL-Service.html"
key = "YOUR SOFTLAYER API KEY"
usr = "YOUR SOFTLAYER API USERNAME"

 
Now we need to set up a Server Proxy. This is an object that we can make method calls against that does all the dirty work of compiling the XML and parsing the data… all the boring stuff. Using the proxy we get to make XML-RPC calls as if all the work was being done on the local machine. This is easy to do. Type this into the interpreter:
 

server = xmlrpclib.ServerProxy(url)

 
Now you have your proxy. If you print out the server variable (print server) you will see that server is an instance of the ServerProxy class made to communicate with the SoftLayer XML-RPC server. Now, let’s actually do something!
 

serverList = server.getServerList(key, usr)

 
This invokes the XML-RPC getServerList method, which retrieves your list of servers and stashes it into serverList. Let’s see what you got:
 

print serverList

 
The data is returned as a LIST of DICTIONARIES, with one DICTIONARY per server. Let’s loop through this list and display the servername of all your servers:
 

for thisServer in serverList:
  print thisServer["SERVERNAME"]

 
The two space indentation at the beginning of the second line are required or else the code won’t work. Hit enter twice, and Python will print out the Servername (hostname + domain name) for all servers in your account. You can pull more data out of the dictionary easily:
 

for thisServer in serverList:
  print thisServer["SERVERNAME"], thisServer["PUBLIC_IP_ADDRESS"]

 
You can make all the method calls listed in the SoftLayer API Documentation by calling them as methods of the server class:
 

server.getBandwidthList(key, usr, "192.168.1.1")
server.getServerNetworkDetails(key, usr, "192.168.1.1")
server.rebootServer(key, usr, "192.168.1.1", "Soft Reboot")

 
Python is easy to pick up and play with, and with it’s XML-RPC library, it’s probably the fastest way for people to hack with the SoftLayer API. The complete code listing to display all your servernames is below:
 

# Quickie Python XML-RPC Demo for the SoftLayer API
# Written by Shawn Boles, SoftLayer Development

# API Connection Details
url = "http://api.service.softlayer.com/xmlrpc/v1/SL-Service.html"
key = "PUT YOUR SOFTLAYER API KEY HERE..."
usr = "PUT YOUR API USERNAME HERE..."

# This is the XML-RPC Library for Python.  It comes standard!
import xmlrpclib

# Set up the proxy object for the SoftLayer server.  You can make
# calls against this object as if the processing is local.
server = xmlrpclib.ServerProxy(url)

# Make a method call on getServerList from the API.
# Don't forget to pass the key and usr variables as the first
# two parameters, in that order!
serverList = server.getServerList(key, usr)

# Loop through all servers, displaying their servernames.
for myserver in serverList:
    print myserver["SERVERNAME"]

 
Only 8 lines of code, ignoring comments and empty lines. Hacking indeed! When a new API method comes out you can pop open a command line and slap together a test case in a minute or two to try it out!

Extra Credit: Let’s do something a little more useful with our new |33+ Python API Hacking Skilz:
 

# Display all my servers and IP addresses, using the SoftLayer API
# Written by Shawn Boles, SoftLayer Development

# API Connection Details
url = "http://api.service.softlayer.com/xmlrpc/v1/SL-Service.html"
key = "PUT YOUR SOFTLAYER API KEY HERE..."
usr = "PUT YOUR API USERNAME HERE..."

# This is the XML-RPC Library for Python.  It comes standard!
import xmlrpclib

# Set up the proxy object for the SoftLayer server.  You can make
# calls against this object as if the processing is local.
server = xmlrpclib.ServerProxy(url)

# Make a method call on getServerList from the API.
# Don't forget to pass the key and usr variables as the first
# two parameters, in that order!
serverList = server.getServerList(key, usr)

# Loop through all servers, displaying their servernames.
for myserver in serverList:
    # Get the list of Server Details from the API for each server:
    serverDetail = server.getServerDetails(key, usr, myserver["ID"])

    # "Unfold" the Server Details data structure and give us access
    # to only the IP information...
    prettyServerDetail = serverDetail[2][0]

    try:
        print myserver["SERVERNAME"], \
            "\n\tPublic IP:", prettyServerDetail["PRIMARY_PUBLIC_IP"], \
            "(", prettyServerDetail["PUBLIC_PORT_SPEED"], "),", \
            "\n\tPrivate IP:", prettyServerDetail["PRIMARY_PRIVATE_IP"], \
            "(", prettyServerDetail["PRIVATE_PORT_SPEED"], "),", \
            "\n\tManage IP:", prettyServerDetail["MGMT_IP"], "\n"
    except KeyError:
        print "NONE\n"
        pass

 
Here’s a direct link to the sample file for your editing pleasure.

In no time at all you will be hacking apps for your API no sweat! And you aren’t locked down to command line tools, either. Python comes with just about every GUI kit, can be used to make your own Python-powered control panel…

Have fun hacking!

No comments

Let’s get this party started.

(This post refers to SoftLayer API version 1. Check out API version 3 for our latest updates.)

Howdy, everyone. The SoftLayer dev team has been growing a bit lately to handle new portal additions and adding fancy new methods to the API for ya’ll. So far we’ve gotten some great feedback on the API and how to make our application servers work better for you and your businesses. Now that we’ve got the API out and some extra head count what say we kick into high gear?

Here’s our game plan. We know how smart our customers are. We know how they think (we hope). They’re geeks who find perverse joy in taking things apart, reassembling them, and building cool new toys out of the leftover parts. We want you to give that a try with our API. Our Implementations Forum has a good start, but we’re looking for something to really knock our socks off. So far the coolest thing we’ve seen is a Yahoo! widget. Who can top that?

Email us, post to the forum, or leave a comment here with sweet implementation goodness. Surprise us. Show us what wacky stuff you can do with your server and our API. If you don’t code then that’s fine. Send us your ideas. Maybe someone will pick up on it. To get the ball rolling we’ll write an app or two of our own. Even better we’ll release the source of our app to get ya’ll started. Let’s see what kind of cool programs we can write.

2 comments

Show off your project

Everyone at SoftLayer is excited about the API. But we can’t wait to see what our customers are going to be doing with it. You can go to the implementations page to see some examples of ways to use the API. What we would really like to put on that page is a list of applications developed by our customers. If you create a use for the API that is new and unique, or if you just want to show the world how cool you are – send us an email at sldn@softlayer.com and tell us about it and we will feature your project on the implementation page.

No comments

Next Page »