lib/elasticity/aws_request.rb in elasticity-2.3.1 vs lib/elasticity/aws_request.rb in elasticity-2.4

- old
+ new

@@ -1,20 +1,23 @@ module Elasticity + class MissingKeyError < StandardError; + end + class AwsRequest attr_reader :access_key attr_reader :secret_key attr_reader :host attr_reader :protocol # Supported values for options: # :region - AWS region (e.g. us-west-1) # :secure - true or false, default true. - def initialize(access, secret, options = {}) - @access_key = access - @secret_key = secret + def initialize(access=nil, secret=nil, options={}) + @access_key = get_access_key(access) + @secret_key = get_secret_key(secret) @host = "elasticmapreduce.#{{:region => 'us-east-1'}.merge(options)[:region]}.amazonaws.com" @protocol = {:secure => true}.merge(options)[:secure] ? 'https' : 'http' end def submit(ruby_params) @@ -36,24 +39,37 @@ true end private + def get_access_key(access) + return access if access + return ENV['AWS_ACCESS_KEY_ID'] if ENV['AWS_ACCESS_KEY_ID'] + raise MissingKeyError, 'Please provide an access key or set AWS_ACCESS_KEY_ID.' + end + + def get_secret_key(secret) + return secret if secret + return ENV['AWS_SECRET_ACCESS_KEY'] if ENV['AWS_SECRET_ACCESS_KEY'] + raise MissingKeyError, 'Please provide a secret key or set AWS_ACCESS_KEY_ID.' + end + # (Used from RightScale's right_aws gem.) # EC2, SQS, SDB and EMR requests must be signed by this guy. # See: http://docs.amazonwebservices.com/AmazonSimpleDB/2007-11-07/DeveloperGuide/index.html?REST_RESTAuth.html # http://developer.amazonwebservices.com/connect/entry.jspa?externalID=1928 def sign_params(service_hash) - uri = '/' # TODO: Why are we hard-coding this? - service_hash["AWSAccessKeyId"] = @access_key - service_hash["Timestamp"] = Time.now.utc.strftime("%Y-%m-%dT%H:%M:%S.000Z") - service_hash["SignatureVersion"] = "2" - service_hash["SignatureMethod"] = "HmacSHA256" + service_hash.merge!({ + 'AWSAccessKeyId' => @access_key, + 'Timestamp' => Time.now.utc.strftime('%Y-%m-%dT%H:%M:%S.000Z'), + 'SignatureVersion' => '2', + 'SignatureMethod' => 'HmacSHA256' + }) canonical_string = service_hash.keys.sort.map do |key| "#{AwsRequest.aws_escape(key)}=#{AwsRequest.aws_escape(service_hash[key])}" end.join('&') - string_to_sign = "POST\n#{@host.downcase}\n#{uri}\n#{canonical_string}" + string_to_sign = "POST\n#{@host.downcase}\n/\n#{canonical_string}" signature = AwsRequest.aws_escape(Base64.encode64(OpenSSL::HMAC.digest("sha256", @secret_key, string_to_sign)).strip) "#{canonical_string}&Signature=#{signature}" end # (Used from RightScale's right_aws gem) @@ -93,15 +109,11 @@ end result end # (Used from Rails' ActiveSupport) - def self.camelize(lower_case_and_underscored_word, first_letter_in_uppercase = true) - if first_letter_in_uppercase - lower_case_and_underscored_word.to_s.gsub(/\/(.?)/) { "::" + $1.upcase }.gsub(/(^|_)(.)/) { $2.upcase } - else - lower_case_and_underscored_word.first + camelize(lower_case_and_underscored_word)[1..-1] - end + def self.camelize(word) + word.to_s.gsub(/\/(.?)/) { "::" + $1.upcase }.gsub(/(^|_)(.)/) { $2.upcase } end # AWS error responses all follow the same form. Extract the message from # the error document. def self.parse_error_response(error_xml)