tutorial

The following tutorial is not particularly practical in nature, other than the fact that it’s practical practice. Just a heads up.

Here, we’ll open up a python interpreter and begin a step-by-step tutorial. This will also verify that the RSCloud install is functioning properly. The first time you attempt to create an object within RSCloud, you will be prompted for your rackspace cloud account credentials. You will see this happen in the demonstration below. The RSCloud binding for the Cloud Databases API, whose module goes by the name CloudDB, is used during this tutorial. The hope is that the user will be able to apply the concepts learned in this walkthrough to the other modules, and also be able to refer back to this section as a comprehensive example. If you think a different binding class should have been used for this walkthrough, I’m sorry. Reading through this should enable you to interact with any of the other modules/bindings.

In order to run any calls on the API, you will need a class instance corresponding to the product API you want to leverage. For instance, if you want to create/manipulate a Rackspace Cloud Database, you will need to create a CloudDB object. Let’s do that real quick.:

>>> import rscloud
>>>
>>> cDB = rscloud.CloudDB('us','dfw')
US Username: your_cloud_account_username
Return to enter api key instead
US Password:
>>>

Note

Keep in mind a couple things: Since this is python, you could also do:

>>> from rscloud import *

in order to circumvent the need to prefix calls with ‘rscloud’. The naming convention and syntax for all services and their methods is fairly consistent as well.

I passed two strings to create my CloudDB object. Those two string arguments are environment (env) and region (region), which correspond to the location of a datacenter. These two arguments will be required in order to create any of the following RSCloud objects (link to list of objects).

  • available environments

    • ‘us’ ; available region(s)
      • ‘dfw’
      • ‘ord’
    • ‘uk’; available region(s)
      • ‘lon’

The resulting signature will always look like

Cloudthing ( env, region )

and returns an object whose methods enable you to manipulate your cloud. The CloudDB object I created (cDB) will perform actions at the (‘us’ , ‘dfw’) datacenter, as per the arguments I enlisted.

Note

Creating a CloudDB object (or any other RSCloud object for that matter) will not create a Cloud Database, nor any instance of any cloud item; however, we can use the CloudDB object to run one of its methods, createDatabase(), to... you guessed it – create a database.

I’ll use my CloudDB object (cDB) to do this. But first, I’ll need a MySQL instance to allocate databases to, which will be accomplished with CloudDB’s createInstance() method, and follow it up with the database creation, where I’ll indicate which instance (the one I will have just created) will contain it. Creating a MySQL instance via createInstance() will require flavor (id), size (in gigabytes) and name arguments. Instead of writing out a list of currently available flavors, let’s use one of our object’s methods, getFlavor(), to return a list of available flavors to choose from.

>>> cDB.getFlavor()

{'flavors': [{'ram': 512, 'id': 1, 'links': [{'href': 'https://dfw.databases.api.rackspacecloud.com/v1.0/730413/flavors/1', 'rel': 'self'}, {'href': 'https://dfw.databases.api.rackspacecloud.com/flavors/1', 'rel': 'bookmark'}], 'name': 'm1.tiny'}, {'ram': 1024, 'id': 2, 'links': [{'href': 'https://dfw.databases.api.rackspacecloud.com/v1.0/730413/flavors/2', 'rel': 'self'}, {'href': 'https://dfw.databases.api.rackspacecloud.com/flavors/2', 'rel': 'bookmark'}], 'name': 'm1.small'}, {'ram': 2048, 'id': 3, 'links': [{'href': 'https://dfw.databases.api.rackspacecloud.com/v1.0/730413/flavors/3', 'rel': 'self'}, {'href': 'https://dfw.databases.api.rackspacecloud.com/flavors/3', 'rel': 'bookmark'}], 'name': 'm1.medium'}, {'ram': 4096, 'id': 4, 'links': [{'href': 'https://dfw.databases.api.rackspacecloud.com/v1.0/730413/flavors/4', 'rel': 'self'}, {'href': 'https://dfw.databases.api.rackspacecloud.com/flavors/4', 'rel': 'bookmark'}], 'name': 'm1.large'}]}

Most of the methods in RSCloud will return something that looks similar to this. It is a dictionary (python data type) of lists. You can access members of this dict of lists just like you would a standard list. The difference is that the indices of the dictionary will be strings, while the indices of the lists will be integers. (See below for how this works out.) A quick look at this might be beneficial if you’re not familiar with python dicts. While we could certainly search through this dict of lists here to find the flavor ID and RAM we want, let’s massage this a bit to make deciphering easier.

>>> cDB.getFlavor()['flavors'][0]['id']
1
>>> cDB.getFlavor()['flavors'][0]['ram']
512
>>>
>>> for flavorflavs in cDB.getFlavor()['flavors']:
...   print "id: " + str(flavorflavs['id']) + " ; RAM: " + str(flavorflavs['ram'])
...
id: 1 ; RAM: 512
id: 2 ; RAM: 1024
id: 3 ; RAM: 2048
id: 4 ; RAM: 4096
>>>

I want a gig of RAM for my instance, so when I do createInstance(), I’ll put ‘2’ in for the flavor argument. From here we see that there is a 50GB limit on size, and I need a 5GB volume, so I’ll put ‘5’ for the size argument. Finally, I’ll choose a name for my CloudDB instance: ‘flotSam’. For a method signature that looks like createInstance( flavor, size, name ), it goes:

>>> cDB.createInstance('2','5','flotSam')
{'instance': {'status': 'BUILD', 'updated': '2013-02-04T23:30:58', 'name': 'flotSam', 'links': [{'href': 'https://dfw.databases.api.rackspacecloud.com/v1.0/730413/instances/87e4589f-db06-44fb-9d4b-b108ad808a36', 'rel': 'self'}, {'href': 'https://dfw.databases.api.rackspacecloud.com/instances/87e4589f-db06-44fb-9d4b-b108ad808a36', 'rel': 'bookmark'}], 'created': '2013-02-04T23:30:58', 'hostname': '7c24ea08cda2d73a51061bc0fde8373fd42316ac.rackspaceclouddb.com', 'volume': {'size': 5}, 'flavor': {'id': '2', 'links': [{'href': 'https://dfw.databases.api.rackspacecloud.com/v1.0/730413/flavors/2', 'rel': 'self'}, {'href': 'https://dfw.databases.api.rackspacecloud.com/flavors/2', 'rel': 'bookmark'}]}, 'id': '87e4589f-db06-44fb-9d4b-b108ad808a36'}}
>>>

The first thing to note in this returned block of text is the ‘status’: ‘BUILD’. We’ll refer to this call as asynchronous, since the CloudDB instance will continue building without holding things up on our end. After some time passes, I’ll check the status on my CloudDB instance with the getInstance method to see if it has finished building. I’ll pass getInstance the instance ID I want details on. Since I want to see if ‘flotSam’ has finished building, I swipe its 32 character instance ID from above. If I passed no arguments, it would return details for all of my account’s CloudDB instances.

Note

If you are following along in a python interpreter, it might be wise to store that instance id as a variable. You will need to pass it as an argument to run many other CloudDB methods. To keep this guide as concrete as possible, I’m not going to do that. But if I did, I’d do something like:

>>> flotSamId = '87e4589f-db06-44fb-9d4b-b108ad808a36'
>>>

Now, to check status:

>>> cDB.getInstance('87e4589f-db06-44fb-9d4b-b108ad808a36')
{'instance': {'status': 'ACTIVE', 'updated': '2013-02-04T23:33:04', 'name': 'flotSam', 'links': [{'href': 'https://dfw.databases.api.rackspacecloud.com/v1.0/730413/instances/87e4589f-db06-44fb-9d4b-b108ad808a36', 'rel': 'self'}, {'href': 'https://dfw.databases.api.rackspacecloud.com/instances/87e4589f-db06-44fb-9d4b-b108ad808a36', 'rel': 'bookmark'}], 'created': '2013-02-04T23:30:58', 'hostname': '7c24ea08cda2d73a51061bc0fde8373fd42316ac.rackspaceclouddb.com', 'volume': {'used': 0.243377685546875, 'size': 5}, 'flavor': {'id': '2', 'links': [{'href': 'https://dfw.databases.api.rackspacecloud.com/v1.0/730413/flavors/2', 'rel': 'self'}, {'href': 'https://dfw.databases.api.rackspacecloud.com/flavors/2', 'rel': 'bookmark'}]}, 'id': '87e4589f-db06-44fb-9d4b-b108ad808a36'}}
>>>

Again accessing the element we’re looking for...

>>> cDB.getInstance('87e4589f-db06-44fb-9d4b-b108ad808a36')['instance']['status']
'ACTIVE'
>>>

Now that I have an ‘ACTIVE’ CloudDB instance to put databases in, I’ll run createDatabase(). I’ll create a database with the name ‘jetSam’ on CloudDB instance ‘flotSam’. flotSam’s instance id is the one I swiped from above: ‘87e4589f-db06-44fb-9d4b-b108ad808a36’.

>>> cDB.createDatabase('87e4589f-db06-44fb-9d4b-b108ad808a36','jetSam')
202
>>>

A 202 status code response means the request has been accepted. Now I’ll run getDatabases(), just for kicks. This method will return a list of the databases within a specific instance. Again, we’ll use flotSam’s instance id. This will verify that my database is in the instance I assigned it to:

>>> cDB.getDatabases('87e4589f-db06-44fb-9d4b-b108ad808a36')
{'databases': [{'name': 'jetSam'}]}
>>>

Everything checks out. For the sake of making this guide exhaustive, I’ll continue through all methods in the CloudDB class. Assume I’ve changed my mind, and I want to double the size of my instance, flotSam, to 10GB of memory, but reduce its allotted RAM to 512MB, which corresponds to a flavor id of “1”. Recall, I initialized it with 5GB of memory and 1024 MB of RAM. Using CloudDB’s setAction(), I can modify my CloudDB instance and accomplish this. The signature of this method looks like

setAction( instance id , reboot , flavor id , [re] size )

The reboot, flavor id, and size arguments all default to False; two of which must remain False for the method to pass. In other words, setAction() can set only one “action” per call. Beware of this limitation when using other methods as well. First, I’ll use flotSam’s instance id and change my flavor id to “1”, while in the second setAction() call, size will go up to the 10GB, so ‘10’ as the 4th argument. Afterward, I’ll getInstance() to verify the changes.:

>>> cDB.setAction('87e4589f-db06-44fb-9d4b-b108ad808a36', flavor='1')
202
>>> cDB.setAction('87e4589f-db06-44fb-9d4b-b108ad808a36', volume='10')
>>> cDB.getInstance('87e4589f-db06-44fb-9d4b-b108ad808a36')['instance']['status']
>>> 'RESIZE'
>>> flotSam = cDB.getInstance('87e4589f-db06-44fb-9d4b-b108ad808a36')['instance']
>>> flotSam['volume']['size']
10
>>> flotSam['flavor']['id']
'1'
>>>

Looks good. If you’ve made it this far, you’ve probably got the hang of it by now. There are a few more methods to finish up the CloudDB class, createUser(), getUsers() and the delete methods. I’ll go in that order.

You probably want to create a user for your database. I know I do. The method signature looks like this

createUser( instance id, name, password, databases )

I’ll create the user ‘Dustin’, with the password ‘DPASS’, on the ‘flotSam’ instance, ‘jetSam’ database, and then verify the changes by looking at info through getUsers(). The databases argument will follow the list/dict format:

[ { ‘name’ : ’ yourddatabasename ’ } ]:

>>> cDB.createUser('87e4589f-db06-44fb-9d4b-b108ad808a36','Dustin','DPASS', databases=[{'name':'jetSam'}])
202
>>> cDB.getUsers('87e4589f-db06-44fb-9d4b-b108ad808a36')
{'users': [{'name': 'Dustin', 'databases': [{'name': 'jetSam'}]}]}
>>>

Clean up time.

>>> cDB.deleteUser('87e4589f-db06-44fb-9d4b-b108ad808a36','Dustin')
202
>>> cDB.deleteDatabase('87e4589f-db06-44fb-9d4b-b108ad808a36', 'jetSam')
202
>>> cDB.deleteInstance('87e4589f-db06-44fb-9d4b-b108ad808a36')
202
>>>

Back to where we started, but we sure learned a lot. Happy provisioning!

Previous topic

intro

Next topic

rscloud package modules