From: Michal Fojtik <[email protected]>
---
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
+ %[email protected]
+ %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