---
 server/lib/deltacloud/drivers/ec2/ec2_driver.rb    |   22 ++++-
 .../lib/deltacloud/drivers/gogrid/gogrid_client.rb |    9 +-
 .../lib/deltacloud/drivers/gogrid/gogrid_driver.rb |  116 +++++++++++++++++++-
 server/lib/deltacloud/drivers/gogrid/test.rb       |   13 --
 .../lib/deltacloud/helpers/application_helper.rb   |    4 +-
 server/lib/deltacloud/helpers/conversion_helper.rb |    6 +-
 server/lib/deltacloud/models/base_model.rb         |    2 +-
 server/public/javascripts/application.js           |   12 ++
 server/server.rb                                   |   21 ++++
 server/views/load_balancers/new.html.haml          |   16 ++-
 server/views/load_balancers/show.html.haml         |   23 +++-
 server/views/load_balancers/show.xml.haml          |    1 +
 12 files changed, 207 insertions(+), 38 deletions(-)
 delete mode 100644 server/lib/deltacloud/drivers/gogrid/test.rb

diff --git a/server/lib/deltacloud/drivers/ec2/ec2_driver.rb 
b/server/lib/deltacloud/drivers/ec2/ec2_driver.rb
index d15a198..aba42b1 100644
--- a/server/lib/deltacloud/drivers/ec2/ec2_driver.rb
+++ b/server/lib/deltacloud/drivers/ec2/ec2_driver.rb
@@ -190,7 +190,7 @@ class EC2Driver < Deltacloud::BaseDriver
         :instance_initiated_shutdown_behavior => 'terminate'
       )
       instance = convert_instance( ec2_instances.instancesSet.item.first, 
'pending' )
-      if opts[:load_balancer_id]
+      if opts[:load_balancer_id] and opts[:load_balancer_id]!=""
         elb = new_client(credentials, :elb)
         elb.register_instances_with_load_balancer({
           :instances => [instance.id],
@@ -365,6 +365,24 @@ class EC2Driver < Deltacloud::BaseDriver
     end
   end
 
+  def lb_register_instance(credentials, opts={})
+    ec2 = new_client( credentials, :elb)
+    safely do
+      ec2.register_instances_with_load_balancer(:instances => 
[opts[:instance_id]],
+        :load_balancer_name => opts[:id])
+      load_balancer(credentials, :id => opts[:id])
+    end
+  end
+
+  def lb_unregister_instance(credentials, opts={})
+    ec2 = new_client( credentials, :elb)
+    safely do
+      ec2.deregister_instances_from_load_balancer(:instances => 
[opts[:instance_id]],
+        :load_balancer_name => opts[:id])
+      load_balancer(credentials, :id => opts[:id])
+    end
+  end
+
   private
 
   def new_client(credentials, type = :ec2)
@@ -404,7 +422,7 @@ class EC2Driver < Deltacloud::BaseDriver
     end
     loadbalancer.Instances.member.each do |instance|
       balancer.instances << instances(credentials, :id => 
instance['InstanceId']).first
-    end
+    end if loadbalancer.Instances
     balancer
   end
 
diff --git a/server/lib/deltacloud/drivers/gogrid/gogrid_client.rb 
b/server/lib/deltacloud/drivers/gogrid/gogrid_client.rb
index c37f061..5492170 100644
--- a/server/lib/deltacloud/drivers/gogrid/gogrid_client.rb
+++ b/server/lib/deltacloud/drivers/gogrid/gogrid_client.rb
@@ -9,7 +9,7 @@ class GoGridClient
                  apikey='YOUR API KEY',
                  secret='YOUR SHARED SECRET', 
                  format='json',
-                 version='1.5')
+                 version='1.6')
     @server = server
     @secret = secret
     @default_params = {'format'=>format, 'v'=>version,'api_key' => apikey}
@@ -36,11 +36,8 @@ class GoGridClient
     else
       @default_params['v'] = '1.5'
     end
-    begin
-      JSON::parse(sendAPIRequest(method, params))
-    rescue Exception => e
-      STDERR.puts("ERROR: #{e.message}")
-    end
+    request = sendAPIRequest(method, params)
+    JSON::parse(request)
   end
   
   def encode_params(params)
diff --git a/server/lib/deltacloud/drivers/gogrid/gogrid_driver.rb 
b/server/lib/deltacloud/drivers/gogrid/gogrid_driver.rb
index e6c99c5..343102f 100644
--- a/server/lib/deltacloud/drivers/gogrid/gogrid_driver.rb
+++ b/server/lib/deltacloud/drivers/gogrid/gogrid_driver.rb
@@ -36,6 +36,7 @@ module Deltacloud
 class GogridDriver < Deltacloud::BaseDriver
 
   feature :instances, :authentication_password
+  feature :instances, :register_to_load_balancer
 
   define_hardware_profile 'server' do
     cpu            2
@@ -45,7 +46,7 @@ class GogridDriver < Deltacloud::BaseDriver
 
   def supported_collections
     DEFAULT_COLLECTIONS.reject! { |c| [ :storage_volumes, :storage_snapshots 
].include?(c) }
-    DEFAULT_COLLECTIONS + [ :keys ]
+    DEFAULT_COLLECTIONS + [ :keys, :load_balancers ]
   end
 
   def images(credentials, opts=nil)
@@ -107,6 +108,24 @@ class GogridDriver < Deltacloud::BaseDriver
     end
   end
 
+  def lb_register_instance(credentials, opts={})
+    client = new_client(credentials)
+    instance = instance(credentials, :id => opts[:instance_id])
+    balancer = client.request('grid/loadbalancer/get', { 'name' => 
opts[:id]})['list'].first
+    safely do
+      convert_load_balancer(credentials, 
client.request('grid/loadbalancer/edit', {
+        "id" => balancer['id'],
+        "realiplist.#{balancer['realiplist'].size}.ip" => 
instance.public_addresses.first,
+        "realiplist.#{balancer['realiplist'].size}.port" => 
balancer['virtualip']['port']
+      }))
+    end
+  end
+
+  def lb_unregister_instance(credentials, opts={})
+      raise Deltacloud::BackendFeatureUnsupported.new('501',
+    'Unregistering instances from load balancer is not supported in GoGrid')
+  end
+
   def list_instances(credentials, id)
     instances = []
     safely do
@@ -192,6 +211,67 @@ class GogridDriver < Deltacloud::BaseDriver
     return creds
   end
 
+
+  def create_load_balancer(credentials, opts={})
+    gogrid = new_client(credentials)
+    balancer, l_instance = nil, nil
+    safely do
+      virtip = get_free_ip_from_realm(credentials, opts['realm_id'])
+      if opts['instance_id']
+        l_instance = instance(credentials, :id => opts['instance_id'])
+        real_ip = {
+          'realiplist.0.port' => opts['listener_inst_port'],
+          'realiplist.0.ip' => l_instance ? l_instance.public_addresses.first 
: ""
+        }
+      else
+        real_ip = false
+      end
+      request = {
+        'name' => opts['name'],
+        'virtualip.ip' => virtip,
+        'virtualip.port' => opts['listener_lbr_port'],
+      }
+      request.merge!(real_ip) if real_ip
+      balancer = gogrid.request('grid/loadbalancer/add', request)['list'].first
+    end
+    balancer = convert_load_balancer(credentials, balancer)
+    balancer.instances = [l_instance] if l_instance
+    balancer
+  end
+
+  def destroy_load_balancer(credentials, id)
+    gogrid = new_client(credentials)
+    balancer = nil
+    safely do
+      balancer = gogrid.request('grid/loadbalancer/delete', { 'name' => id })
+      balancer = load_balancer(credentials, :id => id) unless balancer
+    end
+    convert_load_balancer(credentials, balancer)
+  end
+
+  def load_balancers(credentials, opts={})
+    gogrid = new_client(credentials)
+    balancers = []
+    safely do
+      balancer = gogrid.request('grid/loadbalancer/list', opts || 
{})['list'].each do |balancer|
+        balancers << balancer
+      end
+    end
+    balancers.collect { |b| convert_load_balancer(credentials, b) }
+  end
+
+  def load_balancer(credentials, opts={})
+    gogrid = new_client(credentials)
+    balancer = nil
+    begin
+      balancer = gogrid.request('grid/loadbalancer/get', { 'name' => opts[:id] 
})['list'].first
+      balancer['instances'] = instances(credentials)
+      return convert_load_balancer(credentials, balancer)
+    rescue OpenURI::HTTPError
+      balancer = load_balancers(credentials, :id => opts[:id]).first
+    end
+  end
+
   define_instance_states do
     start.to( :pending )         .automatically
     pending.to( :running )       .automatically
@@ -205,7 +285,37 @@ class GogridDriver < Deltacloud::BaseDriver
 
   def new_client(credentials)
     GoGridClient.new('https://api.gogrid.com/api', credentials.user, 
credentials.password)
+  end
+
+  def convert_load_balancer(credentials, loadbalancer)
+    if loadbalancer['datacenter']
+      b_realm = realm(credentials, :id => loadbalancer['datacenter']['id'])
+    else
+      # Report first Realm until loadbalancer become ready
+      b_realm = realm(credentials, :id => 1)
+    end
+    balancer = LoadBalancer.new({
+      :id => loadbalancer['name'],
+      :realms => [b_realm]
+    })
+    balancer.public_addresses = [loadbalancer['virtualip']['ip']['ip']] if 
loadbalancer['virtualip'] and loadbalancer['virtualip']['ip']
+    balancer.listeners = []
+    balancer.instances = []
+    instance_ips = []
+    loadbalancer['realiplist'].each do |instance_ip|
+      balancer.add_listener({
+        :protocol => 'TCP',
+        :load_balancer_port => loadbalancer['virtualip']['port'],
+        :instance_port => instance_ip['port']
+      })
+      instance_ips << instance_ip['ip']['ip']
+    end if loadbalancer['realiplist']
+    balancer.instances = get_load_balancer_instances(instance_ips, 
loadbalancer['instances'])
+    return balancer
+  end
 
+  def get_load_balancer_instances(instance_ips, instances)
+    instances.select { |i| instance_ips.include?(i.public_addresses.first) } 
if instances
   end
 
   def get_login_data(client, instance_id)
@@ -305,11 +415,11 @@ class GogridDriver < Deltacloud::BaseDriver
     state.eql?('Off') ? 'STOPPED' : 'RUNNING'
   end
 
-  def get_free_ip_from_realm(credentials, realm_id)
+  def get_free_ip_from_realm(credentials, realm_id, ip_type=1)
     ip = ""
     safely do
       ip = new_client(credentials).request('grid/ip/list', {
-        'ip.type' => '1',
+        'ip.type' => ip_type,
         'ip.state' => '1',
         'datacenter' => realm_id
       })['list'].first['ip']
diff --git a/server/lib/deltacloud/drivers/gogrid/test.rb 
b/server/lib/deltacloud/drivers/gogrid/test.rb
deleted file mode 100644
index 809081d..0000000
--- a/server/lib/deltacloud/drivers/gogrid/test.rb
+++ /dev/null
@@ -1,13 +0,0 @@
-require 'gogrid_client'
-require 'ap'
-
-user='fbb1de3897597ccf'
-password='ngieth10'
-
-client=GoGridClient.new('https://api.gogrid.com/api', user, password)
-
-ap client.request('grid/ip/list', {
-  'ip.type' => '1',
-  'ip.state' => '1',
-  'datacenter' => '1'
-})
diff --git a/server/lib/deltacloud/helpers/application_helper.rb 
b/server/lib/deltacloud/helpers/application_helper.rb
index 9a9dfdc..ab96f0c 100644
--- a/server/lib/deltacloud/helpers/application_helper.rb
+++ b/server/lib/deltacloud/helpers/application_helper.rb
@@ -41,8 +41,8 @@ module ApplicationHelper
     collections[:instances].operations[action.to_sym].method
   end
 
-  def driver_has_feature?(feature_name)
-    not driver.features(:instances).select{ |f| f.name.eql?(feature_name) 
}.empty?
+  def driver_has_feature?(feature_name, collection=:instances)
+    not driver.features(collection).select{ |f| f.name.eql?(feature_name) 
}.empty?
   end
 
   def driver_has_auth_features?
diff --git a/server/lib/deltacloud/helpers/conversion_helper.rb 
b/server/lib/deltacloud/helpers/conversion_helper.rb
index e96f9b7..7b0c57e 100644
--- a/server/lib/deltacloud/helpers/conversion_helper.rb
+++ b/server/lib/deltacloud/helpers/conversion_helper.rb
@@ -22,17 +22,17 @@ require 'deltacloud/base_driver'
 module ConversionHelper
 
   def convert_to_json(type, obj)
-    if ( [ :flavor, :account, :image, :realm, :instance, :storage_volume, 
:storage_snapshot, :hardware_profile ].include?( type ) )
+    if ( [ :account, :image, :realm, :instance, :storage_volume, 
:storage_snapshot, :hardware_profile ].include?( type ) )
       if Array.eql?(obj.class)
         data = obj.collect do |o|
-          o.to_hash.merge({ :href => self.send(:"#{type}_url", 
type.eql?(:hardware_profile) ? o.name : o.id ) })
+          o.to_hash.merge({ :href => self.send(:"#{type}_url", 
type.eql?(:instance_profile) ? o.name : o.id ) })
         end
         type = type.to_s.pluralize
       else
         data = obj.to_hash
         data.merge!({ :href => self.send(:"#{type}_url", data[:id]) })
       end
-      return { :"#{type}" => data }.to_json
+      return JSON.generate(Hash[{ :"#{type}" => data }], :allow_nan => true )
     end
   end
 
diff --git a/server/lib/deltacloud/models/base_model.rb 
b/server/lib/deltacloud/models/base_model.rb
index aa997a5..13c65d6 100644
--- a/server/lib/deltacloud/models/base_model.rb
+++ b/server/lib/deltacloud/models/base_model.rb
@@ -48,7 +48,7 @@ class BaseModel
 
   def to_hash
     out = {}
-    self.attributes.each { |attribute| out.merge!({ attribute => 
self.send(:"#{attribute}") } ) }
+    self.attributes.each { |attribute| out.merge!({ attribute => 
self.send(:"#{attribute}").to_s } ) }
     out
   end
 
diff --git a/server/public/javascripts/application.js 
b/server/public/javascripts/application.js
index 80e1d1c..e2a2751 100644
--- a/server/public/javascripts/application.js
+++ b/server/public/javascripts/application.js
@@ -29,4 +29,16 @@ $(document).ready(function() {
     return false;
   })
 
+  if ($('select#list_instances').length) {
+    $('select#list_instances').html("<option>Loading instances...</option>");
+    $.getJSON("/api/instances.json?state=RUNNING",
+      function(data){
+        $('select#list_instances').empty();
+        $.each(data.instances, function(i,item){
+          $('select#list_instances').append('<option 
value="'+item.id+'">'+item.id+'</option>');
+        });
+      }
+    );
+  }
+
 })
diff --git a/server/server.rb b/server/server.rb
index e0e8155..55791a9 100644
--- a/server/server.rb
+++ b/server/server.rb
@@ -358,6 +358,7 @@ end
 
 get '/api/load_balancers/new' do
   @realms = driver.realms(credentials)
+  @instances = driver.instances(credentials) if 
driver_has_feature?(:register_instance, :load_balancers)
   respond_to do |format|
     format.html { haml :"load_balancers/new" }
   end
@@ -404,4 +405,24 @@ collection :load_balancers do
     end
   end
 
+  operation :register, :method => :post, :member => true do
+    description "Add instance to loadbalancer"
+    param :id,  :string,  :required
+    param :instance_id, :string,  :required
+    control do
+      driver.lb_register_instance(credentials, params)
+      redirect(load_balancer_url(params[:id]))
+    end
+  end
+
+  operation :unregister, :method => :post, :member => true do
+    description "Remove instance from loadbalancer"
+    param :id,  :string,  :required
+    param :instance_id, :string,  :required
+    control do
+      driver.lb_unregister_instance(credentials, params)
+      redirect(load_balancer_url(params[:id]))
+    end
+  end
+
 end
diff --git a/server/views/load_balancers/new.html.haml 
b/server/views/load_balancers/new.html.haml
index 734dc44..3d734b1 100644
--- a/server/views/load_balancers/new.html.haml
+++ b/server/views/load_balancers/new.html.haml
@@ -5,25 +5,33 @@
     %label
       Name:
     %input{ :name => 'name', :size => 30 }/
+  -if @instances
+    %p
+      %label
+        Running instance:
+      %select{ :name => 'instance_id'}
+        - @instances.select{|i| i.state=="RUNNING"}.each do |instance|
+          %option{ :value => instance.id } #{instance.id}
   %p
     %label
       Realm:
     %select{ :name => 'realm_id'}
       - @realms.each do |realm|
-        %option{ :value => realm.id } #{realm.id}
+        %option{ :value => realm.id } #{realm.id} - #{realm.name}
+  %hr
   %p
     %label
-      Listener protocol:
+      Protocol:
     %select{ :name => 'listener_protocol'}
       %option{ :value => 'HTTP'}  HTTP
       %option{ :value => 'TCP'} TCP
   %p
     %label
-      Listener load balancer port:
+      Load balancer port:
     %input{ :name => "listener_lbr_port", :size => 30}
   %p
     %label
-      Listener instance port:
+      Instances port:
     %input{ :name => "listener_inst_port", :size => 30}
   %p
     %input{ :type => :submit, :name => "commit", :value => "create" }/
diff --git a/server/views/load_balancers/show.html.haml 
b/server/views/load_balancers/show.html.haml
index a8ceb87..615bd78 100644
--- a/server/views/load_balancers/show.html.haml
+++ b/server/views/load_balancers/show.html.haml
@@ -6,12 +6,13 @@
     %dt Public addresses
     %dd
       = @load_balancer.public_addresses.join(',')
-    %dt Created at
-    %dd
-      = @load_balancer.created_at
+    - if @load_balancer.created_at
+      %dt Created at
+      %dd
+        = @load_balancer.created_at
     %dt Realms
     %dd
-      = @load_balancer.realms.collect { |r| r.id }.join(',')
+      = @load_balancer.realms.collect { |r| "#{r.id} - #{r.name}" }.join(',')
     %dt Listeners
     %dd
       - @load_balancer.listeners.each do |listener|
@@ -19,3 +20,17 @@
         %br
         ="Instance port: #{listener.instance_port}"
         %br
+    - if @load_balancer.instances.class.eql?(Array)
+      %dt Instances
+      - @load_balancer.instances.each do |inst|
+        %dd
+          =inst.id
+          %a{:class => :post, :href => 
unregister_load_balancer_url(@load_balancer.id, :instance_id => inst.id)} Delete
+
+%form{:action => 
url_for("/api/load_balancers/#...@load_balancer.id}/register"), :method => 
:post}
+  %p
+    %strong Assign instance to this load balancer
+  %p
+    %label Instance
+    %select{:name => :instance_id, :id => "list_instances"}
+    %input{:type => :submit, :value => "Assign"}
diff --git a/server/views/load_balancers/show.xml.haml 
b/server/views/load_balancers/show.xml.haml
index c012699..1e50ff9 100644
--- a/server/views/load_balancers/show.xml.haml
+++ b/server/views/load_balancers/show.xml.haml
@@ -17,3 +17,4 @@
   %instances
     - @load_balancer.instances.each do |instance|
       %instance{:href => instance_url(instance.id), :id => instance.id}
+        %link{:rel => "unregister", :href => 
unregister_load_balancer_url(@load_balancer.id, { :instance_id => instance.id})}
-- 
1.7.2

Reply via email to