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/25 16:42:27 UTC

[PATCH core 3/6] Added initial IP managment for GoGrid

---
 server/deltacloud.rb                               |    1 +
 server/lib/deltacloud/base_driver/base_driver.rb   |    4 ++
 .../lib/deltacloud/drivers/gogrid/gogrid_driver.rb |   36 ++++++++++++++++++-
 .../lib/deltacloud/helpers/application_helper.rb   |    1 +
 server/lib/deltacloud/helpers/conversion_helper.rb |    2 +-
 server/lib/deltacloud/models/ip_address.rb         |   26 +++++++++++++
 server/server.rb                                   |   38 ++++++++++++++++++++
 server/views/ip_addresses/index.html.haml          |   23 ++++++++++++
 server/views/ip_addresses/show.html.haml           |   20 ++++++++++
 9 files changed, 149 insertions(+), 2 deletions(-)
 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/show.html.haml

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/drivers/gogrid/gogrid_driver.rb b/server/lib/deltacloud/drivers/gogrid/gogrid_driver.rb
index e6c99c5..8cb0137 100644
--- a/server/lib/deltacloud/drivers/gogrid/gogrid_driver.rb
+++ b/server/lib/deltacloud/drivers/gogrid/gogrid_driver.rb
@@ -45,7 +45,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)
@@ -192,6 +192,31 @@ 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
+    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 +230,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/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/ip_addresses/index.html.haml b/server/views/ip_addresses/index.html.haml
new file mode 100644
index 0000000..a0e0fe8
--- /dev/null
+++ b/server/views/ip_addresses/index.html.haml
@@ -0,0 +1,23 @@
+%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)
diff --git a/server/views/ip_addresses/show.html.haml b/server/views/ip_addresses/show.html.haml
new file mode 100644
index 0000000..1a66514
--- /dev/null
+++ b/server/views/ip_addresses/show.html.haml
@@ -0,0 +1,20 @@
+%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)
-- 
1.7.2


Re: [PATCH core 3/6] Added initial IP managment for GoGrid

Posted by Michal Fojtik <mf...@redhat.com>.
On 26/08/10 16:38 -0700, David Lutterkort wrote:
>On Wed, 2010-08-25 at 16:42 +0200, mfojtik@redhat.com wrote:
>> ---
>>  server/deltacloud.rb                               |    1 +
>>  server/lib/deltacloud/base_driver/base_driver.rb   |    4 ++
>>  .../lib/deltacloud/drivers/gogrid/gogrid_driver.rb |   36 ++++++++++++++++++-
>>  .../lib/deltacloud/helpers/application_helper.rb   |    1 +
>>  server/lib/deltacloud/helpers/conversion_helper.rb |    2 +-
>>  server/lib/deltacloud/models/ip_address.rb         |   26 +++++++++++++
>>  server/server.rb                                   |   38 ++++++++++++++++++++
>>  server/views/ip_addresses/index.html.haml          |   23 ++++++++++++
>>  server/views/ip_addresses/show.html.haml           |   20 ++++++++++
>>  9 files changed, 149 insertions(+), 2 deletions(-)
>>  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/show.html.haml
>
>Couple of comments:
>
>> diff --git a/server/lib/deltacloud/drivers/gogrid/gogrid_driver.rb b/server/lib/deltacloud/drivers/gogrid/gogrid_driver.rb
>> index e6c99c5..8cb0137 100644
>> --- a/server/lib/deltacloud/drivers/gogrid/gogrid_driver.rb
>> +++ b/server/lib/deltacloud/drivers/gogrid/gogrid_driver.rb
>> @@ -192,6 +192,31 @@ 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
>> +    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
>
>On the one hand, I like sending back a 501 to indicate that the driver
>does not support this operation. But I think it's not enough: so far,
>we've been very careful to make sure that clients can discover which
>calls are possible before they actually make them.

Yes, you are right. This could a more complicated problem. Right now we
have mechanism for reporting supported collections but we doesn't have
any mechanism to expose supported operations.

One approach could be using http HEAD method to check if specific
operation is available for collection/resource.

Sinatra already support 'head /' so we can integrate this into Rabbit
and then return 'Allow' header for operations, like:

"HEAD /api/ip_addresses => Response: Allow: HEAD, GET" for those providers
who doesn't support create (POST) or destroy (DELETE) and
"HEAD /api/ip_addresses => Response: Allow: HEAD, GET, POST, DELETE" for
those who does.

What do you think ?

>How will this shake out for, e.g, the Ruby client ? A web UI that uses
>the ruby client should at least be able to decide whether to show a
>'Create IP Address' dialog to the user before it actually makes any
>calls into the ip_addresses collection.

We can include support for HEAD request into client and then report if
specific operation is available or not.

>> +  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
>
>The messages have some typos: they should be "GoGrid does not support
>creating new IP addresses" and "GoGrid does not support destroying IP
>addresses".

Thanks, I'll fix this in next patch.

>David
>
>

-- 
--------------------------------------------------------
Michal Fojtik, mfojtik@redhat.com, +420 532 294 4307
Ruby / Ruby On Rails Developer
Deltacloud API: http://deltacloud.org
--------------------------------------------------------

Re: [PATCH core 3/6] Added initial IP managment for GoGrid

Posted by David Lutterkort <lu...@redhat.com>.
On Wed, 2010-08-25 at 16:42 +0200, mfojtik@redhat.com wrote:
> ---
>  server/deltacloud.rb                               |    1 +
>  server/lib/deltacloud/base_driver/base_driver.rb   |    4 ++
>  .../lib/deltacloud/drivers/gogrid/gogrid_driver.rb |   36 ++++++++++++++++++-
>  .../lib/deltacloud/helpers/application_helper.rb   |    1 +
>  server/lib/deltacloud/helpers/conversion_helper.rb |    2 +-
>  server/lib/deltacloud/models/ip_address.rb         |   26 +++++++++++++
>  server/server.rb                                   |   38 ++++++++++++++++++++
>  server/views/ip_addresses/index.html.haml          |   23 ++++++++++++
>  server/views/ip_addresses/show.html.haml           |   20 ++++++++++
>  9 files changed, 149 insertions(+), 2 deletions(-)
>  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/show.html.haml

Couple of comments:

> diff --git a/server/lib/deltacloud/drivers/gogrid/gogrid_driver.rb b/server/lib/deltacloud/drivers/gogrid/gogrid_driver.rb
> index e6c99c5..8cb0137 100644
> --- a/server/lib/deltacloud/drivers/gogrid/gogrid_driver.rb
> +++ b/server/lib/deltacloud/drivers/gogrid/gogrid_driver.rb
> @@ -192,6 +192,31 @@ 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
> +    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

On the one hand, I like sending back a 501 to indicate that the driver
does not support this operation. But I think it's not enough: so far,
we've been very careful to make sure that clients can discover which
calls are possible before they actually make them.

How will this shake out for, e.g, the Ruby client ? A web UI that uses
the ruby client should at least be able to decide whether to show a
'Create IP Address' dialog to the user before it actually makes any
calls into the ip_addresses collection.

So, we need some metadata for the top-level entrypoint to indicate at
the least whether create is allowed or not.

Destroy is easier since it operates on an existing object, and we can
therefore handle that by conditionally including a destroy action in the
details for each address. That has the advantage that the client needs
to _only_ look at the possible actions for the IP address - it's
conceivable that a cloud might support destroying addresses in general,
but the current user doesn't have permissions to do that. Looks the same
from the user's POV.

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

The messages have some typos: they should be "GoGrid does not support
creating new IP addresses" and "GoGrid does not support destroying IP
addresses".

David