aboisvert_aws 3.0.0 → 3.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -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)