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 2012/05/15 14:50:02 UTC

[PATCH core 1/5] Core: Added rake task for running 'api' tests (rake test:api)

From: Michal Fojtik <mf...@redhat.com>


Signed-off-by: Michal fojtik <mf...@redhat.com>
---
 server/views/instances/show.xml.haml |   11 ++++++-----
 1 file changed, 6 insertions(+), 5 deletions(-)

diff --git a/server/views/instances/show.xml.haml b/server/views/instances/show.xml.haml
index a0ae4b2..24c10b5 100644
--- a/server/views/instances/show.xml.haml
+++ b/server/views/instances/show.xml.haml
@@ -41,11 +41,12 @@
     %firewalls<
       - @instance.firewalls.each do |firewall|
         %firewall{:href => firewall_url(firewall), :id => firewall }
-  %storage_volumes<
-    - @instance.storage_volumes.each do |volume|
-      %storage_volume{:href=> storage_volume_url(volume.keys.first), :id => volume.keys.first, :device => volume.values.first}
-  - if driver.class.has_feature?(:instances, :authentication_key) or driver.class.has_feature?(:instances, :authentication_password)
-    %authentication{ :type => auth_feature_name }
+  - if @instance.storage_volumes
+    %storage_volumes<
+      - @instance.storage_volumes.each do |volume|
+        %storage_volume{:href=> storage_volume_url(volume.keys.first), :id => volume.keys.first, :device => volume.values.first}
+  - if driver.class.has_feature?(:keys, :authentication_key) or driver.class.has_feature?(:keys, :authentication_password)
+    %authentication{ :type => driver_auth_feature_name }
       - if @instance.authn_feature_failed?
         %error  #{@instance.authn_error}
       - else
-- 
1.7.10.1


[PATCH core 2/5] EC2: Added initial support for EC2 frontend

Posted by mf...@redhat.com.
From: Michal Fojtik <mf...@redhat.com>


Signed-off-by: Michal fojtik <mf...@redhat.com>
---
 server/bin/deltacloudd              |    4 +-
 server/config.ru                    |    4 +
 server/lib/ec2/helpers.rb           |   29 ++++++++
 server/lib/ec2/helpers/converter.rb |  140 +++++++++++++++++++++++++++++++++++
 server/lib/ec2/helpers/errors.rb    |   46 ++++++++++++
 server/lib/ec2/query_parser.rb      |  129 ++++++++++++++++++++++++++++++++
 server/lib/ec2/server.rb            |   59 +++++++++++++++
 7 files changed, 409 insertions(+), 2 deletions(-)
 create mode 100644 server/lib/ec2/helpers.rb
 create mode 100644 server/lib/ec2/helpers/converter.rb
 create mode 100644 server/lib/ec2/helpers/errors.rb
 create mode 100644 server/lib/ec2/query_parser.rb
 create mode 100644 server/lib/ec2/server.rb

diff --git a/server/bin/deltacloudd b/server/bin/deltacloudd
index 57b6c49..8eb448d 100755
--- a/server/bin/deltacloudd
+++ b/server/bin/deltacloudd
@@ -61,8 +61,8 @@ BANNER
   opts.on( '-P', '--provider PROVIDER', 'Use PROVIDER (default is set in the driver)') do |provider|
     ENV['API_PROVIDER'] = provider
   end
-  opts.on('--cimi', 'USe the DMTF CIMI frontend, not the Deltacloud frontend') do
-    ENV['API_FRONTEND'] = 'cimi'
+  opts.on('-f', '--frontend FRONTEND', 'Use the different frontend, not the Deltacloud (cimi or ec2)') do |frontend|
+    ENV['API_FRONTEND'] = frontend
   end
   opts.on( '-c', '--config [FILE]', 'Read provider and other config from FILE (default: ~/.deltacloud/config)') do |config|
     options[:config] = File::expand_path(config || DEFAULT_CONFIG)
diff --git a/server/config.ru b/server/config.ru
index 2280d0e..5deff47 100644
--- a/server/config.ru
+++ b/server/config.ru
@@ -30,6 +30,9 @@ if ENV['API_FRONTEND'] == 'deltacloud'
 elsif ENV['API_FRONTEND'] == 'cimi'
   API_VERSION = "1.0.0"
   API_ROOT_URL = "/cloudEntryPoint"
+elsif ENV['API_FRONTEND'] == 'ec2'
+  API_VERSION = "0.1"
+  API_ROOT_URL = "/"
 end
 
 require File.join(File.dirname(__FILE__), 'lib', ENV['API_FRONTEND'], 'server.rb')
@@ -37,6 +40,7 @@ require File.join(File.dirname(__FILE__), 'lib', ENV['API_FRONTEND'], 'server.rb
 frontend_klass = case ENV['API_FRONTEND']
   when 'deltacloud' then Deltacloud::API
   when 'cimi' then CIMI::API
+  when 'ec2' then Deltacloud::EC2::API
 end
 
 class IndexEntrypoint < Sinatra::Base
diff --git a/server/lib/ec2/helpers.rb b/server/lib/ec2/helpers.rb
new file mode 100644
index 0000000..32380fa
--- /dev/null
+++ b/server/lib/ec2/helpers.rb
@@ -0,0 +1,29 @@
+# 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.
+
+module Deltacloud
+  module EC2; end
+end
+
+require_relative './helpers/errors'
+require_relative './helpers/convertor'
+
+require_relative '../deltacloud/helpers/driver_helper'
+require_relative '../deltacloud/helpers/auth_helper'
+require_relative '../deltacloud/core_ext/string'
+require_relative '../deltacloud/core_ext/array'
+require_relative '../deltacloud/core_ext/hash'
+require_relative '../deltacloud/core_ext/integer'
+require_relative '../deltacloud/core_ext/proc'
diff --git a/server/lib/ec2/helpers/converter.rb b/server/lib/ec2/helpers/converter.rb
new file mode 100644
index 0000000..8a70fe1
--- /dev/null
+++ b/server/lib/ec2/helpers/converter.rb
@@ -0,0 +1,140 @@
+# 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.
+
+module Deltacloud::EC2
+
+  class Converter
+
+    def self.convert(builder, action, result)
+      klass_name = ActionHandler::MAPPINGS[action][:method].to_s.camelize
+      klass = Converter.const_get(klass_name)
+      klass.new(builder, result).to_xml
+    end
+
+    class Base
+
+      attr_reader :xml
+      attr_reader :obj
+
+      def initialize(builder, object)
+        @xml = builder
+        @obj = object
+      end
+
+    end
+
+    class Realms < Base
+
+      def to_xml
+        xml.availabilityZoneInfo {
+          obj.each do |item|
+            xml.item {
+              xml.zoneName item.id
+              xml.zoneState item.state
+              xml.regionName item.name
+            }
+          end
+        }
+      end
+
+    end
+
+    class Images < Base
+
+      def to_xml
+        xml.imagesSet {
+          obj.each do |item|
+            xml.item {
+              xml.imageId item.id
+              xml.imageState item.state.downcase
+              xml.imageOwnerId item.owner_id
+              xml.architecture item.architecture
+              xml.imageType 'machine'
+              xml.name item.name
+              xml.description item.description
+            }
+          end
+        }
+      end
+
+    end
+
+    class CreateInstance < Base
+
+      def to_xml
+        xml.reservationId 'r-11111111'
+        xml.ownerId @obj.owner_id
+        xml.groupSet {
+          xml.item {
+            xml.groupId 'sg-11111111'
+            xml.groupName 'default'
+          }
+        }
+        Instances.new(@xml, [@obj]).instance_set
+      end
+
+    end
+
+    class Instances < Base
+
+      def instance_set
+        xml.instancesSet {
+          obj.each do |item|
+            xml.item {
+              xml.instanceId item.id
+              xml.imageId item.image_id
+              xml.instanceType item.instance_profile.name
+              xml.launchTime item.launch_time
+              xml.ipAddress item.public_addresses.first.address
+              xml.privateIpAddress item.public_addresses.first.address
+              xml.dnsName item.public_addresses.first.address
+              xml.privateDnsName item.private_addresses.first.address
+              xml.architecture item.instance_profile.architecture
+              xml.keyName item.keyname
+              xml.instanceState {
+                xml.code '16'
+                xml.name item.state.downcase
+              }
+              xml.placement {
+                xml.availabilityZone item.realm_id
+                xml.groupName
+                xml.tenancy 'default'
+              }
+            }
+          end
+        }
+      end
+
+      def to_xml
+        xml.reservationSet {
+          xml.item {
+            xml.reservationId 'r-11111111'
+            xml.ownerId 'deltacloud'
+            xml.groupSet {
+              xml.item {
+                xml.groupId 'sg-11111111'
+                xml.groupName 'default'
+              }
+            }
+            self.instance_set
+          }
+        }
+      end
+
+    end
+
+  end
+
+end
diff --git a/server/lib/ec2/helpers/errors.rb b/server/lib/ec2/helpers/errors.rb
new file mode 100644
index 0000000..7f8d610
--- /dev/null
+++ b/server/lib/ec2/helpers/errors.rb
@@ -0,0 +1,46 @@
+# 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.
+
+module Deltacloud::EC2
+  module Errors
+
+    def report_error(code)
+      error = (request.env['sinatra.error'] || @exception)
+      code = 500 if not code and not error.class.method_defined? :code
+      Nokogiri::XML::Builder.new do |xml|
+        xml.send(:Response) {
+          xml.send(:Errors) {
+            xml.send(:Code, error_for_code(code))
+            xml.send(:Message, error.respond_to?(:message) ? error.message : '')
+          }
+          xml.send(:RequestID, request_id)
+        }
+      end.to_xml
+    end
+
+    def request_id
+      Digest::MD5.hexdigest("#{request.env['REMOTE_ADDR']}#{request.env['HTTP_USER_AGENT']}#{Time.now.to_i}#{rand(250)}")
+    end
+
+    def error_for_code(code)
+      case code
+        when 401 then 'AuthFailure'
+        when 500 then 'InternalError'
+        else "Unavailable (#{code})"
+      end
+    end
+
+  end
+end
diff --git a/server/lib/ec2/query_parser.rb b/server/lib/ec2/query_parser.rb
new file mode 100644
index 0000000..7eebc9a
--- /dev/null
+++ b/server/lib/ec2/query_parser.rb
@@ -0,0 +1,129 @@
+# 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.
+
+module Deltacloud::EC2
+
+  class ActionHandler
+
+    MAPPINGS = {
+      :describe_availability_zones => { :method => :realms, :params => { 'ZoneName.1' => :id } },
+      :describe_images => { :method => :images, :params => { 'ImageId.1' => :id }},
+      :describe_instances => { :method => :instances, :params => {} },
+      :run_instances => { :method => :create_instance, :params => { 'ImageId' => :image_id, 'InstanceType' => :hwp_id, 'Placement.AvailabilityZone' => :realm_id }}
+    }
+
+    attr_reader :action
+
+    def initialize(action)
+      @action = action
+    end
+
+    def deltacloud_method
+      MAPPINGS[action.action][:method]
+    end
+
+    def deltacloud_method_params
+      MAPPINGS[action.action][:params].inject({}) do |result, p|
+        result[p.last] = action.parameters.delete(p.first)
+        result.delete_if { |k,v| v.nil? }
+      end
+    end
+
+    def perform!(credentials, driver)
+      @result = case deltacloud_method
+        when :create_instance then driver.send(deltacloud_method, credentials, deltacloud_method_params.delete(:image_id), deltacloud_method_params)
+        else driver.send(deltacloud_method, credentials, deltacloud_method_params)
+      end
+    end
+
+    def to_xml
+      ResultParser.parse(action, @result).to_xml
+    end
+
+  end
+
+  class ResultParser
+
+    def self.parse(parser, result)
+      Nokogiri::XML::Builder.new do |xml|
+        xml.send(:"#{parser.action.to_s.camelize}Response", :xmlns => 'http://ec2.amazonaws.com/doc/2012-04-01/') {
+          xml.requestId parser.request_id
+          new(xml, parser, result).build_xml
+        }
+      end
+    end
+
+    def initialize(xml, parser, result)
+      @builder = xml
+      @parser = parser
+      @result = result
+    end
+
+    def build_xml
+      Converter.convert(@builder, @parser.action, @result)
+    end
+
+  end
+
+  class QueryParser
+
+    def self.parse(params, request_id)
+      parser = new(request_id, params)
+      unless parser.valid_action?
+        raise 'Invalid action (%s)' % parser.action
+      else
+        ActionHandler.new(parser)
+      end
+    end
+
+    attr_reader :action
+    attr_reader :parameters
+    attr_reader :version
+    attr_reader :expiration
+    attr_reader :authentication
+    attr_reader :request_id
+
+    def initialize(request_id, params={})
+      @request_id = request_id
+      @action = (params.delete('Action') || 'Unknown').underscore.intern
+      @version = params.delete('Version')
+      @authentication = {
+        :security_token => params.delete('SecurityToken'),
+        :access_key_id => params.delete('AWSAccessKeyId'),
+        :signature => {
+          :version => params.delete('SignatureVersion'),
+          :value => params.delete('Signature'),
+          :method => params.delete('SignatureMethod'),
+          :timestamp => params.delete('Timestamp')
+        }
+      }
+      @expiration = params.delete('Expires')
+      @parameters = params
+    end
+
+    def valid_actions
+      ActionHandler::MAPPINGS.keys
+    end
+
+    def valid_action?
+      return false if @action == :unknown
+      return false unless valid_actions.include?(@action)
+      true
+    end
+
+
+  end
+
+end
diff --git a/server/lib/ec2/server.rb b/server/lib/ec2/server.rb
new file mode 100644
index 0000000..6586f16
--- /dev/null
+++ b/server/lib/ec2/server.rb
@@ -0,0 +1,59 @@
+# 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.
+
+require 'rubygems'
+require 'nokogiri'
+require 'sinatra/base'
+
+require_relative '../sinatra'
+require_relative './helpers'
+require_relative './query_parser'
+require_relative '../deltacloud/models'
+require_relative '../deltacloud/drivers'
+
+module Deltacloud::EC2
+  class API < Sinatra::Base
+
+    extend Deltacloud::Helpers::Drivers
+
+    use Rack::ETag
+    use Rack::CommonLogger
+
+    helpers Sinatra::AuthHelper
+    helpers Deltacloud::Helpers::Drivers
+    helpers Deltacloud::EC2::Errors
+
+    enable :xhtml
+    enable :dump_errors
+    enable :show_errors
+    enable :method_override
+    disable :show_exceptions
+
+    set :version, API_VERSION
+    set :root_url, API_ROOT_URL
+    set :root, File.join(File.dirname(__FILE__), '..', '..')
+
+    after do
+      headers 'Server' => 'Apache-Deltacloud-EC2/' + settings.version
+    end
+
+    get '/', :provides => :xml do
+      ec2_action = QueryParser.parse(params, request_id)
+      ec2_action.perform!(credentials, driver)
+      ec2_action.to_xml
+    end
+
+  end
+end
-- 
1.7.10.1


[PATCH core 3/5] Core: Fix incompatibility between 1.9 and 1.8 ruby in listing methods

Posted by mf...@redhat.com.
From: Michal Fojtik <mf...@redhat.com>


Signed-off-by: Michal fojtik <mf...@redhat.com>
---
 server/lib/deltacloud/drivers/base_driver.rb |   14 ++++++--------
 1 file changed, 6 insertions(+), 8 deletions(-)

diff --git a/server/lib/deltacloud/drivers/base_driver.rb b/server/lib/deltacloud/drivers/base_driver.rb
index ab8fb1a..a100828 100644
--- a/server/lib/deltacloud/drivers/base_driver.rb
+++ b/server/lib/deltacloud/drivers/base_driver.rb
@@ -104,16 +104,13 @@ module Deltacloud
       hwp = nil
       if name
         unless hwp = hardware_profiles(credentials, :id => name).first
-          raise BackendError.new(400, "bad-hardware-profile-name",
-            "Hardware profile '#{name}' does not exist", nil)
+          raise BackendError.new(StandardError.new, "Hardware profile '#{name}' does not exist")
         end
       else
-        unless image = image(credentials, :id=>image_id)
-          raise BackendError.new(400, "bad-image-id",
-              "Image with ID '#{image_id}' does not exist", nil)
+        unless image = image(credentials, :id => image_id)
+          raise BackendError.new(StandardError.new, "Image with ID '#{image_id}' does not exist")
         end
-        hwp = hardware_profiles(credentials,
-                                :architecture=>image.architecture).first
+        hwp = hardware_profiles(credentials, :architecture=>image.architecture).first
       end
       return hwp
     end
@@ -144,7 +141,8 @@ module Deltacloud
     end
 
     def has_capability?(method)
-      (self.class.instance_methods - self.class.superclass.instance_methods).include? method.to_s
+      method = RUBY_VERSION =~ /^1\.9/ ? method : method.to_s
+      (self.class.instance_methods - self.class.superclass.instance_methods).include? method
     end
 
     ## Capabilities
-- 
1.7.10.1


Re: Testing this patchset

Posted by Michal Fojtik <mf...@redhat.com>.
On 05/15/12, mfojtik@redhat.com wrote:

Hi guys,

I just uploaded this patchset to Github for more cleaner testing and
understanding what it is doing. Since this patches apply against the
modular branch, it might be hard to get that proper GIT setup to test it
out.

To do it just checkout this branch:

https://github.com/mifo/deltacloud/tree/ec2_frontend

Then start the EC2 frontend with:

$ ./bin/deltacloud -i mock -f ec2

And you can start using DC with EC2 Query API ;-)

  -- Michal

-- 
Michal Fojtik
Sr. Software Engineer, Deltacloud API (http://deltacloud.org)

[PATCH core 4/5] Core: Require core_ext in config.ru

Posted by mf...@redhat.com.
From: Michal Fojtik <mf...@redhat.com>


Signed-off-by: Michal fojtik <mf...@redhat.com>
---
 server/config.ru                  |    3 +--
 server/lib/cimi/helpers.rb        |    5 -----
 server/lib/deltacloud/core_ext.rb |   28 ++++++++++++++++++++++++++++
 server/lib/deltacloud/helpers.rb  |    5 -----
 server/lib/ec2/helpers.rb         |    9 ++-------
 5 files changed, 31 insertions(+), 19 deletions(-)
 create mode 100644 server/lib/deltacloud/core_ext.rb

diff --git a/server/config.ru b/server/config.ru
index 5deff47..2b5697d 100644
--- a/server/config.ru
+++ b/server/config.ru
@@ -14,7 +14,7 @@
 # License for the specific language governing permissions and limitations
 # under the License.
 
-# The default URL prefix (where to mount Deltacloud API)
+load './lib/deltacloud/core_ext.rb'
 
 # The default driver is 'mock'
 ENV['API_DRIVER'] ||= 'mock'
@@ -22,7 +22,6 @@ ENV['API_DRIVER'] ||= 'mock'
 # Set the API frontend use ('cimi' or 'deltacloud', default is 'deltacloud')
 ENV['API_FRONTEND'] ||= 'deltacloud'
 
-
 # We need to set different API version and entrypoint location
 if ENV['API_FRONTEND'] == 'deltacloud'
   API_VERSION = "9.9.9"
diff --git a/server/lib/cimi/helpers.rb b/server/lib/cimi/helpers.rb
index 4535c39..a9a4926 100644
--- a/server/lib/cimi/helpers.rb
+++ b/server/lib/cimi/helpers.rb
@@ -25,11 +25,6 @@ require_relative '../deltacloud/helpers/assets_helper'
 require_relative '../deltacloud/helpers/deltacloud_helper'
 require_relative '../deltacloud/helpers/rabbit_helper'
 require_relative '../deltacloud/helpers/rabbit_helper'
-require_relative '../deltacloud/core_ext/string'
-require_relative '../deltacloud/core_ext/array'
-require_relative '../deltacloud/core_ext/hash'
-require_relative '../deltacloud/core_ext/integer'
-require_relative '../deltacloud/core_ext/proc'
 require_relative './helpers/cimi_helper'
 require_relative './models'
 
diff --git a/server/lib/deltacloud/core_ext.rb b/server/lib/deltacloud/core_ext.rb
new file mode 100644
index 0000000..51a882a
--- /dev/null
+++ b/server/lib/deltacloud/core_ext.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.
+
+unless Kernel.respond_to?(:require_relative)
+  module Kernel
+    def require_relative(path)
+      require File.join(File.dirname(caller[0]), path.to_str)
+    end
+  end
+end
+
+require_relative './core_ext/string'
+require_relative './core_ext/array'
+require_relative './core_ext/hash'
+require_relative './core_ext/integer'
+require_relative './core_ext/proc'
diff --git a/server/lib/deltacloud/helpers.rb b/server/lib/deltacloud/helpers.rb
index 8e265fc..bc2ea98 100644
--- a/server/lib/deltacloud/helpers.rb
+++ b/server/lib/deltacloud/helpers.rb
@@ -19,11 +19,6 @@ require_relative 'helpers/url_helper'
 require_relative 'helpers/deltacloud_helper'
 require_relative 'helpers/rabbit_helper'
 require_relative 'helpers/blob_stream_helper'
-require_relative 'core_ext/string'
-require_relative 'core_ext/array'
-require_relative 'core_ext/hash'
-require_relative 'core_ext/integer'
-require_relative 'core_ext/proc'
 
 module Deltacloud::Collections
   class Base < Sinatra::Base
diff --git a/server/lib/ec2/helpers.rb b/server/lib/ec2/helpers.rb
index 32380fa..d73ea47 100644
--- a/server/lib/ec2/helpers.rb
+++ b/server/lib/ec2/helpers.rb
@@ -18,12 +18,7 @@ module Deltacloud
 end
 
 require_relative './helpers/errors'
-require_relative './helpers/convertor'
-
+require_relative './helpers/converter'
 require_relative '../deltacloud/helpers/driver_helper'
 require_relative '../deltacloud/helpers/auth_helper'
-require_relative '../deltacloud/core_ext/string'
-require_relative '../deltacloud/core_ext/array'
-require_relative '../deltacloud/core_ext/hash'
-require_relative '../deltacloud/core_ext/integer'
-require_relative '../deltacloud/core_ext/proc'
+
-- 
1.7.10.1


[PATCH core 5/5] EC2 Frontend: Replaced Nokogiri with HAML views, added more actions

Posted by mf...@redhat.com.
From: Michal Fojtik <mf...@redhat.com>


Signed-off-by: Michal fojtik <mf...@redhat.com>
---
 server/lib/ec2/helpers.rb                          |    3 +-
 server/lib/ec2/helpers/converter.rb                |  140 --------------------
 server/lib/ec2/helpers/result.rb                   |   31 +++++
 server/lib/ec2/query_parser.rb                     |   51 ++++---
 server/lib/ec2/server.rb                           |    4 +-
 server/lib/ec2/views/create_key_pair.haml          |    3 +
 server/lib/ec2/views/delete_key_pair.haml          |    1 +
 .../lib/ec2/views/describe_availability_zones.haml |    6 +
 server/lib/ec2/views/describe_images.haml          |   10 ++
 server/lib/ec2/views/describe_instance_set.haml    |   20 +++
 server/lib/ec2/views/describe_instances.haml       |    9 ++
 server/lib/ec2/views/describe_key_pairs.haml       |    5 +
 server/lib/ec2/views/instance_action.haml          |    9 ++
 server/lib/ec2/views/reboot_instances.haml         |    1 +
 server/lib/ec2/views/run_instances.haml            |    7 +
 server/lib/ec2/views/start_instances.haml          |    1 +
 server/lib/ec2/views/stop_instances.haml           |    1 +
 server/lib/ec2/views/terminate_instances.haml      |    9 ++
 18 files changed, 152 insertions(+), 159 deletions(-)
 delete mode 100644 server/lib/ec2/helpers/converter.rb
 create mode 100644 server/lib/ec2/helpers/result.rb
 create mode 100644 server/lib/ec2/views/create_key_pair.haml
 create mode 100644 server/lib/ec2/views/delete_key_pair.haml
 create mode 100644 server/lib/ec2/views/describe_availability_zones.haml
 create mode 100644 server/lib/ec2/views/describe_images.haml
 create mode 100644 server/lib/ec2/views/describe_instance_set.haml
 create mode 100644 server/lib/ec2/views/describe_instances.haml
 create mode 100644 server/lib/ec2/views/describe_key_pairs.haml
 create mode 100644 server/lib/ec2/views/instance_action.haml
 create mode 100644 server/lib/ec2/views/reboot_instances.haml
 create mode 100644 server/lib/ec2/views/run_instances.haml
 create mode 100644 server/lib/ec2/views/start_instances.haml
 create mode 100644 server/lib/ec2/views/stop_instances.haml
 create mode 100644 server/lib/ec2/views/terminate_instances.haml

diff --git a/server/lib/ec2/helpers.rb b/server/lib/ec2/helpers.rb
index d73ea47..cded974 100644
--- a/server/lib/ec2/helpers.rb
+++ b/server/lib/ec2/helpers.rb
@@ -18,7 +18,6 @@ module Deltacloud
 end
 
 require_relative './helpers/errors'
-require_relative './helpers/converter'
+require_relative './helpers/result'
 require_relative '../deltacloud/helpers/driver_helper'
 require_relative '../deltacloud/helpers/auth_helper'
-
diff --git a/server/lib/ec2/helpers/converter.rb b/server/lib/ec2/helpers/converter.rb
deleted file mode 100644
index 8a70fe1..0000000
--- a/server/lib/ec2/helpers/converter.rb
+++ /dev/null
@@ -1,140 +0,0 @@
-# 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.
-
-module Deltacloud::EC2
-
-  class Converter
-
-    def self.convert(builder, action, result)
-      klass_name = ActionHandler::MAPPINGS[action][:method].to_s.camelize
-      klass = Converter.const_get(klass_name)
-      klass.new(builder, result).to_xml
-    end
-
-    class Base
-
-      attr_reader :xml
-      attr_reader :obj
-
-      def initialize(builder, object)
-        @xml = builder
-        @obj = object
-      end
-
-    end
-
-    class Realms < Base
-
-      def to_xml
-        xml.availabilityZoneInfo {
-          obj.each do |item|
-            xml.item {
-              xml.zoneName item.id
-              xml.zoneState item.state
-              xml.regionName item.name
-            }
-          end
-        }
-      end
-
-    end
-
-    class Images < Base
-
-      def to_xml
-        xml.imagesSet {
-          obj.each do |item|
-            xml.item {
-              xml.imageId item.id
-              xml.imageState item.state.downcase
-              xml.imageOwnerId item.owner_id
-              xml.architecture item.architecture
-              xml.imageType 'machine'
-              xml.name item.name
-              xml.description item.description
-            }
-          end
-        }
-      end
-
-    end
-
-    class CreateInstance < Base
-
-      def to_xml
-        xml.reservationId 'r-11111111'
-        xml.ownerId @obj.owner_id
-        xml.groupSet {
-          xml.item {
-            xml.groupId 'sg-11111111'
-            xml.groupName 'default'
-          }
-        }
-        Instances.new(@xml, [@obj]).instance_set
-      end
-
-    end
-
-    class Instances < Base
-
-      def instance_set
-        xml.instancesSet {
-          obj.each do |item|
-            xml.item {
-              xml.instanceId item.id
-              xml.imageId item.image_id
-              xml.instanceType item.instance_profile.name
-              xml.launchTime item.launch_time
-              xml.ipAddress item.public_addresses.first.address
-              xml.privateIpAddress item.public_addresses.first.address
-              xml.dnsName item.public_addresses.first.address
-              xml.privateDnsName item.private_addresses.first.address
-              xml.architecture item.instance_profile.architecture
-              xml.keyName item.keyname
-              xml.instanceState {
-                xml.code '16'
-                xml.name item.state.downcase
-              }
-              xml.placement {
-                xml.availabilityZone item.realm_id
-                xml.groupName
-                xml.tenancy 'default'
-              }
-            }
-          end
-        }
-      end
-
-      def to_xml
-        xml.reservationSet {
-          xml.item {
-            xml.reservationId 'r-11111111'
-            xml.ownerId 'deltacloud'
-            xml.groupSet {
-              xml.item {
-                xml.groupId 'sg-11111111'
-                xml.groupName 'default'
-              }
-            }
-            self.instance_set
-          }
-        }
-      end
-
-    end
-
-  end
-
-end
diff --git a/server/lib/ec2/helpers/result.rb b/server/lib/ec2/helpers/result.rb
new file mode 100644
index 0000000..0fea9c2
--- /dev/null
+++ b/server/lib/ec2/helpers/result.rb
@@ -0,0 +1,31 @@
+# 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.
+
+module Deltacloud::EC2
+  module ResultHelper
+
+    def instance_state_code(state)
+      case state
+        when 'running' then '16'
+        when 'pending' then '0'
+        when 'stopping' then '64'
+        when 'stopped' then '80'
+        when 'shutting-down' then '32'
+        else '-1'
+      end
+    end
+
+  end
+end
diff --git a/server/lib/ec2/query_parser.rb b/server/lib/ec2/query_parser.rb
index 7eebc9a..8d2abc9 100644
--- a/server/lib/ec2/query_parser.rb
+++ b/server/lib/ec2/query_parser.rb
@@ -21,7 +21,14 @@ module Deltacloud::EC2
       :describe_availability_zones => { :method => :realms, :params => { 'ZoneName.1' => :id } },
       :describe_images => { :method => :images, :params => { 'ImageId.1' => :id }},
       :describe_instances => { :method => :instances, :params => {} },
-      :run_instances => { :method => :create_instance, :params => { 'ImageId' => :image_id, 'InstanceType' => :hwp_id, 'Placement.AvailabilityZone' => :realm_id }}
+      :describe_key_pairs => { :method => :keys, :params => {} },
+      :create_key_pair => { :method => :create_key, :params => { 'KeyName' => :key_name }},
+      :delete_key_pair => { :method => :destroy_key, :params => { 'KeyName' => :id }},
+      :run_instances => { :method => :create_instance, :params => { 'ImageId' => :image_id, 'InstanceType' => :hwp_id, 'Placement.AvailabilityZone' => :realm_id }},
+      :stop_instances => { :method => :stop_instance, :params => { 'InstanceId.1' => :id }},
+      :start_instances => { :method => :start_instance, :params => { 'InstanceId.1' => :id }},
+      :reboot_instances => { :method => :reboot_instance, :params => { 'InstanceId.1' => :id }},
+      :terminate_instances => { :method => :destroy_instance, :params => { 'InstanceId.1' => :id }},
     }
 
     attr_reader :action
@@ -44,35 +51,49 @@ module Deltacloud::EC2
     def perform!(credentials, driver)
       @result = case deltacloud_method
         when :create_instance then driver.send(deltacloud_method, credentials, deltacloud_method_params.delete(:image_id), deltacloud_method_params)
+        when :stop_instance then driver.send(deltacloud_method, credentials, deltacloud_method_params.delete(:id))
+        when :start_instance then driver.send(deltacloud_method, credentials, deltacloud_method_params.delete(:id))
+        when :destroy_instance then driver.send(deltacloud_method, credentials, deltacloud_method_params.delete(:id))
+        when :reboot_instance then driver.send(deltacloud_method, credentials, deltacloud_method_params.delete(:id))
         else driver.send(deltacloud_method, credentials, deltacloud_method_params)
       end
     end
 
-    def to_xml
-      ResultParser.parse(action, @result).to_xml
+    def to_xml(context)
+      ResultParser.parse(action, @result, context)
     end
 
   end
 
   class ResultParser
 
-    def self.parse(parser, result)
-      Nokogiri::XML::Builder.new do |xml|
-        xml.send(:"#{parser.action.to_s.camelize}Response", :xmlns => 'http://ec2.amazonaws.com/doc/2012-04-01/') {
-          xml.requestId parser.request_id
-          new(xml, parser, result).build_xml
-        }
-      end
+    include ResultHelper
+
+    attr_reader :query
+    attr_reader :object
+    attr_reader :context
+
+    def self.parse(query, result, context)
+      parser = new(query, result, context)
+      layout = "%#{query.action.to_s.camelize}Response{:xmlns => 'http://ec2.amazonaws.com/doc/2012-04-01/'}\n"+
+        "\t%requestId #{query.request_id}\n" +
+        "\t=render(:#{query.action}, object)\n"
+      Haml::Engine.new(layout, :filename => 'layout').render(parser)
     end
 
-    def initialize(xml, parser, result)
-      @builder = xml
-      @parser = parser
-      @result = result
+    def initialize(query, object, context)
+      @context = context
+      @query = query
+      @object = object
     end
 
     def build_xml
-      Converter.convert(@builder, @parser.action, @result)
+      Converter.convert(query.action, object)
+    end
+
+    def render(template, obj)
+      template_filename = File.join(File.dirname(__FILE__), 'views', '%s.haml' % template.to_s)
+      Haml::Engine.new(File.read(template_filename), :filename => template_filename).render(self, :object => obj)
     end
 
   end
diff --git a/server/lib/ec2/server.rb b/server/lib/ec2/server.rb
index 6586f16..12f1809 100644
--- a/server/lib/ec2/server.rb
+++ b/server/lib/ec2/server.rb
@@ -14,8 +14,8 @@
 # under the License.
 
 require 'rubygems'
-require 'nokogiri'
 require 'sinatra/base'
+require 'haml'
 
 require_relative '../sinatra'
 require_relative './helpers'
@@ -52,7 +52,7 @@ module Deltacloud::EC2
     get '/', :provides => :xml do
       ec2_action = QueryParser.parse(params, request_id)
       ec2_action.perform!(credentials, driver)
-      ec2_action.to_xml
+      ec2_action.to_xml(self)
     end
 
   end
diff --git a/server/lib/ec2/views/create_key_pair.haml b/server/lib/ec2/views/create_key_pair.haml
new file mode 100644
index 0000000..ed00492
--- /dev/null
+++ b/server/lib/ec2/views/create_key_pair.haml
@@ -0,0 +1,3 @@
+%keyName=object.name
+%keyFingerprint=object.fingerprint
+%keyMaterial=object.pem_rsa_key
diff --git a/server/lib/ec2/views/delete_key_pair.haml b/server/lib/ec2/views/delete_key_pair.haml
new file mode 100644
index 0000000..d809ea8
--- /dev/null
+++ b/server/lib/ec2/views/delete_key_pair.haml
@@ -0,0 +1 @@
+%return true
diff --git a/server/lib/ec2/views/describe_availability_zones.haml b/server/lib/ec2/views/describe_availability_zones.haml
new file mode 100644
index 0000000..1d96617
--- /dev/null
+++ b/server/lib/ec2/views/describe_availability_zones.haml
@@ -0,0 +1,6 @@
+%availabilityZoneInfo
+  - object.each do |item|
+    %item
+      %zoneName=item.id
+      %zoneState=item.state
+      %regionName=item.name
diff --git a/server/lib/ec2/views/describe_images.haml b/server/lib/ec2/views/describe_images.haml
new file mode 100644
index 0000000..a49a5ee
--- /dev/null
+++ b/server/lib/ec2/views/describe_images.haml
@@ -0,0 +1,10 @@
+%imagesSet
+  - object.each do |item|
+    %item
+      %imageId=item.id
+      %imageState=item.state.downcase
+      %imageOwnerId=item.owner_id
+      %architecture item.architecture
+      %imageType machine
+      %name=item.name
+      %description=item.description
diff --git a/server/lib/ec2/views/describe_instance_set.haml b/server/lib/ec2/views/describe_instance_set.haml
new file mode 100644
index 0000000..b8c7c1c
--- /dev/null
+++ b/server/lib/ec2/views/describe_instance_set.haml
@@ -0,0 +1,20 @@
+%instanceSet
+  - object.each do |item|
+    %item
+      %instanceId=item.id
+      %imageId=item.image_id
+      %instanceType=item.instance_profile.name
+      %launchTime=item.launch_time
+      %ipAddress=item.public_addresses.first.address
+      %privateIpAddress=item.public_addresses.first.address
+      %dnsName=item.public_addresses.first.address
+      %privateDnsName=item.private_addresses.first.address
+      %architecture=item.instance_profile.architecture
+      %keyName=item.keyname
+      %instanceState
+        %code=instance_state_code(item.state.downcase)
+        %name=item.state.downcase
+      %placement
+        %availabilityZone=item.realm_id
+        %groupName
+        %tenancy default
diff --git a/server/lib/ec2/views/describe_instances.haml b/server/lib/ec2/views/describe_instances.haml
new file mode 100644
index 0000000..75bcf7c
--- /dev/null
+++ b/server/lib/ec2/views/describe_instances.haml
@@ -0,0 +1,9 @@
+%reservationSet
+  %item
+    %reservationId r-11111111
+    %ownerId deltacloud
+    %groupSet
+      %item
+        %groupId sg-11111111
+        %groupName default
+    =render(:describe_instance_set, object)
diff --git a/server/lib/ec2/views/describe_key_pairs.haml b/server/lib/ec2/views/describe_key_pairs.haml
new file mode 100644
index 0000000..9b97bca
--- /dev/null
+++ b/server/lib/ec2/views/describe_key_pairs.haml
@@ -0,0 +1,5 @@
+%keySet
+  - object.each do |item|
+    %item
+      %keyName=item.name
+      %keyFingerprint=item.fingerprint
diff --git a/server/lib/ec2/views/instance_action.haml b/server/lib/ec2/views/instance_action.haml
new file mode 100644
index 0000000..7cafefa
--- /dev/null
+++ b/server/lib/ec2/views/instance_action.haml
@@ -0,0 +1,9 @@
+%instancesSet
+  %item
+    %instanceId=object.id
+    %currentState
+      %code=instance_state_code(object.state.downcase)
+      %name=object.state.downcase
+    %previousState
+      %code -1
+      %name unknown
diff --git a/server/lib/ec2/views/reboot_instances.haml b/server/lib/ec2/views/reboot_instances.haml
new file mode 100644
index 0000000..cc966ed
--- /dev/null
+++ b/server/lib/ec2/views/reboot_instances.haml
@@ -0,0 +1 @@
+=render :instance_action, object
diff --git a/server/lib/ec2/views/run_instances.haml b/server/lib/ec2/views/run_instances.haml
new file mode 100644
index 0000000..ef306a7
--- /dev/null
+++ b/server/lib/ec2/views/run_instances.haml
@@ -0,0 +1,7 @@
+%reservationId r-11111111
+%ownerId deltacloud
+%groupSet
+  %item
+    %groupId sg-11111111
+    %groupName default
+=render :describe_instance_set, [object]
diff --git a/server/lib/ec2/views/start_instances.haml b/server/lib/ec2/views/start_instances.haml
new file mode 100644
index 0000000..cc966ed
--- /dev/null
+++ b/server/lib/ec2/views/start_instances.haml
@@ -0,0 +1 @@
+=render :instance_action, object
diff --git a/server/lib/ec2/views/stop_instances.haml b/server/lib/ec2/views/stop_instances.haml
new file mode 100644
index 0000000..cc966ed
--- /dev/null
+++ b/server/lib/ec2/views/stop_instances.haml
@@ -0,0 +1 @@
+=render :instance_action, object
diff --git a/server/lib/ec2/views/terminate_instances.haml b/server/lib/ec2/views/terminate_instances.haml
new file mode 100644
index 0000000..ee7cba1
--- /dev/null
+++ b/server/lib/ec2/views/terminate_instances.haml
@@ -0,0 +1,9 @@
+%instancesSet
+  %item
+    %instanceId=context.params['InstanceId.1']
+    %currentState
+      %code=32
+      %name shutting-down
+    %previousState
+      %code -1
+      %name unknown
-- 
1.7.10.1