deltacloud-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From mfoj...@redhat.com
Subject [PATCH core] Added basic IP address managment support (for EC2)
Date Mon, 02 May 2011 11:40:56 GMT
From: Michal Fojtik <mfojtik@redhat.com>

---
 server/deltacloud.rb                            |    1 +
 server/lib/deltacloud/core_ext/string.rb        |    2 +
 server/lib/deltacloud/drivers/ec2/ec2_driver.rb |   52 +++++++++++++-
 server/lib/deltacloud/models/address.rb         |   28 +++++++
 server/server.rb                                |   86 +++++++++++++++++++++++
 server/views/addresses/associate.html.haml      |    8 ++
 server/views/addresses/index.html.haml          |   28 +++++++
 server/views/addresses/index.xml.haml           |    4 +
 server/views/addresses/show.html.haml           |   22 ++++++
 server/views/addresses/show.xml.haml            |   12 +++
 10 files changed, 242 insertions(+), 1 deletions(-)
 create mode 100644 server/lib/deltacloud/models/address.rb
 create mode 100644 server/views/addresses/associate.html.haml
 create mode 100644 server/views/addresses/index.html.haml
 create mode 100644 server/views/addresses/index.xml.haml
 create mode 100644 server/views/addresses/show.html.haml
 create mode 100644 server/views/addresses/show.xml.haml

diff --git a/server/deltacloud.rb b/server/deltacloud.rb
index 74fcce6..7caf34f 100644
--- a/server/deltacloud.rb
+++ b/server/deltacloud.rb
@@ -29,6 +29,7 @@ require 'deltacloud/models/realm'
 require 'deltacloud/models/image'
 require 'deltacloud/models/instance'
 require 'deltacloud/models/key'
+require 'deltacloud/models/address'
 require 'deltacloud/models/instance_profile'
 require 'deltacloud/models/storage_snapshot'
 require 'deltacloud/models/storage_volume'
diff --git a/server/lib/deltacloud/core_ext/string.rb b/server/lib/deltacloud/core_ext/string.rb
index 71514cb..42fbad0 100644
--- a/server/lib/deltacloud/core_ext/string.rb
+++ b/server/lib/deltacloud/core_ext/string.rb
@@ -33,10 +33,12 @@ class String
   end
 
   def pluralize
+    return self + 'es' if self =~ /ess$/
     self + "s"
   end
 
   def singularize
+    return self.gsub(/es$/, '') if self =~ /sses$/
     self.gsub(/s$/, '')
   end
 
diff --git a/server/lib/deltacloud/drivers/ec2/ec2_driver.rb b/server/lib/deltacloud/drivers/ec2/ec2_driver.rb
index 4b9899a..fc9ab73 100644
--- a/server/lib/deltacloud/drivers/ec2/ec2_driver.rb
+++ b/server/lib/deltacloud/drivers/ec2/ec2_driver.rb
@@ -33,7 +33,7 @@ module Deltacloud
       class EC2Driver < Deltacloud::BaseDriver
 
         def supported_collections
-          DEFAULT_COLLECTIONS + [ :keys, :buckets, :load_balancers ]
+          DEFAULT_COLLECTIONS + [ :keys, :buckets, :load_balancers, :addresses ]
         end
 
         feature :instances, :user_data
@@ -509,6 +509,56 @@ module Deltacloud
           end
         end
 
+        def addresses(credentials, opts={})
+          ec2 = new_client(credentials)
+          address_id = (opts and opts[:id]) ? opts[:id] : []
+          safely do
+            ec2.describe_addresses(address_id).collect do |address|
+              Address.new(:id => address[:public_ip], :instance_id => address[:instance_id])
+            end
+          end
+        end
+
+        def address(credentials, opts={})
+          addresses(credentials, :id => opts[:id]).first
+        end
+
+        def create_address(credentials, opts={})
+          ec2 = new_client(credentials)
+          safely do
+            Address.new(:id => ec2.allocate_address)
+          end
+        end
+
+        def destroy_address(credentials, opts={})
+          ec2 = new_client(credentials)
+          safely do
+            ec2.release_address(opts[:id])
+          end
+        end
+
+        def associate_address(credentials, opts={})
+          ec2 = new_client(credentials)
+          safely do
+            if ec2.associate_address(opts[:instance_id], opts[:id])
+              Address.new(:id => opts[:id], :instance_id => opts[:instance_id])
+            else
+              raise "ERROR: Cannot associate IP address to an Instance"
+            end
+          end
+        end
+
+        def disassociate_address(credentials, opts={})
+          ec2 = new_client(credentials)
+          safely do
+            if ec2.disassociate_address(opts[:id])
+              Address.new(:id => opts[:id])
+            else
+              raise "ERROR: Cannot disassociate an IP address from the Instance"
+            end
+          end
+        end
+
         def valid_credentials?(credentials)
           retval = true
           begin
diff --git a/server/lib/deltacloud/models/address.rb b/server/lib/deltacloud/models/address.rb
new file mode 100644
index 0000000..dbabb08
--- /dev/null
+++ b/server/lib/deltacloud/models/address.rb
@@ -0,0 +1,28 @@
+#
+# 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 Address < BaseModel
+  attr_accessor :instance_id
+
+  def initialize(init=nil)
+    super(init)
+  end
+
+  def associated?
+    true unless self.instance_id.nil?
+  end
+
+end
diff --git a/server/server.rb b/server/server.rb
index dcc76e5..344d4bf 100644
--- a/server/server.rb
+++ b/server/server.rb
@@ -858,3 +858,89 @@ collection :buckets do
   end
 
 end
+
+get '/api/addresses/:id/associate' do
+  @instances = driver.instances(credentials)
+  @address = Address::new(:id => params[:id])
+  respond_to do |format|
+    format.html { haml :"addresses/associate" }
+  end
+end
+
+collection :addresses do
+  description "Manage IP addresses"
+
+  operation :index do
+    description "List IP addresses assigned to your account."
+    with_capability :addresses
+    control do
+      filter_all :addresses
+    end
+  end
+
+  operation :show do
+    description "Show details about IP addresses specified by given ID"
+    with_capability :address
+    param :id,  :string,  :required
+    control { show :address }
+  end
+
+  operation :create do
+    description "Acquire a new IP address for use with your account."
+    with_capability :create_address
+    control do
+      @address = driver.create_address(credentials, {})
+      respond_to do |format|
+        format.html { haml :"addresses/show" }
+        format.xml do
+          response.status = 201  # Created
+          haml :"addresses/show", :ugly => true
+        end
+      end
+    end
+  end
+
+  operation :destroy do
+    description "Release an IP address associated with your account"
+    with_capability :destroy_address
+    param :id,  :string,  :required
+    control do
+      driver.destroy_address(credentials, { :id => params[:id]})
+      respond_to do |format|
+        format.xml { 204 }
+        format.json { 204 }
+        format.html { redirect(addresses_url) }
+      end
+    end
+  end
+
+  operation :associate, :method => :post, :member => true do
+    description "Associate an IP address to an instance"
+    with_capability :associate_address
+    param :id, :string, :required
+    param :instance_id, :string, :required
+    control do
+      driver.associate_address(credentials, { :id => params[:id], :instance_id => params[:instance_id]})
+      respond_to do |format|
+        format.xml { 202 }  # Accepted
+        format.json { 202 }
+        format.html { redirect(address_url(params[:id])) }
+      end
+    end
+  end
+
+  operation :disassociate, :method => :post, :member => true do
+    description "Disassociate an IP address from an instance"
+    with_capability :associate_address
+    param :id, :string, :required
+    control do
+      driver.disassociate_address(credentials, { :id => params[:id] })
+      respond_to do |format|
+        format.xml { 202 }  # Accepted
+        format.json { 202 }
+        format.html { redirect(address_url(params[:id])) }
+      end
+    end
+  end
+
+end
diff --git a/server/views/addresses/associate.html.haml b/server/views/addresses/associate.html.haml
new file mode 100644
index 0000000..9d1a92d
--- /dev/null
+++ b/server/views/addresses/associate.html.haml
@@ -0,0 +1,8 @@
+%h1 Associate #{@address.id} to an instance
+
+%form{ :action => associate_address_url(@address.id), :method => :post, :class =>
:new_instance }
+  %select{:name => 'instance_id'}
+    %option
+    - @instances.each do |inst|
+      %option{ :value => inst.id } #{inst.id} - #{inst.name}
+    %input{ :type => :submit, :name => "commit", :value => "Associate" }/
diff --git a/server/views/addresses/index.html.haml b/server/views/addresses/index.html.haml
new file mode 100644
index 0000000..acc1bb6
--- /dev/null
+++ b/server/views/addresses/index.html.haml
@@ -0,0 +1,28 @@
+%h1 Addresses
+
+%table.display
+  %thead
+    %tr
+      %th ID
+      %th Instance
+      %th Actions
+  %tbody
+    - @elements.each do |address|
+      %tr
+        %td
+          = link_to address.id, address_url( address.id )
+        %td
+          - if address.instance_id
+            = link_to address.instance_id, instance_url( address.instance_id )
+        %td
+          - if driver.respond_to?(:destroy_address)
+            =link_to_action 'Destroy', destroy_address_url(address.id), :delete
+          - if driver.respond_to?(:associate_address) and not address.associated?
+            =link_to_action 'Associate', associate_address_url(address.id), :get
+          - if driver.respond_to?(:disassociate_address)
+            =link_to_action 'Disassociate', disassociate_address_url(address.id), :post
+  %tfoot
+    - if driver.respond_to?(:create_address)
+      %tr
+        %td{:colspan => 3, :style => "text-align:right;"}
+          =link_to_action "Create", create_address_url, :post
diff --git a/server/views/addresses/index.xml.haml b/server/views/addresses/index.xml.haml
new file mode 100644
index 0000000..e2a564f
--- /dev/null
+++ b/server/views/addresses/index.xml.haml
@@ -0,0 +1,4 @@
+!!!XML
+%addresses
+  - @elements.each do |c|
+    = haml :'address/show', :locals => { :@address => c, :partial => true }
diff --git a/server/views/addresses/show.html.haml b/server/views/addresses/show.html.haml
new file mode 100644
index 0000000..105c41a
--- /dev/null
+++ b/server/views/addresses/show.html.haml
@@ -0,0 +1,22 @@
+%h1 Address
+
+%dl
+  %di
+    %dt Address
+    %dd=@address.id
+  %di
+    %dt Instance
+    %dd
+      - if @address.associated?
+        =link_to @address.instance_id, instance_url(@address.instance_id)
+        =link_to_action 'Disassociate', disassociate_address_url(@address.id), :post
+      - else
+        - if driver.respond_to?(:associate_address)
+          =link_to_action 'Associate', associate_address_url(@address.id), :get
+
+  %di
+    %dt Actions
+    %dd
+    - if driver.respond_to?(:destroy_address)
+      =link_to_action 'Destroy', destroy_address_url(@address.id), :delete
+
diff --git a/server/views/addresses/show.xml.haml b/server/views/addresses/show.xml.haml
new file mode 100644
index 0000000..a450690
--- /dev/null
+++ b/server/views/addresses/show.xml.haml
@@ -0,0 +1,12 @@
+- unless defined?(partial)
+  !!! XML
+%address{ :href => address_url(@address.id), :id => @address.id }
+  %actions
+    - if driver.respond_to?(:destroy_address)
+      %link{ :rel => "destroy", :method => "delete", :href => destroy_address_url(@address.id)}
+    - if driver.respond_to?(:associate_address) and not @address.instance_id
+      %link{ :rel => "associate", :method => "post", :href => associate_address_url(@address.id)}
+    - if driver.respond_to?(:disassociate_address) and @address.instance_id
+      %link{ :rel => "disassociate", :method => "post", :href => disassociate_address_url(@address.id)}
+  - if @address.instance_id
+    %instance{ :href => instance_url(@address.instance_id), :id => @address.instance_id}
-- 
1.7.4.1


Mime
View raw message