diff --git a/lib/fog/aws.rb b/lib/fog/aws.rb index 6d48eb933..dfb1a40a0 100644 --- a/lib/fog/aws.rb +++ b/lib/fog/aws.rb @@ -1,3 +1,4 @@ +require File.dirname(__FILE__) + '/aws/ec2' require File.dirname(__FILE__) + '/aws/simpledb' require File.dirname(__FILE__) + '/aws/s3' diff --git a/lib/fog/aws/ec2.rb b/lib/fog/aws/ec2.rb new file mode 100644 index 000000000..7e9d0cd0a --- /dev/null +++ b/lib/fog/aws/ec2.rb @@ -0,0 +1,90 @@ +require 'rubygems' +require 'base64' +require 'cgi' +require 'hmac-sha2' + +require File.dirname(__FILE__) + '/ec2/parsers' + +module Fog + module AWS + class EC2 + + # Initialize connection to EC2 + # + # ==== Notes + # options parameter must include values for :aws_access_key_id and + # :aws_secret_access_key in order to create a connection + # + # ==== Examples + # sdb = SimpleDB.new( + # :aws_access_key_id => your_aws_access_key_id, + # :aws_secret_access_key => your_aws_secret_access_key + # ) + # + # ==== Parameters + # options<~Hash>:: config arguments for connection. Defaults to {}. + # + # ==== Returns + # SimpleDB object with connection to aws. + def initialize(options={}) + @aws_access_key_id = options[:aws_access_key_id] + @aws_secret_access_key = options[:aws_secret_access_key] + @hmac = HMAC::SHA256.new(@aws_secret_access_key) + @host = options[:host] || 'ec2.amazonaws.com' + @port = options[:port] || 443 + @scheme = options[:scheme] || 'https' + @connection = AWS::Connection.new("#{@scheme}://#{@host}:#{@port}") + end + + # Acquire an elastic IP address. + # + # ==== Returns + # Hash:: The acquired :public_ip address. + def allocate_address + request({ + 'Action' => 'AllocateAddress' + }, Fog::Parsers::AWS::EC2::AllocateAddress.new) + end + + private + + def request(params, parser) + now = Time.now.utc.strftime("%Y-%m-%dT%H:%M:%SZ") + params.merge!({ + 'AWSAccessKeyId' => @aws_access_key_id, + 'Expires' => now, + 'SignatureMethod' => 'HmacSHA256', + 'SignatureVersion' => '2', + 'Timestamp' => now, + 'Version' => '2009-04-04' + }) + + body = '' + for key in params.keys.sort + unless (value = params[key]).nil? + body << "#{key}=#{CGI.escape(value).gsub(/\+/, '%20')}&" + end + end + + string_to_sign = "POST\n#{@host}\n/\n" << body.chop + hmac = @hmac.update(string_to_sign) + body << "Signature=#{CGI.escape(Base64.encode64(hmac.digest).chomp!).gsub(/\+/, '%20')}" + + response = @connection.request({ + :body => body, + :headers => { 'Content-Type' => 'application/x-www-form-urlencoded' }, + :host => @host, + :method => 'POST' + }) + + if parser && !response.body.empty? + Nokogiri::XML::SAX::Parser.new(parser).parse(response.body.split(/<\?xml.*\?>/)[1]) + response.body = parser.response + end + + response + end + + end + end +end diff --git a/lib/fog/aws/ec2/parsers.rb b/lib/fog/aws/ec2/parsers.rb new file mode 100644 index 000000000..e39df7c5f --- /dev/null +++ b/lib/fog/aws/ec2/parsers.rb @@ -0,0 +1,22 @@ +require File.dirname(__FILE__) + '/../../parser' + +module Fog + module Parsers + module AWS + module EC2 + + class AllocateAddress < Fog::Parsers::Base + + def end_element(name) + case name + when 'publicIp' + @response[:public_ip] = @value + end + end + + end + + end + end + end +end \ No newline at end of file diff --git a/spec/aws/ec2/allocate_address_spec.rb b/spec/aws/ec2/allocate_address_spec.rb new file mode 100644 index 000000000..0f00c0c41 --- /dev/null +++ b/spec/aws/ec2/allocate_address_spec.rb @@ -0,0 +1,11 @@ +require File.dirname(__FILE__) + '/../../spec_helper' + +describe 'EC2.batch_put_attributes' do + + it "should return proper attributes" do + actual = ec2.allocate_address + actual.body[:public_ip].should be_a(String) + p actual + end + +end diff --git a/spec/spec_helper.rb b/spec/spec_helper.rb index 73ba301bf..9f8307ea3 100644 --- a/spec/spec_helper.rb +++ b/spec/spec_helper.rb @@ -9,6 +9,16 @@ end require 'fog/aws' +def ec2 + @ec2 ||= begin + data = File.open(File.expand_path('~/.s3conf/s3config.yml')).read + config = YAML.load(data) + Fog::AWS::EC2.new( + :aws_access_key_id => config['aws_access_key_id'], + :aws_secret_access_key => config['aws_secret_access_key'] + ) + end +end def sdb @sdb ||= begin data = File.open(File.expand_path('~/.s3conf/s3config.yml')).read