Module: RightScale::CloudApi::Utils::AWS
- Defined in:
- lib/cloud/aws/base/helpers/utils.rb
Overview
AWS helpers namespace
Constant Summary collapse
- @@digest1 =
OpenSSL::Digest.new("sha1")
- @@digest256 =
Some installations may not support sha256
OpenSSL::Digest.new("sha256") rescue nil
Class Method Summary collapse
-
.amz_escape(string) ⇒ String
Escapes a string accordingly to Amazon rules.
-
.is_dns_bucket?(bucket_name) ⇒ Boolean
Returns
trueif the provided bucket name is a DNS compliant bucket name. -
.parametrize(data) ⇒ Hash
Parametrizes data to the format that Amazon EC2 (and compatible APIs) loves.
-
.sign(aws_secret_access_key, auth_string, digest = nil) ⇒ String
Generates a signature for the given string, secret access key and digest.
-
.sign_s3_signature(aws_secret_access_key, verb, canonicalized_resource, _headers = {}) ⇒ String
Signs and Authenticates REST Requests.
-
.sign_v2_signature(aws_secret_access_key, params, verb, host, urn) ⇒ String
Signature Version 2.
-
.utc_iso8601(time) ⇒ String
Returns ISO-8601 representation for the given time.
Class Method Details
.amz_escape(string) ⇒ String
Escapes a string accordingly to Amazon rules
85 86 87 88 89 90 91 92 93 |
# File 'lib/cloud/aws/base/helpers/utils.rb', line 85 def self.amz_escape(string) string = string.to_s # Use UTF-8 if current ruby supports it (1.9+) string = string.encode("UTF-8") if string.respond_to?(:encode) # CGI::escape is too clever: # - it escapes '~' when Amazon wants it to be un-escaped # - it escapes ' ' as '+' but Amazon loves it as '%20' CGI.escape(string).gsub('%7E','~').gsub('+','%20') end |
.is_dns_bucket?(bucket_name) ⇒ Boolean
Returns true if the provided bucket name is a DNS compliant bucket name
153 154 155 156 157 158 159 160 |
# File 'lib/cloud/aws/base/helpers/utils.rb', line 153 def self.is_dns_bucket?(bucket_name) bucket_name = bucket_name.to_s return false unless (3..63) === bucket_name.size bucket_name.split('.').each do |component| return false unless component[/^[a-z0-9]([a-z0-9-]*[a-z0-9])?$/] end true end |
.parametrize(data) ⇒ Hash
Parametrizes data to the format that Amazon EC2 (and compatible APIs) loves
303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 |
# File 'lib/cloud/aws/base/helpers/utils.rb', line 303 def self.parametrize(data) return data unless data.is_a?(Hash) result = {} # data.each do |mask, values| current_values = Utils::arrayify(values) current_mask = mask.dup.to_s current_mask << ".?" unless current_mask[/\?/] if current_values.size > 1 # current_values.dup.each_with_index do |value, idx| key = current_mask.sub('?', (idx+1).to_s) item = parametrize(value) if item.is_a?(Hash) item.each{ |k, v| result["#{key}.#{k}"] = v } else result[key] = item end end end result end |
.sign(aws_secret_access_key, auth_string, digest = nil) ⇒ String
Generates a signature for the given string, secret access key and digest
50 51 52 |
# File 'lib/cloud/aws/base/helpers/utils.rb', line 50 def self.sign(aws_secret_access_key, auth_string, digest=nil) Utils::base64en(OpenSSL::HMAC.digest(digest || @@digest1, aws_secret_access_key, auth_string)) end |
.sign_s3_signature(aws_secret_access_key, verb, canonicalized_resource, _headers = {}) ⇒ String
Signs and Authenticates REST Requests
178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 |
# File 'lib/cloud/aws/base/helpers/utils.rb', line 178 def self.sign_s3_signature(aws_secret_access_key, verb, canonicalized_resource, _headers={}) headers = {} # Make sure all our headers ara downcased _headers.each do |key, value| headers[key.to_s.downcase] = value.is_a?(Array) ? value.join(',') : value end content_md5 = headers['content-md5'] content_type = headers['content-type'] date = headers['x-amz-date'] || headers['date'] || headers['expires'] canonicalized_x_amz_headers = headers.select{|key, value| key[/^x-amz-/]}.sort.map{|key, value| "#{key}:#{value}"}.join("\n") canonicalized_x_amz_headers << "\n" unless canonicalized_x_amz_headers._blank? # StringToSign string_to_sign = "#{verb.to_s.upcase}\n" + "#{content_md5}\n" + "#{content_type}\n" + "#{date}\n" + "#{canonicalized_x_amz_headers}"+ "#{canonicalized_resource}" sign(aws_secret_access_key, string_to_sign) end |
.sign_v2_signature(aws_secret_access_key, params, verb, host, urn) ⇒ String
Signature Version 2
EC2, SQS and SDB requests must be signed by this guy
118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 |
# File 'lib/cloud/aws/base/helpers/utils.rb', line 118 def self.sign_v2_signature(aws_secret_access_key, params, verb, host, urn) params["Timestamp"] ||= utc_iso8601(Time.now) unless params["Expires"] params["SignatureVersion"] = '2' # select a signing method (make an old openssl working with sha1) # make 'HmacSHA256' to be a default one params['SignatureMethod'] = 'HmacSHA256' unless ['HmacSHA256', 'HmacSHA1'].include?(params['SignatureMethod']) params['SignatureMethod'] = 'HmacSHA1' unless @@digest256 # select a digest digest = (params['SignatureMethod'] == 'HmacSHA256' ? @@digest256 : @@digest1) # form string to sign canonical_string = Utils::params_to_urn(params){ |value| amz_escape(value) } string_to_sign = "#{verb.to_s.upcase}\n" + "#{host.downcase}\n" + "#{urn}\n" + "#{canonical_string}" "#{canonical_string}&Signature=#{amz_escape(sign(aws_secret_access_key, string_to_sign, digest))}" end |
.utc_iso8601(time) ⇒ String
Returns ISO-8601 representation for the given time
66 67 68 69 70 71 72 |
# File 'lib/cloud/aws/base/helpers/utils.rb', line 66 def self.utc_iso8601(time) case when time.is_a?(Fixnum) then Time::at(time) when time.is_a?(String) then Time::parse(time) else time end.utc.strftime("%Y-%m-%dT%H:%M:%S.000Z") end |