icehouse-right_aws 1.11.0 → 2.2.0

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.
Files changed (71) hide show
  1. data/History.txt +93 -15
  2. data/Manifest.txt +15 -1
  3. data/README.txt +0 -4
  4. data/Rakefile +34 -17
  5. data/lib/acf/right_acf_interface.rb +260 -124
  6. data/lib/acf/right_acf_invalidations.rb +144 -0
  7. data/lib/acf/right_acf_origin_access_identities.rb +230 -0
  8. data/lib/acf/right_acf_streaming_interface.rb +229 -0
  9. data/lib/acw/right_acw_interface.rb +4 -5
  10. data/lib/as/right_as_interface.rb +59 -51
  11. data/lib/awsbase/benchmark_fix.rb +0 -0
  12. data/lib/awsbase/right_awsbase.rb +351 -104
  13. data/lib/awsbase/support.rb +2 -82
  14. data/lib/awsbase/version.rb +9 -0
  15. data/lib/ec2/right_ec2.rb +97 -246
  16. data/lib/ec2/right_ec2_ebs.rb +88 -68
  17. data/lib/ec2/right_ec2_images.rb +90 -50
  18. data/lib/ec2/right_ec2_instances.rb +118 -89
  19. data/lib/ec2/right_ec2_placement_groups.rb +108 -0
  20. data/lib/ec2/right_ec2_reserved_instances.rb +51 -44
  21. data/lib/ec2/right_ec2_security_groups.rb +396 -0
  22. data/lib/ec2/right_ec2_spot_instances.rb +425 -0
  23. data/lib/ec2/right_ec2_tags.rb +139 -0
  24. data/lib/ec2/right_ec2_vpc.rb +152 -140
  25. data/lib/ec2/right_ec2_windows_mobility.rb +84 -0
  26. data/lib/elb/right_elb_interface.rb +205 -39
  27. data/lib/iam/right_iam_access_keys.rb +71 -0
  28. data/lib/iam/right_iam_groups.rb +195 -0
  29. data/lib/iam/right_iam_interface.rb +341 -0
  30. data/lib/iam/right_iam_mfa_devices.rb +67 -0
  31. data/lib/iam/right_iam_users.rb +251 -0
  32. data/lib/rds/right_rds_interface.rb +591 -205
  33. data/lib/right_aws.rb +16 -12
  34. data/lib/route_53/right_route_53_interface.rb +640 -0
  35. data/lib/s3/right_s3.rb +34 -13
  36. data/lib/s3/right_s3_interface.rb +17 -14
  37. data/lib/sdb/active_sdb.rb +215 -38
  38. data/lib/sdb/right_sdb_interface.rb +93 -12
  39. data/lib/sqs/right_sqs.rb +1 -2
  40. data/lib/sqs/right_sqs_gen2.rb +0 -1
  41. data/lib/sqs/right_sqs_gen2_interface.rb +9 -9
  42. data/lib/sqs/right_sqs_interface.rb +6 -7
  43. data/right_aws.gemspec +91 -0
  44. data/test/README.mdown +39 -0
  45. data/test/acf/test_helper.rb +0 -0
  46. data/test/acf/test_right_acf.rb +10 -18
  47. data/test/awsbase/test_helper.rb +0 -0
  48. data/test/awsbase/test_right_awsbase.rb +0 -1
  49. data/test/ec2/test_helper.rb +0 -0
  50. data/test/ec2/test_right_ec2.rb +0 -1
  51. data/test/elb/test_helper.rb +2 -0
  52. data/test/elb/test_right_elb.rb +43 -0
  53. data/test/http_connection.rb +0 -0
  54. data/test/route_53/fixtures/a_record.xml +18 -0
  55. data/test/route_53/fixtures/alias_record.xml +18 -0
  56. data/test/route_53/test_helper.rb +2 -0
  57. data/test/route_53/test_right_route_53.rb +141 -0
  58. data/test/s3/test_helper.rb +0 -0
  59. data/test/s3/test_right_s3.rb +11 -9
  60. data/test/s3/test_right_s3_stubbed.rb +6 -4
  61. data/test/sdb/test_active_sdb.rb +71 -13
  62. data/test/sdb/test_batch_put_attributes.rb +54 -0
  63. data/test/sdb/test_helper.rb +0 -0
  64. data/test/sdb/test_right_sdb.rb +13 -7
  65. data/test/sqs/test_helper.rb +0 -0
  66. data/test/sqs/test_right_sqs.rb +0 -6
  67. data/test/sqs/test_right_sqs_gen2.rb +22 -34
  68. data/test/test_credentials.rb +0 -0
  69. data/test/ts_right_aws.rb +0 -0
  70. metadata +146 -16
  71. data/VERSION +0 -1
@@ -49,13 +49,12 @@ module RightAws
49
49
  # :port => 443 # Amazon service port: 80 or 443(default)
50
50
  # :protocol => 'https' # Amazon service protocol: 'http' or 'https'(default)
51
51
  # :signature_version => '0' # The signature version : '0','1 or '2'(default)
52
- # :multi_thread => true|false # Multi-threaded (connection per each thread): true or false(default)
53
52
  # :logger => Logger Object # Logger instance: logs to STDOUT if omitted
54
53
  # :nil_representation => 'mynil'} # interpret Ruby nil as this string value; i.e. use this string in SDB to represent Ruby nils (default is the string 'nil')
55
54
  #
56
55
  # Example:
57
56
  #
58
- # sdb = RightAws::SdbInterface.new('1E3GDYEOGFJPIT7XXXXXX','hgTHt68JY07JKUY08ftHYtERkjgtfERn57XXXXXX', {:multi_thread => true, :logger => Logger.new('/tmp/x.log')}) #=> #<RightSdb:0xa6b8c27c>
57
+ # sdb = RightAws::SdbInterface.new('1E3GDYEOGFJPIT7XXXXXX','hgTHt68JY07JKUY08ftHYtERkjgtfERn57XXXXXX', {:logger => Logger.new('/tmp/x.log')}) #=> #<RightSdb:0xa6b8c27c>
59
58
  #
60
59
  # see: http://docs.amazonwebservices.com/AmazonSimpleDB/2007-11-07/DeveloperGuide/
61
60
  #
@@ -89,24 +88,42 @@ module RightAws
89
88
 
90
89
  # Prepare attributes for putting.
91
90
  # (used by put_attributes)
92
- def pack_attributes(attributes, replace = false) #:nodoc:
91
+ def pack_attributes(items_or_attributes, replace = false, batch = false) #:nodoc:
92
+ if batch
93
+ index = 0
94
+ items_or_attributes.inject({}){|result, (item_name, attributes)|
95
+ item_prefix = "Item.#{index}."
96
+ result["#{item_prefix}ItemName"] = item_name.to_s
97
+ result.merge!(
98
+ pack_single_item_attributes(attributes, replace, item_prefix))
99
+ index += 1
100
+ result
101
+ }
102
+ else
103
+ pack_single_item_attributes(items_or_attributes, replace)
104
+ end
105
+ end
106
+
107
+ def pack_single_item_attributes(attributes, replace, prefix = "")
93
108
  result = {}
94
109
  if attributes
95
110
  idx = 0
96
111
  skip_values = attributes.is_a?(Array)
97
112
  attributes.each do |attribute, values|
98
113
  # set replacement attribute
99
- result["Attribute.#{idx}.Replace"] = 'true' if replace
114
+ result["#{prefix}Attribute.#{idx}.Replace"] = 'true' if replace
100
115
  # pack Name/Value
101
116
  unless values.nil?
102
- Array(values).each do |value|
103
- result["Attribute.#{idx}.Name"] = attribute
104
- result["Attribute.#{idx}.Value"] = ruby_to_sdb(value) unless skip_values
117
+ # Array(values) does not work here:
118
+ # - Array('') => [] but we wanna get here ['']
119
+ [values].flatten.each do |value|
120
+ result["#{prefix}Attribute.#{idx}.Name"] = attribute
121
+ result["#{prefix}Attribute.#{idx}.Value"] = ruby_to_sdb(value) unless skip_values
105
122
  idx += 1
106
123
  end
107
124
  else
108
- result["Attribute.#{idx}.Name"] = attribute
109
- result["Attribute.#{idx}.Value"] = ruby_to_sdb(nil) unless skip_values
125
+ result["#{prefix}Attribute.#{idx}.Name"] = attribute
126
+ result["#{prefix}Attribute.#{idx}.Value"] = ruby_to_sdb(nil) unless skip_values
110
127
  idx += 1
111
128
  end
112
129
  end
@@ -152,7 +169,7 @@ module RightAws
152
169
  # (similar to ActiveRecord::Base#find using :conditions => ['query', param1, .., paramN])
153
170
  #
154
171
  def query_expression_from_array(params) #:nodoc:
155
- return '' if params.blank?
172
+ return '' if params.right_blank?
156
173
  query = params.shift.to_s
157
174
  query.gsub(/(\\)?(\?)/) do
158
175
  if $1 # if escaped '\?' is found - replace it by '?' without backslash
@@ -164,7 +181,7 @@ module RightAws
164
181
  end
165
182
 
166
183
  def query_expression_from_hash(hash)
167
- return '' if hash.blank?
184
+ return '' if hash.right_blank?
168
185
  expression = []
169
186
  hash.each do |key, value|
170
187
  expression << "#{key}=#{escape(value)}"
@@ -237,6 +254,27 @@ module RightAws
237
254
  on_exception
238
255
  end
239
256
 
257
+ # Query Metadata for Domain
258
+ #
259
+ # Returns a hash on success or an exception on error.
260
+ #
261
+ # example:
262
+ # sdb = RightAWS:::SdbInterface.new
263
+ # sdb.domain_metadata('toys') # => {:attribute_values_size_bytes=>"2754",
264
+ # :item_count=>"25",
265
+ # :item_names_size_bytes=>"900",
266
+ # :timestamp=>"1291890409",
267
+ # :attribute_name_count=>"7",
268
+ # :box_usage=>"0.0000071759",
269
+ # :attribute_names_size_bytes=>"48",
270
+ # :attribute_value_count=>"154",
271
+ # :request_id=>"79bbfe8f-f0c9-59a2-0963-16d5fc6c3c52"}
272
+ # see http://docs.amazonwebservices.com/AmazonSimpleDB/latest/DeveloperGuide/index.html?SDB_API_DomainMetadata.html
273
+ def domain_metadata(domain)
274
+ link = generate_request("DomainMetadata","DomainName"=>domain)
275
+ request_info(link,QSdbGenericParser.new)
276
+ end
277
+
240
278
  # Delete SDB domain at Amazon.
241
279
  #
242
280
  # Returns a hash: { :box_usage, :request_id } on success or an exception on error.
@@ -307,6 +345,37 @@ module RightAws
307
345
  rescue Exception
308
346
  on_exception
309
347
  end
348
+
349
+ # Add/Replace attributes for multiple items at a time.
350
+ #
351
+ # Params:
352
+ # domain_name = DomainName
353
+ # items = {
354
+ # 'Item1' => {
355
+ # 'nameA' => [valueA1, valueA2,..., valueAN],
356
+ # ...
357
+ # 'nameB' => [valueB1, valueB2,..., valueBN]
358
+ # },
359
+ # 'Item2' => {
360
+ # 'nameC' => [valueC1, valueC2,..., valueCN],
361
+ # ...
362
+ # 'nameD' => [valueD1, valueD2,..., valueDN]
363
+ # }
364
+ # }
365
+ # replace = :replace | any other value to skip replacement
366
+ #
367
+ # Usage of batch_put_attributes is similar to put_attributes except that
368
+ # instead of supplying an item_name and a hash of attributes, you supply a
369
+ # hash of item names to attributes.
370
+ #
371
+ # See: http://docs.amazonwebservices.com/AmazonSimpleDB/latest/DeveloperGuide/index.html?SDB_API_BatchPutAttributes.html
372
+ def batch_put_attributes(domain_name, items, replace = false)
373
+ params = { 'DomainName' => domain_name }.merge(pack_attributes(items, replace, true))
374
+ link = generate_request("BatchPutAttributes", params)
375
+ request_info( link, QSdbSimpleParser.new)
376
+ rescue Exception
377
+ on_exception
378
+ end
310
379
 
311
380
  # Retrieve SDB item's attribute(s).
312
381
  #
@@ -476,7 +545,7 @@ module RightAws
476
545
  # see: http://docs.amazonwebservices.com/AmazonSimpleDB/2007-11-07/DeveloperGuide/index.html?SDB_API_QueryWithAttributes.html
477
546
  #
478
547
  def query_with_attributes(domain_name, attributes=[], query_expression = nil, max_number_of_items = nil, next_token = nil)
479
- attributes = attributes.to_a
548
+ attributes = Array(attributes)
480
549
  query_expression = query_expression_from_array(query_expression) if query_expression.is_a?(Array)
481
550
  @last_query_expression = query_expression
482
551
  #
@@ -566,6 +635,18 @@ module RightAws
566
635
  #-----------------------------------------------------------------
567
636
  # PARSERS:
568
637
  #-----------------------------------------------------------------
638
+ class QSdbGenericParser < RightAWSParser #:nodoc:
639
+ def reset
640
+ @result = {}
641
+ end
642
+ def tagend(name)
643
+ case full_tag_name
644
+ when %r{/(DomainMetadataResult|ResponseMetadata)/}
645
+ @result[name.right_underscore.to_sym] = @text
646
+ end
647
+ end
648
+ end
649
+
569
650
  class QSdbListDomainParser < RightAWSParser #:nodoc:
570
651
  def reset
571
652
  @result = { :domains => [] }
@@ -59,7 +59,6 @@ module RightAws
59
59
  #
60
60
  # {:server => 'queue.amazonaws.com' # Amazon service host: 'queue.amazonaws.com' (default)
61
61
  # :port => 443 # Amazon service port: 80 or 443 (default)
62
- # :multi_thread => true|false # Multi-threaded (connection per each thread): true or false (default)
63
62
  # :signature_version => '0' # The signature version : '0' or '1'(default)
64
63
  # :logger => Logger Object} # Logger instance: logs to STDOUT if omitted }
65
64
  #
@@ -271,7 +270,7 @@ module RightAws
271
270
  grantees << Grantee.new(self, grantee_email_address, key, value[:name], value[:perms])
272
271
  end
273
272
  if grantee_email_address
274
- grantees.blank? ? nil : grantees.shift
273
+ grantees.right_blank? ? nil : grantees.shift
275
274
  else
276
275
  grantees
277
276
  end
@@ -60,7 +60,6 @@ module RightAws
60
60
  #
61
61
  # {:server => 'queue.amazonaws.com' # Amazon service host: 'queue.amazonaws.com' (default)
62
62
  # :port => 443 # Amazon service port: 80 or 443 (default)
63
- # :multi_thread => true|false # Multi-threaded (connection per each thread): true or false (default)
64
63
  # :signature_version => '0' # The signature version : '0' or '1'(default)
65
64
  # :logger => Logger Object} # Logger instance: logs to STDOUT if omitted }
66
65
  class SqsGen2
@@ -65,13 +65,12 @@ module RightAws
65
65
  # Amazon's article "Migrating to Amazon SQS API version 2008-01-01" at:
66
66
  # http://developer.amazonwebservices.com/connect/entry.jspa?externalID=1148
67
67
  #
68
- # sqs = RightAws::SqsGen2Interface.new('1E3GDYEOGFJPIT75KDT40','hgTHt68JY07JKUY08ftHYtERkjgtfERn57DFE379', {:multi_thread => true, :logger => Logger.new('/tmp/x.log')})
68
+ # sqs = RightAws::SqsGen2Interface.new('1E3GDYEOGFJPIT75KDT40','hgTHt68JY07JKUY08ftHYtERkjgtfERn57DFE379', {:logger => Logger.new('/tmp/x.log')})
69
69
  #
70
70
  # Params is a hash:
71
71
  #
72
72
  # {:server => 'queue.amazonaws.com' # Amazon service host: 'queue.amazonaws.com' (default)
73
73
  # :port => 443 # Amazon service port: 80 or 443 (default)
74
- # :multi_thread => true|false # Multi-threaded (connection per each thread): true or false (default)
75
74
  # :signature_version => '0' # The signature version : '0', '1' or '2'(default)
76
75
  # :logger => Logger Object} # Logger instance: logs to STDOUT if omitted }
77
76
  #
@@ -127,7 +126,7 @@ module RightAws
127
126
  #
128
127
  service_params = signed_service_params(@aws_secret_access_key, service_hash, :post, @params[:server], service)
129
128
  request = Net::HTTP::Post.new(AwsUtils::URLencode(service))
130
- request['Content-Type'] = 'application/x-www-form-urlencoded'
129
+ request['Content-Type'] = 'application/x-www-form-urlencoded; charset=utf-8'
131
130
  request.body = service_params
132
131
  # prepare output hash
133
132
  { :request => request,
@@ -201,8 +200,8 @@ module RightAws
201
200
  # http://docs.amazonwebservices.com/AWSSimpleQueueService/latest/SQSDeveloperGuide/index.html?Query_QueryGetQueueAttributes.html
202
201
  def get_queue_attributes(queue_url, *attributes)
203
202
  attributes.flatten!
204
- attributes << 'All' if attributes.blank?
205
- params = amazonize_list('AttributeName', attributes.to_a)
203
+ attributes << 'All' if attributes.right_blank?
204
+ params = amazonize_list('AttributeName', attributes)
206
205
  params.merge!(:queue_url => queue_url)
207
206
  req_hash = generate_request('GetQueueAttributes', params)
208
207
  request_info(req_hash, SqsGetQueueAttributesParser.new(:logger => @logger))
@@ -245,8 +244,8 @@ module RightAws
245
244
  # see http://docs.amazonwebservices.com/AWSSimpleQueueService/latest/SQSDeveloperGuide/index.html?Query_QueryAddPermission.html
246
245
  # http://docs.amazonwebservices.com/AWSSimpleQueueService/latest/SQSDeveloperGuide/index.html?acp-overview.html
247
246
  def add_permissions(queue_url, label, grantees, actions)
248
- params = amazonize_list('AWSAccountId', grantees.to_a)
249
- params.merge!(amazonize_list('ActionName', actions.to_a))
247
+ params = amazonize_list('AWSAccountId', Array(grantees))
248
+ params.merge!(amazonize_list('ActionName', Array(actions)))
250
249
  params.merge!('Label' => label,
251
250
  :queue_url => queue_url )
252
251
  req_hash = generate_request('AddPermission', params)
@@ -281,7 +280,8 @@ module RightAws
281
280
  #
282
281
  def receive_message(queue_url, max_number_of_messages=1, visibility_timeout=nil, attributes=nil)
283
282
  return [] if max_number_of_messages == 0
284
- params = amazonize_list('AttributeName', attributes.to_a)
283
+ params = {}
284
+ params.merge!(amazonize_list('AttributeName', Array(attributes))) unless attributes.right_blank?
285
285
  params.merge!('MaxNumberOfMessages' => max_number_of_messages,
286
286
  'VisibilityTimeout' => visibility_timeout,
287
287
  :queue_url => queue_url )
@@ -428,7 +428,7 @@ module RightAws
428
428
  #
429
429
  def pop_message(queue_url, attributes=nil)
430
430
  messages = pop_messages(queue_url, 1, attributes)
431
- messages.blank? ? nil : messages[0]
431
+ messages.right_blank? ? nil : messages[0]
432
432
  rescue
433
433
  on_exception
434
434
  end
@@ -49,13 +49,12 @@ module RightAws
49
49
 
50
50
  # Creates a new SqsInterface instance.
51
51
  #
52
- # sqs = RightAws::SqsInterface.new('1E3GDYEOGFJPIT75KDT40','hgTHt68JY07JKUY08ftHYtERkjgtfERn57DFE379', {:multi_thread => true, :logger => Logger.new('/tmp/x.log')})
52
+ # sqs = RightAws::SqsInterface.new('1E3GDYEOGFJPIT75KDT40','hgTHt68JY07JKUY08ftHYtERkjgtfERn57DFE379', {:logger => Logger.new('/tmp/x.log')})
53
53
  #
54
54
  # Params is a hash:
55
55
  #
56
56
  # {:server => 'queue.amazonaws.com' # Amazon service host: 'queue.amazonaws.com'(default)
57
57
  # :port => 443 # Amazon service port: 80 or 443(default)
58
- # :multi_thread => true|false # Multi-threaded (connection per each thread): true or false(default)
59
58
  # :signature_version => '0' # The signature version : '0', '1' or '2'(default)
60
59
  # :logger => Logger Object} # Logger instance: logs to STDOUT if omitted }
61
60
  #
@@ -104,8 +103,8 @@ module RightAws
104
103
  param.each{ |key, value| param.delete(key) if (value.nil? || key.is_a?(Symbol)) }
105
104
  # created request
106
105
  param_to_str = param.to_a.collect{|key,val| key.to_s + "=" + CGI::escape(val.to_s) }.join("&")
107
- param_to_str = "?#{param_to_str}" unless param_to_str.blank?
108
- request = "Net::HTTP::#{method.capitalize}".constantize.new("#{queue_uri}#{param_to_str}")
106
+ param_to_str = "?#{param_to_str}" unless param_to_str.right_blank?
107
+ request = "Net::HTTP::#{method.capitalize}".right_constantize.new("#{queue_uri}#{param_to_str}")
109
108
  request.body = message if message
110
109
  # set main headers
111
110
  request['content-md5'] = ''
@@ -311,7 +310,7 @@ module RightAws
311
310
  def peek_message(queue_url, message_id)
312
311
  req_hash = generate_rest_request('GET', :queue_url => "#{queue_url}/#{CGI::escape message_id}" )
313
312
  messages = request_info(req_hash, SqsReceiveMessagesParser.new(:logger => @logger))
314
- messages.blank? ? nil : messages[0]
313
+ messages.right_blank? ? nil : messages[0]
315
314
  rescue
316
315
  on_exception
317
316
  end
@@ -452,7 +451,7 @@ module RightAws
452
451
  #
453
452
  def receive_message(queue_url, visibility_timeout=nil)
454
453
  result = receive_messages(queue_url, 1, visibility_timeout)
455
- result.blank? ? nil : result[0]
454
+ result.right_blank? ? nil : result[0]
456
455
  rescue
457
456
  on_exception
458
457
  end
@@ -482,7 +481,7 @@ module RightAws
482
481
  #
483
482
  def pop_message(queue_url)
484
483
  messages = pop_messages(queue_url)
485
- messages.blank? ? nil : messages[0]
484
+ messages.right_blank? ? nil : messages[0]
486
485
  rescue
487
486
  on_exception
488
487
  end
@@ -0,0 +1,91 @@
1
+ #-- -*- mode: ruby; encoding: utf-8 -*-
2
+ # Copyright: Copyright (c) 2010 RightScale, Inc.
3
+ #
4
+ # Permission is hereby granted, free of charge, to any person obtaining
5
+ # a copy of this software and associated documentation files (the
6
+ # 'Software'), to deal in the Software without restriction, including
7
+ # without limitation the rights to use, copy, modify, merge, publish,
8
+ # distribute, sublicense, and/or sell copies of the Software, and to
9
+ # permit persons to whom the Software is furnished to do so, subject to
10
+ # the following conditions:
11
+ #
12
+ # The above copyright notice and this permission notice shall be
13
+ # included in all copies or substantial portions of the Software.
14
+ #
15
+ # THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
16
+ # EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
17
+ # MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
18
+ # IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
19
+ # CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
20
+ # TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
21
+ # SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
22
+ #++
23
+
24
+ require 'rubygems'
25
+ require File.expand_path(File.join(File.dirname(__FILE__), "lib", "awsbase", "version"))
26
+
27
+ Gem::Specification.new do |spec|
28
+ spec.name = 'right_aws'
29
+ spec.rubyforge_project = 'rightaws'
30
+ spec.version = RightAws::VERSION::STRING
31
+ spec.authors = ['RightScale, Inc.']
32
+ spec.email = 'support@rightscale.com'
33
+ spec.summary = 'Interface classes for the Amazon EC2, SQS, and S3 Web Services'
34
+ spec.has_rdoc = true
35
+ spec.rdoc_options = ['--main', 'README.txt', '--title', '']
36
+ spec.extra_rdoc_files = ['README.txt']
37
+ spec.required_ruby_version = '>= 1.8.7'
38
+ spec.require_path = 'lib'
39
+
40
+ spec.add_dependency('right_http_connection', '>= 1.2.5')
41
+ #spec.requirements << "uuidtools >= 1.0.7 if you want to use ActiveSdb"
42
+ spec.requirements << "libxml-ruby >= 0.5.2.0 is encouraged"
43
+
44
+ spec.add_development_dependency('rake')
45
+ spec.add_development_dependency('rcov')
46
+
47
+ spec.description = <<-EOF
48
+ == DESCRIPTION:
49
+
50
+ The RightScale AWS gems have been designed to provide a robust, fast, and secure interface to Amazon EC2, EBS, S3, SQS, SDB, and CloudFront.
51
+ These gems have been used in production by RightScale since late 2006 and are being maintained to track enhancements made by Amazon.
52
+ The RightScale AWS gems comprise:
53
+
54
+ - RightAws::Ec2 -- interface to Amazon EC2 (Elastic Compute Cloud) and the
55
+ associated EBS (Elastic Block Store)
56
+ - RightAws::S3 and RightAws::S3Interface -- interface to Amazon S3 (Simple Storage Service)
57
+ - RightAws::Sqs and RightAws::SqsInterface -- interface to first-generation Amazon SQS (Simple Queue Service) (API version 2007-05-01)
58
+ - RightAws::SqsGen2 and RightAws::SqsGen2Interface -- interface to second-generation Amazon SQS (Simple Queue Service) (API version 2008-01-01)
59
+ - RightAws::SdbInterface and RightAws::ActiveSdb -- interface to Amazon SDB (SimpleDB)
60
+ - RightAws::AcfInterface -- interface to Amazon CloudFront, a content distribution service
61
+
62
+ == FEATURES:
63
+
64
+ - Full programmmatic access to EC2, EBS, S3, SQS, SDB, and CloudFront.
65
+ - Complete error handling: all operations check for errors and report complete
66
+ error information by raising an AwsError.
67
+ - Persistent HTTP connections with robust network-level retry layer using
68
+ RightHttpConnection). This includes socket timeouts and retries.
69
+ - Robust HTTP-level retry layer. Certain (user-adjustable) HTTP errors returned
70
+ by Amazon's services are classified as temporary errors.
71
+ These errors are automaticallly retried using exponentially increasing intervals.
72
+ The number of retries is user-configurable.
73
+ - Fast REXML-based parsing of responses (as fast as a pure Ruby solution allows).
74
+ - Uses libxml (if available) for faster response parsing.
75
+ - Support for large S3 list operations. Buckets and key subfolders containing
76
+ many (> 1000) keys are listed in entirety. Operations based on list (like
77
+ bucket clear) work on arbitrary numbers of keys.
78
+ - Support for streaming GETs from S3, and streaming PUTs to S3 if the data source is a file.
79
+ - Support for single-threaded usage, multithreaded usage, as well as usage with multiple
80
+ AWS accounts.
81
+ - Support for both first- and second-generation SQS (API versions 2007-05-01
82
+ and 2008-01-01). These versions of SQS are not compatible.
83
+ - Support for signature versions 0 and 1 on SQS, SDB, and EC2.
84
+ - Interoperability with any cloud running Eucalyptus (http://eucalyptus.cs.ucsb.edu)
85
+ - Test suite (requires AWS account to do "live" testing).
86
+ EOF
87
+
88
+ candidates = Dir.glob('{lib,test}/**/*') + ['History.txt', 'Manifest.txt', 'README.txt', 'Rakefile', 'right_aws.gemspec']
89
+ spec.files = candidates.sort
90
+ spec.test_files = Dir.glob('test/**/*')
91
+ end
@@ -0,0 +1,39 @@
1
+ # Notes and tips for developers
2
+
3
+ ## Setting up credentials for testing
4
+
5
+ Before you can run any tests, you need to set up credentials (API key and secret) that
6
+ will be used when talking to AWS. The credentials are loaded in `test/test_credentials.rb`
7
+ and are expected to be found in `~/.rightscale/testcredentials.rb` and look like this:
8
+
9
+ TestCredentials.aws_access_key_id= 'AAAAAAAAAAAAAAAAAAAA'
10
+ TestCredentials.aws_secret_access_key= 'asdfasdfsadf'
11
+ TestCredentials.account_number= '???'
12
+
13
+ If you prefer to store your secret key in the OS X keychain, you can do this:
14
+
15
+ def secret_access_key_from_keychain (key_id)
16
+ dump = `security -q find-generic-password -a "#{key_id}" -g 2>&1`
17
+ dump[/password: "(.*)"/, 1]
18
+ end
19
+
20
+ TestCredentials.aws_access_key_id= 'AAAAAAAAAAAAAAAAAAAA'
21
+ TestCredentials.aws_secret_access_key= secret_access_key_from_keychain(TestCredentials.aws_access_key_id)
22
+ TestCredentials.account_number= '???'
23
+
24
+ ## Running tests
25
+
26
+ There is no test suite that runs all tests. Each module is tested separately. E.g.,
27
+ to run the Load Balancer tests, run `rake testelb`. Run `rake -T` for a full list.
28
+
29
+ Some tests need to launch services on AWS to have something to test. This means two things:
30
+
31
+ 1. Running all the tests will cost you money.
32
+ 2. You will need to shut down some services separately once you are done, or things
33
+ will keep running and cost you money.
34
+
35
+ As an example, the ELB and Route 53 tests need a load balancer for testing. Starting a load balancer
36
+ for every test would make every test case cost as much as running the LB for one hour, so it makes
37
+ more sense to leave it running until it's no longer needed.
38
+
39
+ The ELB tests contain instructions for shutting down the load balancer.
File without changes
@@ -9,7 +9,7 @@ class TestAcf < Test::Unit::TestCase
9
9
  def setup
10
10
  @acf= Rightscale::AcfInterface.new(TestCredentials.aws_access_key_id, TestCredentials.aws_secret_access_key)
11
11
  @s3 = Rightscale::S3.new(TestCredentials.aws_access_key_id, TestCredentials.aws_secret_access_key)
12
- @bucket_name = "right-acf-awesome-test-bucket-0001"
12
+ @bucket_name = "right-acf-awesome-test-bucket-xxx1"
13
13
  @bucket_domain = "#{@bucket_name}.s3.amazonaws.com"
14
14
  end
15
15
 
@@ -27,13 +27,18 @@ class TestAcf < Test::Unit::TestCase
27
27
  @acf.create_distribution("right-cloudfront-awesome-test-bucket-not-exist", "Mustn't to be born", true)
28
28
  end
29
29
  # a bucket is not a domain naming complied guy
30
- bucket_name = 'right_cloudfront_awesome_test_bucket_BAD'
30
+ bucket_name = 'right_cloudfront_awesome_test_bucket_BAD_XXX'
31
31
  @s3.bucket(bucket_name, :create)
32
32
  assert_raise(Rightscale::AwsError) do
33
33
  @acf.create_distribution(bucket_name, "Mustn't to be born", true)
34
34
  end
35
35
  end
36
36
 
37
+ def test_02_x_delete_bad_bucket
38
+ bucket_name = 'right_cloudfront_awesome_test_bucket_BAD_XXX'
39
+ @s3.bucket(bucket_name, false).delete
40
+ end
41
+
37
42
  def test_03_create
38
43
  comment = 'WooHoo!!!'
39
44
  # create a test bucket
@@ -69,8 +74,8 @@ class TestAcf < Test::Unit::TestCase
69
74
  end
70
75
  # change a config
71
76
  config[:enabled] = false
72
- config[:cnames] << 'x1.myawesomesite.com'
73
- config[:cnames] << 'x2.myawesomesite.com'
77
+ config[:cnames] << 'xxx1.myawesomesite.com'
78
+ config[:cnames] << 'xxx2.myawesomesite.com'
74
79
  # set config
75
80
  set_config_result = nil
76
81
  assert_nothing_raised do
@@ -83,7 +88,7 @@ class TestAcf < Test::Unit::TestCase
83
88
  new_config = @acf.get_distribution_config(old[:aws_id])
84
89
  end
85
90
  assert !new_config[:enabled]
86
- assert_equal new_config[:cnames].sort, ['x1.myawesomesite.com', 'x2.myawesomesite.com']
91
+ assert_equal new_config[:cnames].sort, ['xxx1.myawesomesite.com', 'xxx2.myawesomesite.com']
87
92
  assert_not_equal config[:e_tag], new_config[:e_tag]
88
93
 
89
94
  # try to update the old config again (must fail because ETAG has changed)
@@ -92,19 +97,6 @@ class TestAcf < Test::Unit::TestCase
92
97
  end
93
98
  end
94
99
 
95
- def test_07_caching
96
- # enable caching
97
- @acf.params[:cache] = true
98
- # list distributions
99
- @acf.list_distributions
100
- # list the distributions again - cache should hit
101
- assert_raise(Rightscale::AwsNoChange) do
102
- @acf.list_distributions
103
- end
104
- # disable caching
105
- @acf.params[:cache] = true
106
- end
107
-
108
100
  def test_08_delete_distribution
109
101
  # we need ETAG so use get_distribution
110
102
  distribution = @acf.get_distribution(get_test_distribution[:aws_id])