From: marios <[email protected]>

---
 .../drivers/terremark/terremark_driver.rb          |  271 ++++++++++++++++++++
 server/lib/drivers.rb                              |    1 +
 2 files changed, 272 insertions(+), 0 deletions(-)
 create mode 100644 server/lib/deltacloud/drivers/terremark/terremark_driver.rb

diff --git a/server/lib/deltacloud/drivers/terremark/terremark_driver.rb 
b/server/lib/deltacloud/drivers/terremark/terremark_driver.rb
new file mode 100644
index 0000000..b7ff9bd
--- /dev/null
+++ b/server/lib/deltacloud/drivers/terremark/terremark_driver.rb
@@ -0,0 +1,271 @@
+# Copyright (C) 2010  Red Hat, Inc.
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  
USA
+#
+# This driver uses the fog library (Geemus - Wesley Beary) to talk to 
terremark... see 
+#                                   http://github.com/geemus/fog
+# see terremark vcloud express api at: 
+# 
https://community.vcloudexpress.terremark.com/en-us/product_docs/w/wiki/d-complete-vcloud-express-api-document.aspx
+#
+# 02 May 2010
+#
+require 'deltacloud/base_driver'
+path = File.dirname(__FILE__)
+$: << path
+begin
+  require 'fog'
+  require 'excon'
+  require 'nokogiri'
+rescue LoadError
+  puts "ERROR: please ensure fog, excon and nokogiri gems installed. ('gem 
install fog', 'gem install excon' , 'gem install nokogiri')"
+  exit(1)
+end
+
+module Deltacloud
+  module Drivers
+    module Terremark
+      
+class TerremarkDriver < Deltacloud::BaseDriver
+
+#--
+# HARDWARE PROFILES
+#--
+  define_hardware_profile 'default' do
+    cpu   [1,2,4,8]
+    memory  [512, 1024, 2048, 4096, 8192]
+    storage (1..500).to_a
+  end
+  #storage_disks [1..15]
+
+  
+#--
+# IMAGES
+#--
+#aka "vapp_templates"
+  def images(credentials, opts=nil)
+      image_list = []
+      safely do
+        terremark_client = new_client(credentials)
+        vdc_id = terremark_client.default_vdc_id
+        catalogItems = 
terremark_client.get_catalog(vdc_id).body['CatalogItems']
+        catalogItems.each{|catalog_item|
+          current_item_id = catalog_item['href'].split('/').last
+          current_item = 
terremark_client.get_catalog_item(current_item_id).body['Entity']
+            if(current_item['type'] == 
'application/vnd.vmware.vcloud.vAppTemplate+xml')
+              image_list << convert_image(current_item, credentials.user)
+            end
+        } #end of catalogItems.each
+      end #end of safely do
+      image_list = filter_on( image_list, :id, opts )
+      image_list = filter_on( image_list, :architecture, opts )
+      image_list = filter_on( image_list, :owner_id, opts )
+      image_list
+  end
+  
+#--
+# REALMS
+#--
+#only one realm... everything in US?
+  def realms(credentials, opts=nil)
+     [Realm.new( {
+      :id=>"US-Miami",
+      :name=>"United States - Miami",
+      :state=> "AVAILABLE"
+    } )]
+  end
+    
+#--
+# INSTANCES
+#--
+#aka vApps
+  def instances(credentials, opts=nil)
+      instances = []
+      safely do
+        terremark_client = new_client(credentials)
+        vdc_items = 
terremark_client.get_vdc(terremark_client.default_vdc_id()).body['ResourceEntities']
+        vdc_items.each{|current_item|
+          if(current_item['type'] == 'application/vnd.vmware.vcloud.vApp+xml') 
+             vapp_id =  current_item['href'].split('/').last
+             vapp = terremark_client.get_vapp(vapp_id)
+            instances  << convert_instance(vapp, terremark_client, 
credentials.user)
+          end
+        }#end vdc_items.each
+      end #end safely do 
+      instances = filter_on( instances, :id, opts )
+      instances
+  end
+
+#--
+# FINITE STATE MACHINE
+#--
+#by default new instance --> powered_off
+  define_instance_states do 
+    start.to(:pending)            .on( :create )  
+    pending.to(:stopped)          .automatically   
+    stopped.to(:running)          .on( :start )
+    running.to(:running)          .on( :reboot )
+    running.to(:shutting_down)    .on( :stop )
+    shutting_down.to(:stopped)    .automatically
+    stopped.to(:end)              .on( :destroy )
+   end
+
+
+#--
+# CREATE INSTANCE
+#--  
+#launch a vapp template. Needs a name, ram, no. cpus, id of vapp_template
+  def create_instance(credentials, image_id, opts)
+    new_vapp = nil
+    vapp_opts = {} #assemble options to pass to 
Fog::Terremark::Real.instantiate_vapp_template
+    terremark_hwp = hardware_profiles(credentials, {:name => 'default'}).first 
#sanity check values against default
+    name = opts['name'] #name could be nil or length 0 or too long
+    name = "inst#{Time.now.to_i}" if (name.nil? || (name.length == 0))
+    name = name.slice(0..14) #name max 15 chars
+    unless ( (terremark_hwp.include?(:cpu, opts[:hwp_cpu].to_i)) &&
+              (terremark_hwp.include?(:memory, opts[:hwp_memory].to_i)) ) then 
+       raise 
Deltacloud::Validation::Failure.new(Deltacloud::Validation::Param.new(["cpu"]), 
"Error with cpu and/or memory values. you said cpu->#{opts[:hwp_cpu]} and 
mem->#{opts[:hwp_memory]}")
+    end
+    vapp_opts['cpus'] = opts[:hwp_cpu]
+    vapp_opts['memory'] =  opts[:hwp_memory]
+    terremark_client = new_client(credentials)
+    safely do
+#######
+#FIXME#  what happens if there is an issue getting the new vapp id? (eg even 
though created succesfully)
+#######
+      vapp_id = terremark_client.instantiate_vapp_template(name, image_id, 
vapp_opts).body['href'].split('/').last
+      new_vapp = terremark_client.get_vapp(vapp_id)
+      return convert_instance(new_vapp, terremark_client, credentials.user) 
#return an Instance object
+    end
+  end
+
+#--
+# REBOOT INSTANCE
+#--
+  def reboot_instance(credentials, id)
+    safely do
+       terremark_client =  new_client(credentials)
+       terremark_client.reset(id)
+    end
+    #thats it?
+  end
+
+#--
+# START INSTANCE
+#--
+def start_instance(credentials, id)
+    safely do
+       terremark_client =  new_client(credentials) 
+       terremark_client.power_on(id)
+    end
+end
+
+
+#--
+# STOP INSTANCE
+#--
+def stop_instance(credentials, id)
+    safely do
+      terremark_client = new_client(credentials)
+      terremark_client.shutdown(id)
+    end
+end
+  
+#--
+# DESTROY INSTANCE
+#--
+#shuts down... in terremark need to do a futher delete to get rid of a vapp 
entirely
+def destroy_instance(credentials, id)
+   safely do
+     terremark_client = new_client(credentials)
+     terremark_client.delete_vapp(id)   
+   end   
+end
+  
+  
+  private 
+  
+#--
+# CONVERT IMAGE
+#--  
+#gets a vapp_template from a catalog and makes it a Image
+  def convert_image(catalog_vapp_template, account_name)
+    name = catalog_vapp_template['name']
+    #much fudging ensues
+    arch = name.scan(/[36][24].bit/).first
+    arch ||= "n/a"
+    #k enuf o'that now!
+    Image.new( {
+                  :id => catalog_vapp_template['href'].split('/').last,
+                  :name => catalog_vapp_template['name'],
+                  :architecture => arch,
+                  :owner_id => account_name,
+                  :description => catalog_vapp_template['name']
+               })
+  end
+ 
+#--
+# CONVERT INSTANCE
+#--
+  def convert_instance(vapp, terremark_client, account_name)
+      vapp_private_ip = vapp.body['IpAddress'] 
+      vapp_public_ip = 
terremark_client.get_public_ips(terremark_client.default_vdc_id).body['PublicIpAddresses'].first['name']#get_public_address(terremark_client,
 vapp_private_ip)
+      vapp_status = vapp.body['status']
+      current_state = ((vapp_status == "0" || vapp_status == "1")  ? "PENDING" 
: (vapp_status == "2" ? "STOPPED" : "RUNNING" )) #status == 0->BEING_CREATED 
2->OFF 4->ON
+      Instance.new( {
+                    :id => vapp.body['href'].split('/').last,
+                    :owner_id => "#{account_name}",
+                    :image_id => "n/a", #cant get this... see 
https://community.vcloudexpress.terremark.com/en-us/discussion_forums/f/60/t/376.aspx
 
+                    :name => vapp.body['name'],
+                    :realm_id => "US-Miami",
+                    :state => current_state, 
+                    :actions => instance_actions_for(current_state), 
+                    :public_addresses => vapp_public_ip,                       
                             
+                    :private_addresses => vapp_private_ip,
+                    :instance_profile => InstanceProfile.new("default")
+                    } )  
+  end
+  
+#--
+# NEW CLIENT
+#--
+#use supplied credentials to make a new client for talking to terremark
+  def new_client(credentials)
+    #Fog constructor expecting  credentials[:terremark_password] and 
credentials[:terremark_username]
+    terremark_credentials = {:terremark_vcloud_username => 
"#{credentials.user}", :terremark_vcloud_password => "#{credentials.password}" }
+    safely do
+      terremark_client = Fog::Terremark::Vcloud.new(terremark_credentials)
+      vdc_id = terremark_client.default_vdc_id
+      if (vdc_id.nil?)
+         raise DeltaCloud::AuthException.new
+      end
+         return terremark_client
+      end
+  end   
+  
+ def safely(&block)
+    begin
+      block.call
+#    rescue Excon::Errors.status_error => e #this is what you get from the fog 
requests if :expects status code is off
+#        raise Deltacloud::AuthException.new
+    rescue Exception => e
+        puts "ERROR: #{e.message}"
+    end
+ end
+  
+end
+
+    end
+  end
+end
diff --git a/server/lib/drivers.rb b/server/lib/drivers.rb
index 72df672..269fe75 100644
--- a/server/lib/drivers.rb
+++ b/server/lib/drivers.rb
@@ -5,6 +5,7 @@ DRIVERS = {
   :rhevm => { :name => "RHEVM" },
   :rimu => { :name => "Rimu", :class => "RimuHostingDriver"},
   :opennebula => { :name => "Opennebula", :class => "OpennebulaDriver" },
+  :terremark => { :name => "Terremark"},
   :mock => { :name => "Mock" }
 }
 
-- 
1.6.6.1

_______________________________________________
deltacloud-devel mailing list
[email protected]
https://fedorahosted.org/mailman/listinfo/deltacloud-devel

Reply via email to