Thursday 15 January 2015

Ruby SDK for CaaS

Getting started with Dimension Data Cloud SDK (Ruby)


In addition to the .NET client library, a Ruby alternative has also been developed. It can be used to automate various tasks, such as setting up and tearing down different environments on the cloud platform.
The SDK is available as a ruby gem. The code itself can be found on github. In this post, we’ll set up an Ubuntu server and connect it to the internet so we can reach it via ssh.
Before we can start, we need to have both ruby and the SDK on our system. If you still need to install ruby, you can find instructions here. Installing the SDK itself is easy via gem:
user@localhost:~$ gem install didata_cloud_sdk
Fetching: didata_cloud_sdk-0.3.2.gem (100%)
Successfully installed didata_cloud_sdk-0.3.2
Parsing documentation for didata_cloud_sdk-0.3.2
Installing ri documentation for didata_cloud_sdk-0.3.2
Done installing documentation for didata_cloud_sdk after 0 seconds
1 gem installed

Now that the SDK is installed, we can start building our environment. You’ll see that it’s quite straightforward, we can even do it right in the console. Let’s fire up irb (the interactive ruby shell) :
user@localhost:~$ irb
2.0.0-p247 :001 > require "ddcloud"
 => true
2.0.0-p247 :002 > user = "username"
 => "username"
2.0.0-p247 :003 > pass = "password"
 => "password"
2.0.0-p247 :004 > url = "https://api-eu.dimensiondata.com/oec/0.9"
 => "https://api-eu.dimensiondata.com/oec/0.9"
2.0.0-p247 :005 > org_id = "xxxxxxxxxx"
 => "xxxxxxxxxx"
We first load the SDK in the session and define a couple of variables which hold our login information. I’m logging in via the European portal, so my url starts with « api-eu ».  Different possibilities are :
·        North America : api-na
·        Australia : api-au
·        Africa : api-mea
·        Asia Pacific : api-ap
The org_id is a unique string which specifies your organization. You’ll find it at the top of your account page in the cloud web portal.
With this information, we can create a client to communicate with the cloud API:
2.0.0-p247 :006 > c = DDcloud::Client.new url, org_id, user, pass
 => #<DDcloud::Client:0x00000002afe068 @api_base="https://api-eu.dimensiondata.com/oec/0.9", @org_id="xxxxxxxxxxx", @username="username", @password="password", @datacenter="EU1", @default_password="verysecurepassword", @colors=true, @silent=false>
The client itself is not yet connected to the API, but will use the credentials you provided to execute requests on your behalf.
To create a new machine and connect it to the internet, we need to complete 3 steps:
1)      Create a network
2)      Create and start the cloud server
3)      Connect it to the internet
We’ll go right ahead and create a network:
2.0.0-p247 :007 > c.network.create "EU-test-network", "This is a test network"
=> #<Hashie::Mash operation="Add Network" result="SUCCESS" result_code="REASON_0" result_detail="Network created successfully (Network ID: 58dce2ee-d18f-11e1-b508-180373fb6591)">
2.0.0-p247 :008 > c.network.show_by_name "EU-test-network"
=> #<Hashie::Mash description="This is a test network" id="58dce2ee-d18f-11e1-b508-180373fb6591" location="EU1" multicast="false" name="EU-test-network" private_net="10.240.215.0">
When creating a network, we need to specify a name and optionally a description. The network is created before the function returns, so the request can take some time. You can check the status of the network by calling the « show_by_name » method.
We’ll now create the cloud server and place it in the network. We again need to provide a name and a description, as well as a network id and an image id. The network id can be extracted from the « show_by_name » call. The image id specifies which operating system is preinstalled on your new cloud server. Dimension Data provides a rather large list of operating systems which you can find in the cloud portal. In this case, we’re interested in an Ubuntu server. The id for this image is: d4ed6d40-e2f0-11e2-84e5-180373fb68df
Putting this all together:
2.0.0-p247 :009 > network = c.network.show_by_name "EU-test-network"
=> #<Hashie::Mash description="This is a test network" id="58dce2ee-d18f-11e1-b508-180373fb6591" location="EU1" multicast="false" name="EU-test-network" private_net="10.240.215.0">
2.0.0-p247 :010 > network_id = network[:id]
 => "58dce2ee-d18f-11e1-b508-180373fb6591"
2.0.0-p247 :011 > image_id = "d4ed6d40-e2f0-11e2-84e5-180373fb68df"
 => "d4ed6d40-e2f0-11e2-84e5-180373fb68df"
2.0.0-p247 :012 > c.server.create "testserver", "this is a testserver", network_id, image_id
=> #<Hashie::Mash operation="Deploy Server" result="SUCCESS" result_code="REASON_0" result_detail="Server \"Deploy\" issued">

The server creation is not instantaneous, we can follow along as follows:
2.0.0-p247 :021 > require "pp"
2.0.0-p247 :022 > pp c.server.show_by_name("testserver")
{"id"=>"41c17cab-e331-4ac4-9732-91ac65b5c8c9",
 "location"=>"EU1",
 "name"=>"testserver",
 "description"=>"this is a testserver",
 "operating_system"=>
  {"id"=>"UBUNTU1264", "display_name"=>"UBUNTU12/64", "type"=>"UNIX"},
 "cpu_count"=>"2",
 "memory_mb"=>"4096",
 "disk"=>
  {"id"=>"db05fa4e-8876-4df6-a55b-7cad16557083",
   "scsi_id"=>"0",
   "size_gb"=>"10",
   "speed"=>"STANDARD",
   "state"=>"NORMAL"},
 "source_image_id"=>"d4ed6d40-e2f0-11e2-84e5-180373fb68df",
 "network_id"=>"58dce2ee-d18f-11e1-b508-180373fb6591",
 "machine_name"=>"10-240-215-11",
 "private_ip"=>"10.240.215.11",
 "created"=>"2014-12-04T13:58:21.000Z",
 "is_deployed"=>"false",
 "is_started"=>"true",
 "state"=>"PENDING_ADD",
 "status"=>
  {"action"=>"DEPLOY_SERVER",
   "request_time"=>"2014-12-04T13:58:21.000Z",
   "user_name"=>"username",
   "number_of_steps"=>"13",
   "update_time"=>"2014-12-04T14:03:00.000Z",
   "step"=>{"name"=>"WAIT_FOR_GUEST_OS_CUSTOMIZATION", "number"=>"10"}}}
The server is correctly deployed and started when both the « is_deployed » and « is_started » variables are true.
Finally, we need to connect the network to the internet and open port 22 to allow ssh access. For this, we’ll have to create an aclrule (to open port 22) and create a natrule (to map our internal address to an external ip). Let’s go:
2.0.0-p247 :025 >   c.network.natrule_create network_id, "map_testserver", "10.240.215.11"
=> #<Hashie::Mash id="038d6d6e-d4d0-4245-a1fc-7f60c39acf57" name="map_testserver" nat_ip="164.177.187.50" source_ip="10.240.215.11">
We have to provide the network id, give the rule a name and provide the internal ip of our server. In this case, we extracted the ip from the server « show_by_name » method. Notice that the API returns the public ip in the « nat_ip » variable. Let’s note this ip, we’ll need it to access our server later.
Creating the aclrule is a bit more involved :
2.0.0-p247 :027 > c.network.aclrule_create network_id, "port-22-allow", 105, true, "tcp", "22", true
=> #<Hashie::Mash action="PERMIT" destination_ip_range=#<Hashie::Mash> id="bb40e393-02ef-4a1f-bff4-98de7cba6f67" name="port-22-allow" port_range=#<Hashie::Mash port1="22" type="EQUAL_TO"> position="105" protocol="TCP" source_ip_range=#<Hashie::Mash> status="NORMAL" type="OUTSIDE_ACL">
We again provide the network id and a name. We also have to provide a position (105, which in this case will be the last rule before « drop any any »). The next argument specifies that the rule is inbound. We also specify the protocol (tcp) and the port (22). Finally, we specify that the rule is an « Allow » rule (true).
Our cloud server is now available on the public ip we noted before. Let’s try to access it via ssh. By default, the password is « verysecurepassword », which is actually not that secure. It is recommended to change this as soon as possible .
user@localhost:~$ ssh root@164.177.187.50
The authenticity of host '164.177.187.50 (164.177.187.50)' can't be established.
ECDSA key fingerprint is db:e6:c9:32:1d:99:6c:f0:23:ed:a3:cb:d7:11:ee:ea.
Are you sure you want to continue connecting (yes/no)? yes
Warning: Permanently added '164.177.187.50' (ECDSA) to the list of known hosts.
root@164.177.187.50's password:
Welcome to Ubuntu 12.04.2 LTS (GNU/Linux 3.2.0-23-generic x86_64)

 * Documentation:  https://help.ubuntu.com/

  System information as of Thu Dec  4 15:23:22 CET 2014

  System load:  0.0               Processes:           77
  Usage of /:   17.2% of 8.02GB   Users logged in:     0
  Memory usage: 1%                IP address for eth0: 10.240.215.11
  Swap usage:   0%

  Graph this data and manage this system at https://landscape.canonical.com/

root@10-240-215-11:~#

There you have it, you’ve installed your first cloud server via the API!

No comments:

Post a Comment