---
 .../lib/deltacloud/drivers/gogrid/gogrid_driver.rb |  225 ++++++++++++++++++++
 .../lib/deltacloud/drivers/gogrid/gogrid_test.rb   |   73 +++++++
 2 files changed, 298 insertions(+), 0 deletions(-)
 create mode 100644 server/lib/deltacloud/drivers/gogrid/gogrid_driver.rb
 create mode 100644 server/lib/deltacloud/drivers/gogrid/gogrid_test.rb

diff --git a/server/lib/deltacloud/drivers/gogrid/gogrid_driver.rb 
b/server/lib/deltacloud/drivers/gogrid/gogrid_driver.rb
new file mode 100644
index 0000000..1593f79
--- /dev/null
+++ b/server/lib/deltacloud/drivers/gogrid/gogrid_driver.rb
@@ -0,0 +1,225 @@
+#
+# Copyright (C) 2009  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
+
+require 'deltacloud/base_driver'
+require 'right_gogrid'
+
+module Deltacloud
+  module Drivers
+    module Gogrid
+
+class GogridDriver < Deltacloud::BaseDriver
+
+  # Storage capacity is same on all machines (10gb), it could be extended 
using 'Cloud Storage'
+  define_hardware_profile('server-with-512mb-ram') do
+    cpu              2
+    memory         0.5
+    storage        10
+    architecture 'i386'
+  end
+
+  define_hardware_profile('server-with-1gb-ram') do
+    cpu            2
+    memory         1
+    storage        10
+    architecture   'i386'
+  end
+
+  define_hardware_profile('server-with-2gb-ram') do
+    cpu            2
+    memory         2
+    storage        10
+    architecture   'i386'
+  end
+
+  define_hardware_profile('server-with-4gb-ram') do
+    cpu            2
+    memory         4
+    storage        10
+    architecture   'i386'
+  end
+
+  define_hardware_profile('server-with-8gb-ram') do
+    cpu            2
+    memory         8
+    storage        10
+    architecture   'i386'
+  end
+
+  # The only valid option for flavors is server RAM for now
+  def flavors(credentials, opts=nil)
+    results = []
+    safely do
+      gg=new_client(credentials)
+      results = gg.list_common_lookup('server.ram').collect do |sr|
+        Flavor.new(:id => sr['description'].downcase.tr(' ', '-'), :memory => 
sr['name'], :architecture => 'i386')
+      end
+    end
+    return results if ( opts.nil? )
+    results = filter_on( results, :id, opts )
+    results = filter_on( results, :architecture, opts )
+    results
+  end
+
+  def images(credentials, opts=nil)
+    images = []
+    safely do
+      gg=new_client(credentials)
+      images = gg.list_images.collect { |image| convert_image(image, 
credentials[:name]) }
+    end
+    images = filter_on( images, :architecture, opts )
+    images.sort_by{|e| [e.owner_id,e.description]}
+  end
+
+  # gogrid doesn't supports realm yet (it's US/CA from whois)
+  def realms(credentials, opts=nil)
+    [Realm.new({
+      :id => "us",
+      :name => "United States",
+      :state => "AVAILABLE"
+    } )]
+  end
+
+  # Name consist from credentials name and timestamp
+  #
+  def create_instance(credentials, image_id, opts=nil)
+    flavor_id =(opts && opts[:flavor_id]) ? opts[:flavor_id] : 
'server-with-512mb-ram'
+    # TODO: Fix naming here (IDEA: add 'name' to instance model)
+    name = 'Node '+Time.now.to_i.to_s
+    safely do
+      grid = new_client(credentials)
+      flavor = flavors(credentials).select { |f| f.id.eql?(flavor_id) }.first
+      image = images(credentials).select { |i| i.id.eql?(image_id) }.first
+      return convert_srv_to_instance(grid.add_server(name, image.name, 
flavor.memory, get_free_ip(credentials), image.description), flavor_id)
+    end
+  end
+
+  def instances(credentials, opts=nil)
+    safely do
+      gg = new_client(credentials)
+      instances = gg.list_servers.collect { |server| 
convert_srv_to_instance(server, convert_ram_to_flavor(server['ram']['name']))}
+      instances = filter_on( instances, :id, opts )
+      instances = filter_on( instances, :state, opts )
+      return instances
+    end
+  end
+
+  def reboot_instance(credentials, id)
+    safely do
+      gg = new_client(credentials)
+      return gg.gogrid_power_server(:power => 'restart', :name => id)
+    end
+  end
+
+  def stop_instance(credentials, id)
+    safely do
+      gg = new_client(credentials)
+      return gg.gogrid_power_server(:power => 'off', :name => id)
+    end
+  end
+
+  def destroy_instance(credentials, id)
+    safely do
+      gg = new_client(credentials)
+      gg.gogrid_delete_server(:name => id)
+    end
+  end
+
+
+  define_instance_states do
+    start.to( :on )          .on( :create )
+    pending.to( :on )         .automatically
+    running.to( :off )        .on( :reboot )
+    running.to( :off )        .on( :stop )
+    shutting_down.to( :off )  .automatically
+    stopped.to( :off )        .automatically
+  end
+
+  private
+
+  def convert_image(gg_image, owner_id=nil)
+    Image.new( {
+      :id=>gg_image['id'],
+      :name => gg_image['name'],
+      :description=>gg_image['friendlyName'],
+      :owner_id=>owner_id,
+      :architecture=>convert_arch(gg_image['description']),
+    } )
+  end
+
+  def new_client(credentials)
+    Rightscale::Gogrid.new(credentials.user, credentials.password)
+  end
+
+  # Determine architecture from description
+  def convert_arch(description)
+    return 'x86_64' if description.include?('64-bit')
+    return 'i386'
+  end
+
+  # NOTE: GoGrid doesn't use an ID for your instances. Instead they using a 
'friendly name'
+  def convert_srv_to_instance(srv, flavor_id)
+    server = srv.kind_of?(Hash) ? srv : srv.first
+    Instance.new({
+      :id => server['name'],
+      :state => server['state']['name'],
+      :name => server['description'],
+      :image_id => server['image']['id'],
+      :owner_id => 'root',
+      :realm => 'us',
+      :public_addresses => server['ip']['ip'],
+      :private_addresses => nil,
+      :flavor_id => flavor_id,
+      :actions => instance_actions_for(server['state']['name'])
+    })
+  end
+
+  # We produce flavors from RAM
+  def convert_ram_to_flavor(ram)
+    'server-with-'+ram.downcase+'-ram'
+  end
+
+  # You need a free IP from subnet you have assigned in case you want to start 
an instance
+  def get_free_ip(credentials)
+    gg=new_client(credentials)
+    # TODO: I'm not sure about this, they changed API recently and 
right_gogrid doesn't work well there
+    ip=gg.list_ips('Unassigned').select {|i| i['public'] }.last
+    return ip['ip'] if ip and ip['ip']
+    return nil
+  end
+
+  def safely(&block)
+    begin
+      block.call
+    rescue Rightscale::GogridError => e
+      if ( e.include?( /Forbidden/ ) )
+        raise Deltacloud::AuthException.new
+      else
+        e.errors.each do |error|
+          puts "ERROR #{error.inspect}"
+        end
+      end
+    end
+  end
+
+end
+
+    end
+  end
+end
+
+
diff --git a/server/lib/deltacloud/drivers/gogrid/gogrid_test.rb 
b/server/lib/deltacloud/drivers/gogrid/gogrid_test.rb
new file mode 100644
index 0000000..ab2c5af
--- /dev/null
+++ b/server/lib/deltacloud/drivers/gogrid/gogrid_test.rb
@@ -0,0 +1,73 @@
+require 'lib/deltacloud/drivers/gogrid/gogrid_driver'
+require 'test/unit'
+
+CREDS = nil
+
+class GoGridTest < Test::Unit::TestCase
+
+  def test_valid_flavors
+    gd=Deltacloud::Drivers::Gogrid::GogridDriver.new
+    assert_kind_of Array, gd.flavors(CREDS)
+    assert_kind_of Flavor, gd.flavors(CREDS).first
+  end
+
+  def test_valid_images
+    gd=Deltacloud::Drivers::Gogrid::GogridDriver.new
+    assert_kind_of Array, gd.images(CREDS)
+    assert_kind_of Image, gd.images(CREDS).first
+  end
+
+  def test_create_instance
+    gd=Deltacloud::Drivers::Gogrid::GogridDriver.new
+    images = gd.images(CREDS)
+    assert_kind_of Array, images
+    instance = gd.create_instance(CREDS, images.first.id)
+    assert_kind_of Instance, instance
+  end
+
+  def test_list_instances
+    gd=Deltacloud::Drivers::Gogrid::GogridDriver.new
+    instances = gd.instances(CREDS)
+    assert_kind_of Array, instances
+    assert_kind_of Instance, instances.first
+  end
+
+  def test_get_instance
+    gd=Deltacloud::Drivers::Gogrid::GogridDriver.new
+    instances = gd.instances(CREDS)
+    if instances.kind_of?(Array)
+      assert_kind_of Instance, gd.instance(CREDS, { :id => instances.first.id 
})
+    end
+  end
+
+  def test_list_realms
+    gd=Deltacloud::Drivers::Gogrid::GogridDriver.new
+    assert_kind_of Array, gd.realms(CREDS)
+    assert_kind_of Realm, gd.realms(CREDS).first
+  end
+
+  # This tests fails anyway, because created instance isn't ready for it. 
+  # If you want to really test, if these actions work properly, you could 
create an instance
+  # first and change instances.last.id to ID of your instance. In this way 
tests will work.
+
+  def test_reboot_instance
+    gd=Deltacloud::Drivers::Gogrid::GogridDriver.new
+    instances = gd.instances(CREDS)
+    assert_kind_of Hash, gd.reboot_instance(CREDS, instances.last.id)
+  end
+
+  def test_stop_instance
+    gd=Deltacloud::Drivers::Gogrid::GogridDriver.new
+    instances = gd.instances(CREDS)
+    assert_kind_of Hash, gd.stop_instance(CREDS, instances.last.id)
+  end
+
+  def test_destroy_instance
+    gd=Deltacloud::Drivers::Gogrid::GogridDriver.new
+    instances = gd.instances(CREDS)
+    assert_kind_of Hash, gd.destroy_instance(CREDS, instances.last.id)
+  end
+
+
+
+end
-- 
1.6.6.2

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

Reply via email to