aboisvert_aws 3.0.0 → 3.0.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -24,7 +24,7 @@
24
24
  # Test
25
25
  module RightAws
26
26
  require 'digest/md5'
27
-
27
+
28
28
  class AwsUtils #:nodoc:
29
29
  @@digest1 = OpenSSL::Digest::Digest.new("sha1")
30
30
  @@digest256 = nil
@@ -38,7 +38,7 @@ module RightAws
38
38
  end
39
39
  time.utc.strftime("%Y-%m-%dT%H:%M:%S.000Z")
40
40
  end
41
-
41
+
42
42
  def self.sign(aws_secret_access_key, auth_string)
43
43
  Base64.encode64(OpenSSL::HMAC.digest(@@digest1, aws_secret_access_key, auth_string)).strip
44
44
  end
@@ -112,11 +112,11 @@ module RightAws
112
112
  end
113
113
 
114
114
  # From Amazon's SQS Dev Guide, a brief description of how to escape:
115
- # "URL encode the computed signature and other query parameters as specified in
116
- # RFC1738, section 2.2. In addition, because the + character is interpreted as a blank space
117
- # by Sun Java classes that perform URL decoding, make sure to encode the + character
115
+ # "URL encode the computed signature and other query parameters as specified in
116
+ # RFC1738, section 2.2. In addition, because the + character is interpreted as a blank space
117
+ # by Sun Java classes that perform URL decoding, make sure to encode the + character
118
118
  # although it is not required by RFC1738."
119
- # Avoid using CGI::escape to escape URIs.
119
+ # Avoid using CGI::escape to escape URIs.
120
120
  # CGI::escape will escape characters in the protocol, host, and port
121
121
  # sections of the URI. Only target chars in the query
122
122
  # string should be escaped.
@@ -124,19 +124,19 @@ module RightAws
124
124
  e = URI.escape(raw)
125
125
  e.gsub(/\+/, "%2b")
126
126
  end
127
-
127
+
128
128
  def self.allow_only(allowed_keys, params)
129
129
  bogus_args = []
130
130
  params.keys.each {|p| bogus_args.push(p) unless allowed_keys.include?(p) }
131
131
  raise AwsError.new("The following arguments were given but are not legal for the function call #{caller_method}: #{bogus_args.inspect}") if bogus_args.length > 0
132
132
  end
133
-
133
+
134
134
  def self.mandatory_arguments(required_args, params)
135
135
  rargs = required_args.dup
136
136
  params.keys.each {|p| rargs.delete(p)}
137
137
  raise AwsError.new("The following mandatory arguments were not provided to #{caller_method}: #{rargs.inspect}") if rargs.length > 0
138
138
  end
139
-
139
+
140
140
  def self.caller_method
141
141
  caller[1]=~/`(.*?)'/
142
142
  $1
@@ -175,14 +175,14 @@ module RightAws
175
175
 
176
176
  class AwsNoChange < RuntimeError
177
177
  end
178
-
178
+
179
179
  class RightAwsBase
180
180
 
181
181
  # Amazon HTTP Error handling
182
182
 
183
183
  # Text, if found in an error message returned by AWS, indicates that this may be a transient
184
184
  # error. Transient errors are automatically retried with exponential back-off.
185
- AMAZON_PROBLEMS = [ 'internal service error',
185
+ AMAZON_PROBLEMS = [ 'internal service error',
186
186
  'is currently unavailable',
187
187
  'no response from',
188
188
  'Please try again',
@@ -194,13 +194,13 @@ module RightAws
194
194
  'InsufficientInstanceCapacity'
195
195
  ]
196
196
  @@amazon_problems = AMAZON_PROBLEMS
197
- # Returns a list of Amazon service responses which are known to be transient problems.
198
- # We have to re-request if we get any of them, because the problem will probably disappear.
197
+ # Returns a list of Amazon service responses which are known to be transient problems.
198
+ # We have to re-request if we get any of them, because the problem will probably disappear.
199
199
  # By default this method returns the same value as the AMAZON_PROBLEMS const.
200
200
  def self.amazon_problems
201
201
  @@amazon_problems
202
202
  end
203
-
203
+
204
204
  # Sets the list of Amazon side problems. Use in conjunction with the
205
205
  # getter to append problems.
206
206
  def self.amazon_problems=(problems_list)
@@ -213,7 +213,7 @@ module RightAws
213
213
  #
214
214
  # If an API call action is in the list then no attempts to retry are performed.
215
215
  #
216
- RAISE_ON_TIMEOUT_ON_ACTIONS = %w{
216
+ RAISE_ON_TIMEOUT_ON_ACTIONS = %w{
217
217
  AllocateAddress
218
218
  CreateSnapshot
219
219
  CreateVolume
@@ -235,7 +235,7 @@ module RightAws
235
235
 
236
236
  module RightAwsBaseInterface
237
237
  DEFAULT_SIGNATURE_VERSION = '2'
238
-
238
+
239
239
  @@caching = false
240
240
  def self.caching
241
241
  @@caching
@@ -299,7 +299,7 @@ module RightAws
299
299
  @params[:host_to_sign] = @params[:server].dup
300
300
  @params[:host_to_sign] << ":#{@params[:port]}" unless default_port == @params[:port].to_i
301
301
  # a set of options to be passed to RightHttpConnection object
302
- @params[:connection_options] = {} unless @params[:connection_options].is_a?(Hash)
302
+ @params[:connection_options] = {} unless @params[:connection_options].is_a?(Hash)
303
303
  @with_connection_options = {}
304
304
  @params[:connections] ||= :shared # || :dedicated
305
305
  @params[:max_connections] ||= 10
@@ -324,11 +324,11 @@ module RightAws
324
324
  end
325
325
  end
326
326
 
327
- # Returns +true+ if the describe_xxx responses are being cached
327
+ # Returns +true+ if the describe_xxx responses are being cached
328
328
  def caching?
329
329
  @params.key?(:cache) ? @params[:cache] : @@caching
330
330
  end
331
-
331
+
332
332
  # Check if the aws function response hits the cache or not.
333
333
  # If the cache hits:
334
334
  # - raises an +AwsNoChange+ exception if +do_raise+ == +:raise+.
@@ -346,9 +346,9 @@ module RightAws
346
346
  # check for changes
347
347
  unless @cache[function] && @cache[function][:response_md5] == response_md5
348
348
  # well, the response is new, reset cache data
349
- update_cache(function, {:response_md5 => response_md5,
350
- :timestamp => Time.now,
351
- :hits => 0,
349
+ update_cache(function, {:response_md5 => response_md5,
350
+ :timestamp => Time.now,
351
+ :hits => 0,
352
352
  :parsed => nil})
353
353
  else
354
354
  # aha, cache hits, update the data and throw an exception if needed
@@ -364,11 +364,11 @@ module RightAws
364
364
  end
365
365
  result
366
366
  end
367
-
367
+
368
368
  def update_cache(function, hash)
369
369
  (@cache[function.to_sym] ||= {}).merge!(hash) if caching?
370
370
  end
371
-
371
+
372
372
  def on_exception(options={:raise=>true, :log=>true}) # :nodoc:
373
373
  raise if $!.is_a?(AwsNoChange)
374
374
  AwsError::on_aws_exception(self, options)
@@ -465,7 +465,7 @@ module RightAws
465
465
  :protocol => @params[:protocol] }
466
466
  request_hash.merge!(@params[:connection_options])
467
467
  request_hash.merge!(@with_connection_options)
468
-
468
+
469
469
  # If an action is marked as "non-retryable" and there was no :raise_on_timeout option set
470
470
  # explicitly then do set that option
471
471
  if Array(RightAwsBase::raise_on_timeout_on_actions).include?(action) && !request_hash.has_key?(:raise_on_timeout)
@@ -551,7 +551,7 @@ module RightAws
551
551
  check_result = @error_handler.check(request)
552
552
  if check_result
553
553
  @error_handler = nil
554
- return check_result
554
+ return check_result
555
555
  end
556
556
  raise AwsError.new(@last_errors, @last_response.code, @last_request_id)
557
557
  end
@@ -830,7 +830,7 @@ module RightAws
830
830
  end
831
831
  end
832
832
  end
833
-
833
+
834
834
  # Execute a block of code with custom set of settings for right_http_connection.
835
835
  # Accepts next options (see Rightscale::HttpConnection for explanation):
836
836
  # :raise_on_timeout
@@ -897,35 +897,35 @@ module RightAws
897
897
  # Attribute inherited by RuntimeError:
898
898
  # message - the text of the error, generally as returned by AWS in its XML response.
899
899
  class AwsError < RuntimeError
900
-
900
+
901
901
  # either an array of errors where each item is itself an array of [code, message]),
902
902
  # or an error string if the error was raised manually, as in <tt>AwsError.new('err_text')</tt>
903
903
  attr_reader :errors
904
-
904
+
905
905
  # Request id (if exists)
906
906
  attr_reader :request_id
907
-
907
+
908
908
  # Response HTTP error code
909
909
  attr_reader :http_code
910
-
910
+
911
911
  def initialize(errors=nil, http_code=nil, request_id=nil)
912
912
  @errors = errors
913
913
  @request_id = request_id
914
914
  @http_code = http_code
915
915
  super(@errors.is_a?(Array) ? @errors.map{|code, msg| "#{code}: #{msg}"}.join("; ") : @errors.to_s)
916
916
  end
917
-
917
+
918
918
  # Does any of the error messages include the regexp +pattern+?
919
919
  # Used to determine whether to retry request.
920
920
  def include?(pattern)
921
921
  if @errors.is_a?(Array)
922
- @errors.each{ |code, msg| return true if code =~ pattern }
922
+ @errors.each{ |code, msg| return true if code =~ pattern }
923
923
  else
924
- return true if @errors_str =~ pattern
924
+ return true if @errors_str =~ pattern
925
925
  end
926
926
  false
927
927
  end
928
-
928
+
929
929
  # Generic handler for AwsErrors. +aws+ is the RightAws::S3, RightAws::EC2, or RightAws::SQS
930
930
  # object that caused the exception (it must provide last_request and last_response). Supported
931
931
  # boolean options are:
@@ -949,7 +949,7 @@ module RightAws
949
949
  raise if options[:raise] # re-raise an exception
950
950
  return nil
951
951
  end
952
-
952
+
953
953
  # True if e is an AWS system error, i.e. something that is for sure not the caller's fault.
954
954
  # Used to force logging.
955
955
  def self.system_error?(e)
@@ -960,9 +960,9 @@ module RightAws
960
960
 
961
961
 
962
962
  class AWSErrorHandler
963
- # 0-100 (%)
964
- DEFAULT_CLOSE_ON_4XX_PROBABILITY = 10
965
-
963
+ # 0-100 (%)
964
+ DEFAULT_CLOSE_ON_4XX_PROBABILITY = 10
965
+
966
966
  @@reiteration_start_delay = 0.2
967
967
  def self.reiteration_start_delay
968
968
  @@reiteration_start_delay
@@ -978,42 +978,42 @@ module RightAws
978
978
  def self.reiteration_time=(reiteration_time)
979
979
  @@reiteration_time = reiteration_time
980
980
  end
981
-
982
- @@close_on_error = true
983
- def self.close_on_error
984
- @@close_on_error
985
- end
986
- def self.close_on_error=(close_on_error)
987
- @@close_on_error = close_on_error
988
- end
989
-
990
- @@close_on_4xx_probability = DEFAULT_CLOSE_ON_4XX_PROBABILITY
991
- def self.close_on_4xx_probability
992
- @@close_on_4xx_probability
993
- end
994
- def self.close_on_4xx_probability=(close_on_4xx_probability)
995
- @@close_on_4xx_probability = close_on_4xx_probability
996
- end
997
-
998
- # params:
999
- # :reiteration_time
1000
- # :errors_list
1001
- # :close_on_error = true | false
1002
- # :close_on_4xx_probability = 1-100
1003
- def initialize(aws, parser, params={}) #:nodoc:
981
+
982
+ @@close_on_error = true
983
+ def self.close_on_error
984
+ @@close_on_error
985
+ end
986
+ def self.close_on_error=(close_on_error)
987
+ @@close_on_error = close_on_error
988
+ end
989
+
990
+ @@close_on_4xx_probability = DEFAULT_CLOSE_ON_4XX_PROBABILITY
991
+ def self.close_on_4xx_probability
992
+ @@close_on_4xx_probability
993
+ end
994
+ def self.close_on_4xx_probability=(close_on_4xx_probability)
995
+ @@close_on_4xx_probability = close_on_4xx_probability
996
+ end
997
+
998
+ # params:
999
+ # :reiteration_time
1000
+ # :errors_list
1001
+ # :close_on_error = true | false
1002
+ # :close_on_4xx_probability = 1-100
1003
+ def initialize(aws, parser, params={}) #:nodoc:
1004
1004
  @aws = aws # Link to RightEc2 | RightSqs | RightS3 instance
1005
1005
  @parser = parser # parser to parse Amazon response
1006
1006
  @started_at = Time.now
1007
- @stop_at = @started_at + (params[:reiteration_time] || @@reiteration_time)
1008
- @errors_list = params[:errors_list] || []
1007
+ @stop_at = @started_at + (params[:reiteration_time] || @@reiteration_time)
1008
+ @errors_list = params[:errors_list] || []
1009
1009
  @reiteration_delay = @@reiteration_start_delay
1010
1010
  @retries = 0
1011
- # close current HTTP(S) connection on 5xx, errors from list and 4xx errors
1011
+ # close current HTTP(S) connection on 5xx, errors from list and 4xx errors
1012
1012
  @close_on_error = params[:close_on_error].nil? ? @@close_on_error : params[:close_on_error]
1013
- @close_on_4xx_probability = params[:close_on_4xx_probability] || @@close_on_4xx_probability
1013
+ @close_on_4xx_probability = params[:close_on_4xx_probability] || @@close_on_4xx_probability
1014
1014
  end
1015
-
1016
- # Returns false if
1015
+
1016
+ # Returns false if
1017
1017
  def check(request) #:nodoc:
1018
1018
  result = false
1019
1019
  error_found = false
@@ -1026,7 +1026,7 @@ module RightAws
1026
1026
  # is this a redirect?
1027
1027
  # yes!
1028
1028
  if response.is_a?(Net::HTTPRedirection)
1029
- redirect_detected = true
1029
+ redirect_detected = true
1030
1030
  else
1031
1031
  # no, it's an error ...
1032
1032
  @aws.logger.warn("##### #{@aws.class.name} returned an error: #{response.code} #{response.message}\n#{response.body} #####")
@@ -1048,7 +1048,7 @@ module RightAws
1048
1048
  @aws.last_request_id = '-undefined-'
1049
1049
  last_errors_text = response.message
1050
1050
  end
1051
-
1051
+
1052
1052
  # Ok, it is a redirect, find the new destination location
1053
1053
  if redirect_detected
1054
1054
  location = response['location']
@@ -1078,21 +1078,21 @@ module RightAws
1078
1078
  end
1079
1079
  end
1080
1080
  end
1081
-
1081
+
1082
1082
  # check the time has gone from the first error come
1083
1083
  if redirect_detected || error_found
1084
- # Close the connection to the server and recreate a new one.
1085
- # It may have a chance that one server is a semi-down and reconnection
1086
- # will help us to connect to the other server
1084
+ # Close the connection to the server and recreate a new one.
1085
+ # It may have a chance that one server is a semi-down and reconnection
1086
+ # will help us to connect to the other server
1087
1087
  if !redirect_detected && @close_on_error
1088
1088
  @aws.destroy_connection(request, "#{self.class.name}: error match to pattern '#{error_match}'")
1089
- end
1090
-
1089
+ end
1090
+
1091
1091
  if (Time.now < @stop_at)
1092
1092
  @retries += 1
1093
1093
  unless redirect_detected
1094
1094
  @aws.logger.warn("##### Retry ##{@retries} is being performed. Sleeping for #{@reiteration_delay} sec. Whole time: #{Time.now-@started_at} sec ####")
1095
- sleep @reiteration_delay
1095
+ sleep @reiteration_delay
1096
1096
  @reiteration_delay *= 2
1097
1097
 
1098
1098
  # Always make sure that the fp is set to point to the beginning(?)
@@ -1111,39 +1111,39 @@ module RightAws
1111
1111
  result = @aws.request_info(request, @parser)
1112
1112
  else
1113
1113
  @aws.logger.warn("##### Ooops, time is over... ####")
1114
- end
1115
- # aha, this is unhandled error:
1116
- elsif @close_on_error
1114
+ end
1115
+ # aha, this is unhandled error:
1116
+ elsif @close_on_error
1117
1117
  # On 5xx(Server errors), 403(RequestTimeTooSkewed) and 408(Request Timeout) a conection has to be closed
1118
1118
  if @aws.last_response.code.to_s[/^(5\d\d|403|408)$/]
1119
1119
  @aws.destroy_connection(request, "#{self.class.name}: code: #{@aws.last_response.code}: '#{@aws.last_response.message}'")
1120
- # Is this a 4xx error ?
1121
- elsif @aws.last_response.code.to_s[/^4\d\d$/] && @close_on_4xx_probability > rand(100)
1120
+ # Is this a 4xx error ?
1121
+ elsif @aws.last_response.code.to_s[/^4\d\d$/] && @close_on_4xx_probability > rand(100)
1122
1122
  @aws.destroy_connection(request, "#{self.class.name}: code: #{@aws.last_response.code}: '#{@aws.last_response.message}', " +
1123
1123
  "probability: #{@close_on_4xx_probability}%")
1124
1124
  end
1125
1125
  end
1126
1126
  result
1127
1127
  end
1128
-
1128
+
1129
1129
  end
1130
1130
 
1131
1131
 
1132
1132
  #-----------------------------------------------------------------
1133
1133
 
1134
1134
  class RightSaxParserCallbackTemplate #:nodoc:
1135
- def initialize(right_aws_parser)
1136
- @right_aws_parser = right_aws_parser
1137
- end
1138
- def on_characters(chars)
1135
+ def initialize(right_aws_parser)
1136
+ @right_aws_parser = right_aws_parser
1137
+ end
1138
+ def on_characters(chars)
1139
1139
  @right_aws_parser.text(chars)
1140
- end
1141
- def on_start_document; end
1142
- def on_comment(msg); end
1143
- def on_processing_instruction(target, data); end
1144
- def on_cdata_block(cdata); end
1145
- def on_end_document; end
1146
- end
1140
+ end
1141
+ def on_start_document; end
1142
+ def on_comment(msg); end
1143
+ def on_processing_instruction(target, data); end
1144
+ def on_cdata_block(cdata); end
1145
+ def on_end_document; end
1146
+ end
1147
1147
 
1148
1148
  class RightSaxParserCallback < RightSaxParserCallbackTemplate
1149
1149
  def self.include_callback
@@ -1167,25 +1167,25 @@ module RightAws
1167
1167
  end
1168
1168
 
1169
1169
  class RightAWSParser #:nodoc:
1170
- # default parsing library
1171
- DEFAULT_XML_LIBRARY = 'rexml'
1172
- # a list of supported parsers
1173
- @@supported_xml_libs = [DEFAULT_XML_LIBRARY, 'libxml']
1174
-
1175
- @@xml_lib = DEFAULT_XML_LIBRARY # xml library name: 'rexml' | 'libxml'
1170
+ # default parsing library
1171
+ DEFAULT_XML_LIBRARY = 'rexml'
1172
+ # a list of supported parsers
1173
+ @@supported_xml_libs = [DEFAULT_XML_LIBRARY, 'libxml']
1174
+
1175
+ @@xml_lib = DEFAULT_XML_LIBRARY # xml library name: 'rexml' | 'libxml'
1176
1176
  def self.xml_lib
1177
1177
  @@xml_lib
1178
1178
  end
1179
1179
  def self.xml_lib=(new_lib_name)
1180
1180
  @@xml_lib = new_lib_name
1181
1181
  end
1182
-
1182
+
1183
1183
  attr_accessor :result
1184
1184
  attr_reader :xmlpath
1185
1185
  attr_accessor :xml_lib
1186
1186
  attr_reader :full_tag_name
1187
1187
  attr_reader :tag
1188
-
1188
+
1189
1189
  def initialize(params={})
1190
1190
  @xmlpath = ''
1191
1191
  @full_tag_name = ''
@@ -1220,17 +1220,17 @@ module RightAws
1220
1220
  # Get response body
1221
1221
  xml_text = xml_text.body unless xml_text.is_a?(String)
1222
1222
  @xml_lib = params[:xml_lib] || @xml_lib
1223
- # check that we had no problems with this library otherwise use default
1224
- @xml_lib = DEFAULT_XML_LIBRARY unless @@supported_xml_libs.include?(@xml_lib)
1223
+ # check that we had no problems with this library otherwise use default
1224
+ @xml_lib = DEFAULT_XML_LIBRARY unless @@supported_xml_libs.include?(@xml_lib)
1225
1225
  # load xml library
1226
1226
  if @xml_lib=='libxml' && !defined?(XML::SaxParser)
1227
1227
  begin
1228
1228
  require 'xml/libxml'
1229
- # Setup SaxParserCallback
1229
+ # Setup SaxParserCallback
1230
1230
  if XML::Parser::VERSION >= '0.5.1' &&
1231
1231
  XML::Parser::VERSION < '0.9.7'
1232
1232
  RightSaxParserCallback.include_callback
1233
- end
1233
+ end
1234
1234
  rescue LoadError => e
1235
1235
  @@supported_xml_libs.delete(@xml_lib)
1236
1236
  @xml_lib = DEFAULT_XML_LIBRARY
@@ -1249,31 +1249,31 @@ module RightAws
1249
1249
  xml = XML::SaxParser.string(xml_text)
1250
1250
  else
1251
1251
  xml = XML::SaxParser.new
1252
- xml.string = xml_text
1252
+ xml.string = xml_text
1253
1253
  end
1254
- # check libxml-ruby version
1254
+ # check libxml-ruby version
1255
1255
  if XML::Parser::VERSION >= '0.9.7'
1256
1256
  xml.callbacks = RightSaxParserCallbackNs.new(self)
1257
1257
  elsif XML::Parser::VERSION >= '0.5.1'
1258
- xml.callbacks = RightSaxParserCallback.new(self)
1259
- else
1260
- xml.on_start_element{|name, attr_hash| self.tag_start(name, attr_hash)}
1258
+ xml.callbacks = RightSaxParserCallback.new(self)
1259
+ else
1260
+ xml.on_start_element{|name, attr_hash| self.tag_start(name, attr_hash)}
1261
1261
  xml.on_characters{ |text| self.text(text)}
1262
- xml.on_end_element{ |name| self.tag_end(name)}
1263
- end
1262
+ xml.on_end_element{ |name| self.tag_end(name)}
1263
+ end
1264
1264
  xml.parse
1265
1265
  else
1266
1266
  REXML::Document.parse_stream(xml_text, self)
1267
1267
  end
1268
1268
  end
1269
- # Parser must have a lots of methods
1269
+ # Parser must have a lots of methods
1270
1270
  # (see /usr/lib/ruby/1.8/rexml/parsers/streamparser.rb)
1271
1271
  # We dont need most of them in RightAWSParser and method_missing helps us
1272
1272
  # to skip their definition
1273
1273
  def method_missing(method, *params)
1274
1274
  # if the method is one of known - just skip it ...
1275
- return if [:comment, :attlistdecl, :notationdecl, :elementdecl,
1276
- :entitydecl, :cdata, :xmldecl, :attlistdecl, :instruction,
1275
+ return if [:comment, :attlistdecl, :notationdecl, :elementdecl,
1276
+ :entitydecl, :cdata, :xmldecl, :attlistdecl, :instruction,
1277
1277
  :doctype].include?(method)
1278
1278
  # ... else - call super to raise an exception
1279
1279
  super(method, params)