You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@deltacloud.apache.org by mf...@redhat.com on 2010/08/27 14:55:29 UTC

[PATCH core 1/5] Fixed gitignore filename IP managment for GoGrid driver

---
 server/.gitiginore                                 |    4 --
 server/.gitignore                                  |    4 ++
 server/deltacloud.rb                               |    1 +
 server/lib/deltacloud/base_driver/base_driver.rb   |    4 ++
 server/lib/deltacloud/base_driver/features.rb      |    6 +++
 server/lib/deltacloud/drivers/ec2/ec2_driver.rb    |   47 +++++++++++++++++++-
 .../lib/deltacloud/drivers/gogrid/gogrid_client.rb |    7 +--
 .../lib/deltacloud/drivers/gogrid/gogrid_driver.rb |   47 ++++++++++++++++++-
 .../lib/deltacloud/helpers/application_helper.rb   |    1 +
 server/lib/deltacloud/helpers/conversion_helper.rb |    2 +-
 server/lib/deltacloud/models/ip_address.rb         |   26 +++++++++++
 server/lib/sinatra/rabbit.rb                       |    2 +
 server/public/javascripts/application.js           |    9 ++++
 server/server.rb                                   |   38 ++++++++++++++++
 server/views/instances/new.html.haml               |    6 +++
 server/views/ip_addresses/index.html.haml          |   27 +++++++++++
 server/views/ip_addresses/index.xml.haml           |    4 ++
 server/views/ip_addresses/show.html.haml           |   23 ++++++++++
 server/views/ip_addresses/show.xml.haml            |   10 ++++
 server/views/realms/index.html.haml                |    4 +-
 20 files changed, 256 insertions(+), 16 deletions(-)
 delete mode 100644 server/.gitiginore
 create mode 100644 server/.gitignore
 create mode 100644 server/lib/deltacloud/models/ip_address.rb
 create mode 100644 server/views/ip_addresses/index.html.haml
 create mode 100644 server/views/ip_addresses/index.xml.haml
 create mode 100644 server/views/ip_addresses/show.html.haml
 create mode 100644 server/views/ip_addresses/show.xml.haml

diff --git a/server/.gitiginore b/server/.gitiginore
deleted file mode 100644
index 48e68d2..0000000
--- a/server/.gitiginore
+++ /dev/null
@@ -1,4 +0,0 @@
-log/*.log
-*.swp
-*.kpf
-tmp/*
diff --git a/server/.gitignore b/server/.gitignore
new file mode 100644
index 0000000..48e68d2
--- /dev/null
+++ b/server/.gitignore
@@ -0,0 +1,4 @@
+log/*.log
+*.swp
+*.kpf
+tmp/*
diff --git a/server/deltacloud.rb b/server/deltacloud.rb
index 6799b2f..49050fa 100644
--- a/server/deltacloud.rb
+++ b/server/deltacloud.rb
@@ -10,6 +10,7 @@ require 'deltacloud/models/realm'
 require 'deltacloud/models/image'
 require 'deltacloud/models/instance'
 require 'deltacloud/models/key'
+require 'deltacloud/models/ip_address'
 require 'deltacloud/models/instance_profile'
 require 'deltacloud/models/storage_snapshot'
 require 'deltacloud/models/storage_volume'
diff --git a/server/lib/deltacloud/base_driver/base_driver.rb b/server/lib/deltacloud/base_driver/base_driver.rb
index 88563a5..82209bb 100644
--- a/server/lib/deltacloud/base_driver/base_driver.rb
+++ b/server/lib/deltacloud/base_driver/base_driver.rb
@@ -136,6 +136,10 @@ module Deltacloud
       []
     end
 
+    def ip_addresses(credentials, opts=nil)
+      []
+    end
+
     def image(credentials, opts)
       images = images(credentials, opts)
       return images.first unless images.empty?
diff --git a/server/lib/deltacloud/base_driver/features.rb b/server/lib/deltacloud/base_driver/features.rb
index 3ed4085..abc97b5 100644
--- a/server/lib/deltacloud/base_driver/features.rb
+++ b/server/lib/deltacloud/base_driver/features.rb
@@ -158,6 +158,12 @@ module Deltacloud
       end
     end
 
+    declare_feature :instances, :assign_ip_address do
+      operation :create do
+        param :ip_address_id, :string, :optional
+      end
+    end
+
     declare_feature :instances, :hardware_profiles do
       description "Size instances according to changes to a hardware profile"
       # The parameters are filled in from the hardware profiles
diff --git a/server/lib/deltacloud/drivers/ec2/ec2_driver.rb b/server/lib/deltacloud/drivers/ec2/ec2_driver.rb
index 909eca3..eea0c41 100644
--- a/server/lib/deltacloud/drivers/ec2/ec2_driver.rb
+++ b/server/lib/deltacloud/drivers/ec2/ec2_driver.rb
@@ -36,7 +36,7 @@ module Deltacloud
 class EC2Driver < Deltacloud::BaseDriver
 
   def supported_collections
-    DEFAULT_COLLECTIONS + [ :keys ]
+    DEFAULT_COLLECTIONS + [ :keys, :ip_addresses ]
   end
 
   feature :instances, :user_data
@@ -310,6 +310,41 @@ class EC2Driver < Deltacloud::BaseDriver
     end
   end
 
+  def ip_addresses(credentials, opts=nil)
+    ec2 = new_client( credentials )
+    ips = []
+    safely do
+      address_set = ec2.describe_addresses.addressesSet
+      address_set.item.each do |ip|
+        ips << convert_ip_address(ip)
+      end if address_set
+    end
+    ips = filter_on( ips, :type, opts )
+    ips = filter_on( ips, :state, opts )
+    return ips
+  end
+
+  def ip_address(credentials, opts={})
+    ip_addresses(credentials).select { |ip| ip.id.eql?(opts[:id])}.first
+  end
+
+  def create_ip_address(credentials, opts)
+    ec2 = new_client( credentials )
+    safely do
+      ip = ec2.allocate_address().publicIp
+      return ip_addresses(credentials, :id => ip)
+    end
+  end
+
+  def destroy_ip_address(credentials, opts)
+    ec2 = new_client( credentials )
+    response = false
+    safely do
+      response = ec2.release_address(:public_ip => opts[:id]).return
+    end
+    throw BackendError.new(500, 'Unable to release this IP address', '', '') unless response.to_s.eql?("true")
+  end
+
   private
 
   def new_client(credentials)
@@ -323,6 +358,16 @@ class EC2Driver < Deltacloud::BaseDriver
     end
   end
 
+  def convert_ip_address(ip)
+    IpAddress.new({
+      :id => ip['publicIp'],
+      :address => ip['publicIp'],
+      :type => 'public',
+      :state => ip['instanceId'] ? 'assigned' : 'unassigned',
+      :realm_id => 'us-east-1a' # TODO: Add realm Realm here
+    })
+  end
+
   def convert_key(key)
     Key.new({
       :id => key['keyName'],
diff --git a/server/lib/deltacloud/drivers/gogrid/gogrid_client.rb b/server/lib/deltacloud/drivers/gogrid/gogrid_client.rb
index c37f061..4ab73b1 100644
--- a/server/lib/deltacloud/drivers/gogrid/gogrid_client.rb
+++ b/server/lib/deltacloud/drivers/gogrid/gogrid_client.rb
@@ -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
+    result = sendAPIRequest(method, params)
+    JSON::parse(result)
   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..4034b5d 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, :assign_ip_address
 
   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, :ip_addresses ]
   end
 
   def images(credentials, opts=nil)
@@ -82,13 +83,19 @@ class GogridDriver < Deltacloud::BaseDriver
       server_ram = "512MB"
     end
     client = new_client(credentials)
+    if opts and opts[:ip_address_id]
+      ip_address = ip_address(credentials, :id => opts[:ip_address_id])
+      ip_address = ip_address.address
+    else
+      ip_address = get_free_ip_from_realm(credentials, opts[:realm_id] || '1')
+    end
     name = (opts[:name] && opts[:name]!='') ? opts[:name] : get_random_instance_name
     safely do
       instance = client.request('grid/server/add', {
         'name' => name,
         'image' => image_id,
         'server.ram' => server_ram,
-        'ip' => get_free_ip_from_realm(credentials, opts[:realm_id] || '1')
+        'ip' => ip_address
       })['list'].first
       if instance
         login_data = get_login_data(client, instance[:id])
@@ -120,7 +127,6 @@ class GogridDriver < Deltacloud::BaseDriver
   end
 
   def instances(credentials, opts=nil)
-    require 'ap'
     instances = []
     if opts and opts[:id]
       begin
@@ -192,6 +198,32 @@ class GogridDriver < Deltacloud::BaseDriver
     return creds
   end
 
+  def ip_addresses(credentials, opts=nil)
+    gogrid = new_client( credentials )
+    ips = []
+    safely do
+      gogrid.request('grid/ip/list')['list'].each do |ip|
+        ips << convert_ip_address(ip)
+      end
+    end
+    puts opts.inspect
+    ips = filter_on( ips, :type, opts )
+    ips = filter_on( ips, :state, opts )
+    return ips
+  end
+
+  def ip_address(credentials, opts={})
+    ip_addresses(credentials).select { |ip| ip.id.eql?(opts[:id].to_i)}.first
+  end
+
+  def create_ip_address(credentials, opts)
+    throw BackendFeatureUnsupported.new(501, "GoGrid not supports creating new IP addresses")
+  end
+
+  def destroy_ip_address(credentials, opts)
+    throw BackendFeatureUnsupported.new(501, "GoGrid not supports destroying new IP addresses")
+  end
+
   define_instance_states do
     start.to( :pending )         .automatically
     pending.to( :running )       .automatically
@@ -205,7 +237,16 @@ class GogridDriver < Deltacloud::BaseDriver
 
   def new_client(credentials)
     GoGridClient.new('https://api.gogrid.com/api', credentials.user, credentials.password)
+  end
 
+  def convert_ip_address(ip)
+    IpAddress.new({
+      :id => ip['id'],
+      :address => ip['ip'],
+      :type => ip['public'] ? 'public' : 'private',
+      :state => ip['state']['name'].downcase,
+      :realm_id => ip['datacenter']['id']
+    })
   end
 
   def get_login_data(client, instance_id)
diff --git a/server/lib/deltacloud/helpers/application_helper.rb b/server/lib/deltacloud/helpers/application_helper.rb
index 9a9dfdc..8b525ff 100644
--- a/server/lib/deltacloud/helpers/application_helper.rb
+++ b/server/lib/deltacloud/helpers/application_helper.rb
@@ -60,6 +60,7 @@ module ApplicationHelper
       filter.merge!(:architecture => params[:architecture]) if params[:architecture]
       filter.merge!(:owner_id => params[:owner_id]) if params[:owner_id]
       filter.merge!(:state => params[:state]) if params[:state]
+      filter.merge!(:type => params[:type]) if params[:type]
       filter = nil if filter.keys.size.eql?(0)
       singular = model.to_s.singularize.to_sym
       @elements = driver.send(model.to_sym, credentials, filter)
diff --git a/server/lib/deltacloud/helpers/conversion_helper.rb b/server/lib/deltacloud/helpers/conversion_helper.rb
index e96f9b7..5641343 100644
--- a/server/lib/deltacloud/helpers/conversion_helper.rb
+++ b/server/lib/deltacloud/helpers/conversion_helper.rb
@@ -22,7 +22,7 @@ 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 ( [ :flavor, :account, :image, :realm, :instance, :storage_volume, :storage_snapshot, :hardware_profile, :ip_address ].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 ) })
diff --git a/server/lib/deltacloud/models/ip_address.rb b/server/lib/deltacloud/models/ip_address.rb
new file mode 100644
index 0000000..db81271
--- /dev/null
+++ b/server/lib/deltacloud/models/ip_address.rb
@@ -0,0 +1,26 @@
+#
+# Copyright (C) 2009  Red Hat, Inc.
+#
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements.  See the NOTICE file distributed with
+# this work for additional information regarding copyright ownership.  The
+# ASF licenses this file to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance with the
+# License.  You may obtain a copy of the License at
+#
+#       http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the
+# License for the specific language governing permissions and limitations
+# under the License.
+
+class IpAddress < BaseModel
+
+  attr_accessor :address
+  attr_accessor :type
+  attr_accessor :state
+  attr_accessor :realm_id
+
+end
diff --git a/server/lib/sinatra/rabbit.rb b/server/lib/sinatra/rabbit.rb
index f411268..91d48da 100644
--- a/server/lib/sinatra/rabbit.rb
+++ b/server/lib/sinatra/rabbit.rb
@@ -256,10 +256,12 @@ class String
   end
 
   def pluralize
+    return self+'es' if self =~ /ss$/
     self + "s"
   end
 
   def singularize
+    return self.gsub(/es$/, '') if self =~ /ses$/
     self.gsub(/s$/, '')
   end
 
diff --git a/server/public/javascripts/application.js b/server/public/javascripts/application.js
index 80e1d1c..19ee379 100644
--- a/server/public/javascripts/application.js
+++ b/server/public/javascripts/application.js
@@ -29,4 +29,13 @@ $(document).ready(function() {
     return false;
   })
 
+  if ($("select[name=ip_address_id]").length) {
+    $.getJSON('/api/ip_addresses', { format : 'json', state : 'unassigned', type : 'public'}, function(data) {
+      $("select[name=ip_address_id]").empty()
+      $.each(data.ip_addresses, function(i, ip_address){
+        $("select[name=ip_address_id]").append('<option value="'+ip_address.id+'">'+ip_address.address+'</option>')
+      }) 
+    }) 
+  }
+
 })
diff --git a/server/server.rb b/server/server.rb
index 1373fa3..130ecb1 100644
--- a/server/server.rb
+++ b/server/server.rb
@@ -352,3 +352,41 @@ collection :keys do
   end
 
 end
+
+collection :ip_addresses do
+  description "Manage IP addresses"
+
+  operation :index do
+    description "List all IP addresses associated with your account"
+    param :type,  :string,  :optional
+    param :state,  :string,  :optional
+    control do
+      filter_all :ip_addresses
+    end
+  end
+
+  operation :show do
+    description "Show details about given IP address"
+    param :id,  :string,  :required
+    control { show :ip_address }
+  end
+
+  operation :create do
+    description "Create a new IP address"
+    param  :ip,  :string,  :optional
+    control do
+      @ip_address = driver.create_ip_address(credentials, params)
+      show :ip_address
+    end
+  end
+
+  operation :destroy do
+    description "Destroy IP address"
+    param  :id,  :string,  :required
+    control do
+      @ip_address = driver.destroy_ip_address(credentials, params)
+      redirect ip_addresses_url
+    end
+  end
+
+end
diff --git a/server/views/instances/new.html.haml b/server/views/instances/new.html.haml
index 6d67c2d..cf79146 100644
--- a/server/views/instances/new.html.haml
+++ b/server/views/instances/new.html.haml
@@ -14,6 +14,12 @@
       %label
         Instance Keyname:
         %input{:name => 'keyname', :size => 30 }
+  -if driver_has_feature?(:assign_ip_address)
+    %p
+      %label
+        Instance IP address:
+        %select{:name => 'ip_address_id'}
+          %option Loading...
   - if !@hardware_profiles.empty?
     %h3 What size machine?
     - for hwp in @hardware_profiles
diff --git a/server/views/ip_addresses/index.html.haml b/server/views/ip_addresses/index.html.haml
new file mode 100644
index 0000000..b0a430b
--- /dev/null
+++ b/server/views/ip_addresses/index.html.haml
@@ -0,0 +1,27 @@
+%h1 IP Addresses
+
+%table.display
+  %thead
+    %tr
+      %th ID
+      %th IP Address
+      %th Type
+      %th State
+      %th Realm
+  %tbody
+    - @elements.each do |ip|
+      %tr
+        %td
+          =link_to ip.id, ip_address_url( ip.id )
+        %td
+          =ip.address
+        %td
+          =ip.type
+        %td
+          =ip.state
+        %td
+          =link_to ip.realm_id, realm_url(ip.realm_id)
+  %tfoot
+    %tr
+      %td{:colspan => 5, :style => "text-align:right;"}
+        =link_to 'Create &raquo;', create_ip_address_url, :class => 'post'
diff --git a/server/views/ip_addresses/index.xml.haml b/server/views/ip_addresses/index.xml.haml
new file mode 100644
index 0000000..2f4752c
--- /dev/null
+++ b/server/views/ip_addresses/index.xml.haml
@@ -0,0 +1,4 @@
+!!!XML
+%ip_addresses
+  - @elements.each do |c|
+    = haml :'ip_addresses/show', :locals => { :@ip_address => c, :partial => true }
diff --git a/server/views/ip_addresses/show.html.haml b/server/views/ip_addresses/show.html.haml
new file mode 100644
index 0000000..76d3722
--- /dev/null
+++ b/server/views/ip_addresses/show.html.haml
@@ -0,0 +1,23 @@
+%h1
+  = @ip_address.id
+
+%dl
+  %di
+    %dt ID
+    %dd
+      = @ip_address.id
+    %dt Address
+    %dd
+      = @ip_address.address
+    %dt State
+    %dd
+      = @ip_address.state
+    %dt IP Type
+    %dd
+      = @ip_address.type
+    %dt Realm
+    %dd
+      = link_to driver.realm(credentials, @ip_address.realm_id).name, realm_url(@ip_address.realm_id)
+    %dt
+    %dd
+      = link_to 'Destroy', destroy_ip_address_url(@ip_address.id), :class => 'delete'
diff --git a/server/views/ip_addresses/show.xml.haml b/server/views/ip_addresses/show.xml.haml
new file mode 100644
index 0000000..e49493f
--- /dev/null
+++ b/server/views/ip_addresses/show.xml.haml
@@ -0,0 +1,10 @@
+- unless defined?(partial)
+  !!! XML
+%ip_address{ :href => ip_address_url(@ip_address.id), :id => @ip_address.id, :type => "#{@ip_address.type}" }
+  %address<
+    =@ip_address.address
+  %state<
+    =@ip_address.state
+  %realm{:href => realm_url(@ip_address.realm_id), :id => @ip_address.realm_id}
+  %actions
+    %link{ :rel => "destroy", :method => "delete", :href => destroy_ip_address_url(@ip_address.id)}
diff --git a/server/views/realms/index.html.haml b/server/views/realms/index.html.haml
index cfee320..ea4cf85 100644
--- a/server/views/realms/index.html.haml
+++ b/server/views/realms/index.html.haml
@@ -5,9 +5,9 @@
   %thead
     %tr
       %th
-        Name
+        ID
       %th
-        Architecture
+        Name
       %th
         Memory
       %th
-- 
1.7.2.2