---
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