You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@deltacloud.apache.org by mf...@apache.org on 2012/05/25 09:34:06 UTC
[3/4] git commit: EC2: Added initial support for EC2 frontend
EC2: Added initial support for EC2 frontend
Project: http://git-wip-us.apache.org/repos/asf/deltacloud/repo
Commit: http://git-wip-us.apache.org/repos/asf/deltacloud/commit/3baf29ca
Tree: http://git-wip-us.apache.org/repos/asf/deltacloud/tree/3baf29ca
Diff: http://git-wip-us.apache.org/repos/asf/deltacloud/diff/3baf29ca
Branch: refs/heads/master
Commit: 3baf29ca80817c1279ae71d1e4db9f56c6b072ca
Parents: 3c05173
Author: Michal Fojtik <mf...@redhat.com>
Authored: Thu May 10 17:19:04 2012 +0200
Committer: Michal fojtik <mf...@redhat.com>
Committed: Fri May 25 09:33:50 2012 +0200
----------------------------------------------------------------------
server/bin/deltacloudd | 4 +-
server/config.ru | 8 ++
server/lib/ec2/helpers.rb | 22 +++++
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 | 60 +++++++++++++
7 files changed, 407 insertions(+), 2 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/deltacloud/blob/3baf29ca/server/bin/deltacloudd
----------------------------------------------------------------------
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)
http://git-wip-us.apache.org/repos/asf/deltacloud/blob/3baf29ca/server/config.ru
----------------------------------------------------------------------
diff --git a/server/config.ru b/server/config.ru
index 87d9506..d3c6ce6 100644
--- a/server/config.ru
+++ b/server/config.ru
@@ -35,6 +35,14 @@ if ENV['API_FRONTEND'] == 'cimi'
end
end
+if ENV['API_FRONTEND'] == 'ec2'
+ Deltacloud::configure do |server|
+ server.root_url '/'
+ server.version '2012-04-01'
+ server.klass 'Deltacloud::EC2::API'
+ end
+end
+
Deltacloud.require_frontend!
class IndexEntrypoint < Sinatra::Base
http://git-wip-us.apache.org/repos/asf/deltacloud/blob/3baf29ca/server/lib/ec2/helpers.rb
----------------------------------------------------------------------
diff --git a/server/lib/ec2/helpers.rb b/server/lib/ec2/helpers.rb
new file mode 100644
index 0000000..7517f36
--- /dev/null
+++ b/server/lib/ec2/helpers.rb
@@ -0,0 +1,22 @@
+# 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 '../deltacloud/helpers/driver_helper'
+require_relative '../deltacloud/helpers/auth_helper'
http://git-wip-us.apache.org/repos/asf/deltacloud/blob/3baf29ca/server/lib/ec2/helpers/converter.rb
----------------------------------------------------------------------
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
http://git-wip-us.apache.org/repos/asf/deltacloud/blob/3baf29ca/server/lib/ec2/helpers/errors.rb
----------------------------------------------------------------------
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
http://git-wip-us.apache.org/repos/asf/deltacloud/blob/3baf29ca/server/lib/ec2/query_parser.rb
----------------------------------------------------------------------
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
http://git-wip-us.apache.org/repos/asf/deltacloud/blob/3baf29ca/server/lib/ec2/server.rb
----------------------------------------------------------------------
diff --git a/server/lib/ec2/server.rb b/server/lib/ec2/server.rb
new file mode 100644
index 0000000..29fc545
--- /dev/null
+++ b/server/lib/ec2/server.rb
@@ -0,0 +1,60 @@
+# 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, Deltacloud[:version]
+ set :root_url, Deltacloud[:root_url]
+ set :root, File.join(File.dirname(__FILE__), '..', '..')
+
+ after do
+ headers 'Server' => 'Apache-Deltacloud-EC2/' + settings.version
+ end
+
+ get '/' do
+ content_type :xml
+ ec2_action = QueryParser.parse(params, request_id)
+ ec2_action.perform!(credentials, driver)
+ ec2_action.to_xml
+ end
+
+ end
+end