icehouse-right_aws 1.11.0 → 2.2.0
Sign up to get free protection for your applications and to get access to all the features.
- data/History.txt +93 -15
- data/Manifest.txt +15 -1
- data/README.txt +0 -4
- data/Rakefile +34 -17
- data/lib/acf/right_acf_interface.rb +260 -124
- data/lib/acf/right_acf_invalidations.rb +144 -0
- data/lib/acf/right_acf_origin_access_identities.rb +230 -0
- data/lib/acf/right_acf_streaming_interface.rb +229 -0
- data/lib/acw/right_acw_interface.rb +4 -5
- data/lib/as/right_as_interface.rb +59 -51
- data/lib/awsbase/benchmark_fix.rb +0 -0
- data/lib/awsbase/right_awsbase.rb +351 -104
- data/lib/awsbase/support.rb +2 -82
- data/lib/awsbase/version.rb +9 -0
- data/lib/ec2/right_ec2.rb +97 -246
- data/lib/ec2/right_ec2_ebs.rb +88 -68
- data/lib/ec2/right_ec2_images.rb +90 -50
- data/lib/ec2/right_ec2_instances.rb +118 -89
- data/lib/ec2/right_ec2_placement_groups.rb +108 -0
- data/lib/ec2/right_ec2_reserved_instances.rb +51 -44
- data/lib/ec2/right_ec2_security_groups.rb +396 -0
- data/lib/ec2/right_ec2_spot_instances.rb +425 -0
- data/lib/ec2/right_ec2_tags.rb +139 -0
- data/lib/ec2/right_ec2_vpc.rb +152 -140
- data/lib/ec2/right_ec2_windows_mobility.rb +84 -0
- data/lib/elb/right_elb_interface.rb +205 -39
- data/lib/iam/right_iam_access_keys.rb +71 -0
- data/lib/iam/right_iam_groups.rb +195 -0
- data/lib/iam/right_iam_interface.rb +341 -0
- data/lib/iam/right_iam_mfa_devices.rb +67 -0
- data/lib/iam/right_iam_users.rb +251 -0
- data/lib/rds/right_rds_interface.rb +591 -205
- data/lib/right_aws.rb +16 -12
- data/lib/route_53/right_route_53_interface.rb +640 -0
- data/lib/s3/right_s3.rb +34 -13
- data/lib/s3/right_s3_interface.rb +17 -14
- data/lib/sdb/active_sdb.rb +215 -38
- data/lib/sdb/right_sdb_interface.rb +93 -12
- data/lib/sqs/right_sqs.rb +1 -2
- data/lib/sqs/right_sqs_gen2.rb +0 -1
- data/lib/sqs/right_sqs_gen2_interface.rb +9 -9
- data/lib/sqs/right_sqs_interface.rb +6 -7
- data/right_aws.gemspec +91 -0
- data/test/README.mdown +39 -0
- data/test/acf/test_helper.rb +0 -0
- data/test/acf/test_right_acf.rb +10 -18
- data/test/awsbase/test_helper.rb +0 -0
- data/test/awsbase/test_right_awsbase.rb +0 -1
- data/test/ec2/test_helper.rb +0 -0
- data/test/ec2/test_right_ec2.rb +0 -1
- data/test/elb/test_helper.rb +2 -0
- data/test/elb/test_right_elb.rb +43 -0
- data/test/http_connection.rb +0 -0
- data/test/route_53/fixtures/a_record.xml +18 -0
- data/test/route_53/fixtures/alias_record.xml +18 -0
- data/test/route_53/test_helper.rb +2 -0
- data/test/route_53/test_right_route_53.rb +141 -0
- data/test/s3/test_helper.rb +0 -0
- data/test/s3/test_right_s3.rb +11 -9
- data/test/s3/test_right_s3_stubbed.rb +6 -4
- data/test/sdb/test_active_sdb.rb +71 -13
- data/test/sdb/test_batch_put_attributes.rb +54 -0
- data/test/sdb/test_helper.rb +0 -0
- data/test/sdb/test_right_sdb.rb +13 -7
- data/test/sqs/test_helper.rb +0 -0
- data/test/sqs/test_right_sqs.rb +0 -6
- data/test/sqs/test_right_sqs_gen2.rb +22 -34
- data/test/test_credentials.rb +0 -0
- data/test/ts_right_aws.rb +0 -0
- metadata +146 -16
- 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', {:
|
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(
|
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)
|
103
|
-
|
104
|
-
|
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.
|
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.
|
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
|
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 => [] }
|
data/lib/sqs/right_sqs.rb
CHANGED
@@ -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.
|
273
|
+
grantees.right_blank? ? nil : grantees.shift
|
275
274
|
else
|
276
275
|
grantees
|
277
276
|
end
|
data/lib/sqs/right_sqs_gen2.rb
CHANGED
@@ -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', {:
|
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.
|
205
|
-
params = amazonize_list('AttributeName', attributes
|
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
|
249
|
-
params.merge!(amazonize_list('ActionName', actions
|
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 =
|
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.
|
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', {:
|
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.
|
108
|
-
request = "Net::HTTP::#{method.capitalize}".
|
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.
|
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.
|
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.
|
484
|
+
messages.right_blank? ? nil : messages[0]
|
486
485
|
rescue
|
487
486
|
on_exception
|
488
487
|
end
|
data/right_aws.gemspec
ADDED
@@ -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
|
data/test/README.mdown
ADDED
@@ -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.
|
data/test/acf/test_helper.rb
CHANGED
File without changes
|
data/test/acf/test_right_acf.rb
CHANGED
@@ -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-
|
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 = '
|
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] << '
|
73
|
-
config[:cnames] << '
|
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, ['
|
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])
|