aws 2.3.34 → 2.4.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.
@@ -1,232 +0,0 @@
1
- module Aws
2
-
3
- class Mon < Aws::AwsBase
4
- include Aws::AwsBaseInterface
5
-
6
-
7
- #Amazon EC2 API version being used
8
- API_VERSION = "2009-05-15"
9
- DEFAULT_HOST = "monitoring.amazonaws.com"
10
- DEFAULT_PATH = '/'
11
- DEFAULT_PROTOCOL = 'https'
12
- DEFAULT_PORT = 443
13
-
14
- # Available measures for EC2 instances:
15
- # NetworkIn NetworkOut DiskReadOps DiskWriteOps DiskReadBytes DiskWriteBytes CPUUtilization
16
- measures=%w(NetworkIn NetworkOut DiskReadOps DiskWriteOps DiskReadBytes DiskWriteBytes CPUUtilization)
17
-
18
- @@bench = Aws::AwsBenchmarkingBlock.new
19
-
20
- def self.bench_xml
21
- @@bench.xml
22
- end
23
-
24
- def self.bench_ec2
25
- @@bench.service
26
- end
27
-
28
- # Current API version (sometimes we have to check it outside the GEM).
29
- @@api = ENV['EC2_API_VERSION'] || API_VERSION
30
-
31
- def self.api
32
- @@api
33
- end
34
-
35
-
36
- def initialize(aws_access_key_id=nil, aws_secret_access_key=nil, params={})
37
- init({ :name => 'MON',
38
- :default_host => ENV['MON_URL'] ? URI.parse(ENV['MON_URL']).host : DEFAULT_HOST,
39
- :default_port => ENV['MON_URL'] ? URI.parse(ENV['MON_URL']).port : DEFAULT_PORT,
40
- :default_service => ENV['MON_URL'] ? URI.parse(ENV['MON_URL']).path : DEFAULT_PATH,
41
- :default_protocol => ENV['MON_URL'] ? URI.parse(ENV['MON_URL']).scheme : DEFAULT_PROTOCOL,
42
- :api_version => API_VERSION },
43
- aws_access_key_id || ENV['AWS_ACCESS_KEY_ID'],
44
- aws_secret_access_key|| ENV['AWS_SECRET_ACCESS_KEY'],
45
- params)
46
- end
47
-
48
-
49
- def generate_request(action, params={})
50
- service_hash = {"Action" => action,
51
- "AWSAccessKeyId" => @aws_access_key_id,
52
- "Version" => @@api }
53
- service_hash.update(params)
54
- service_params = signed_service_params(@aws_secret_access_key, service_hash, :get, @params[:server], @params[:service])
55
-
56
- # use POST method if the length of the query string is too large
57
- if service_params.size > 2000
58
- if signature_version == '2'
59
- # resign the request because HTTP verb is included into signature
60
- service_params = signed_service_params(@aws_secret_access_key, service_hash, :post, @params[:server], @params[:service])
61
- end
62
- request = Net::HTTP::Post.new(service)
63
- request.body = service_params
64
- request['Content-Type'] = 'application/x-www-form-urlencoded'
65
- else
66
- request = Net::HTTP::Get.new("#{@params[:service]}?#{service_params}")
67
- end
68
-
69
- #puts "\n\n --------------- QUERY REQUEST TO AWS -------------- \n\n"
70
- #puts "#{@params[:service]}?#{service_params}\n\n"
71
-
72
- # prepare output hash
73
- { :request => request,
74
- :server => @params[:server],
75
- :port => @params[:port],
76
- :protocol => @params[:protocol] }
77
- end
78
-
79
-
80
- # Sends request to Amazon and parses the response
81
- # Raises AwsError if any banana happened
82
- def request_info(request, parser, options={})
83
- conn = get_conn(:mon_connection, @params, @logger)
84
- request_info_impl(conn, @@bench, request, parser, options)
85
- end
86
-
87
- #-----------------------------------------------------------------
88
- # REQUESTS
89
- #-----------------------------------------------------------------
90
-
91
- def list_metrics(options={})
92
-
93
- next_token = options[:next_token] || nil
94
-
95
- params = { }
96
- params['NextToken'] = next_token unless next_token.nil?
97
-
98
- @logger.info("list Metrics ")
99
-
100
- link = generate_request("ListMetrics", params)
101
- resp = request_info(link, QMonListMetrics.new(:logger => @logger))
102
-
103
- rescue Exception
104
- on_exception
105
- end
106
-
107
-
108
- # measureName: CPUUtilization (Units: Percent), NetworkIn (Units: Bytes), NetworkOut (Units: Bytes), DiskWriteOps (Units: Count)
109
- # DiskReadBytes (Units: Bytes), DiskReadOps (Units: Count), DiskWriteBytes (Units: Bytes)
110
- # stats: array containing one or more of Minimum, Maximum, Sum, Average, Samples
111
- # start_time : Timestamp to start
112
- # end_time: Timestamp to end
113
- # unit: Either Seconds, Percent, Bytes, Bits, Count, Bytes, Bits/Second, Count/Second, and None
114
- #
115
- # Optional parameters:
116
- # period: Integer 60 or multiple of 60
117
- # dimensions: Hash containing keys ImageId, AutoScalingGroupName, InstanceId, InstanceType
118
- # customUnit: nil. not supported currently.
119
- # namespace: AWS/EC2
120
-
121
- def get_metric_statistics ( measure_name, stats, start_time, end_time, unit, options={})
122
-
123
- period = options[:period] || 60
124
- dimensions = options[:dimensions] || nil
125
- custom_unit = options[:custom_unit] || nil
126
- namespace = options[:namespace] || "AWS/EC2"
127
-
128
- params = {}
129
- params['MeasureName'] = measure_name
130
- i=1
131
- stats.each do |s|
132
- params['Statistics.member.'+i.to_s] = s
133
- i = i+1
134
- end
135
- params['Period'] = period
136
- if (dimensions != nil)
137
- i = 1
138
- dimensions.each do |k, v|
139
- params['Dimensions.member.'+i.to_s+".Name."+i.to_s] = k
140
- params['Dimensions.member.'+i.to_s+".Value."+i.to_s] = v
141
- i = i+1
142
- end
143
- end
144
- params['StartTime'] = start_time
145
- params['EndTime'] = end_time
146
- params['Unit'] = unit
147
- #params['CustomUnit'] = customUnit always nil
148
- params['Namespace'] = namespace
149
-
150
- link = generate_request("GetMetricStatistics", params)
151
- resp = request_info(link, QMonGetMetricStatistics.new(:logger => @logger))
152
-
153
- rescue Exception
154
- on_exception
155
- end
156
-
157
-
158
- #-----------------------------------------------------------------
159
- # PARSERS: Instances
160
- #-----------------------------------------------------------------
161
-
162
-
163
- class QMonGetMetricStatistics < Aws::AwsParser
164
-
165
- def reset
166
- @result = []
167
- end
168
-
169
- def tagstart(name, attributes)
170
- @metric = {} if name == 'member'
171
- end
172
-
173
- def tagend(name)
174
- case name
175
- when 'Timestamp' then
176
- @metric[:timestamp] = @text
177
- when 'Samples' then
178
- @metric[:samples] = @text
179
- when 'Unit' then
180
- @metric[:unit] = @text
181
- when 'Average' then
182
- @metric[:average] = @text
183
- when 'Minimum' then
184
- @metric[:minimum] = @text
185
- when 'Maximum' then
186
- @metric[:maximum] = @text
187
- when 'Sum' then
188
- @metric[:sum] = @text
189
- when 'Value' then
190
- @metric[:value] = @text
191
- when 'member' then
192
- @result << @metric
193
- end
194
- end
195
- end
196
-
197
- class QMonListMetrics < Aws::AwsParser
198
-
199
- def reset
200
- @result = []
201
- @namespace = ""
202
- @measure_name = ""
203
- end
204
-
205
- def tagstart(name, attributes)
206
- @metric = {} if name == 'member'
207
- end
208
-
209
- def tagend(name)
210
- case name
211
- when 'MeasureName' then
212
- @measure_name = @text
213
- when 'Namespace' then
214
- @namespace = @text
215
- when 'Name' then
216
- @metric[:name] = @text
217
- when 'Value' then
218
- @metric[:value] = @text
219
- when 'member' then
220
- @metric[:namespace] = @namespace
221
- @metric[:measure_name] = @measure_name
222
- @result << @metric
223
- end
224
- end
225
- end
226
-
227
-
228
- end
229
-
230
-
231
- end
232
-
@@ -1,1115 +0,0 @@
1
- #
2
- # Copyright (c) 2007-2008 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
18
- # NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
19
- # LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
20
- # OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
21
- # WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
22
- #
23
-
24
- module Aws
25
-
26
- # = Aws::S3 -- RightScale's Amazon S3 interface
27
- # The Aws::S3 class provides a complete interface to Amazon's Simple
28
- # Storage Service.
29
- # For explanations of the semantics
30
- # of each call, please refer to Amazon's documentation at
31
- # http://developer.amazonwebservices.com/connect/kbcategory.jspa?categoryID=48
32
- #
33
- # See examples below for the bucket and buckets methods.
34
- #
35
- # Error handling: all operations raise an Aws::AwsError in case
36
- # of problems. Note that transient errors are automatically retried.
37
- #
38
- # It is a good way to use domain naming style getting a name for the buckets.
39
- # See http://docs.amazonwebservices.com/AmazonS3/2006-03-01/UsingBucket.html
40
- # about the naming convention for the buckets. This case they can be accessed using a virtual domains.
41
- #
42
- # Let assume you have 3 buckets: 'awesome-bucket', 'awesome_bucket' and 'AWEsomE-bucket'.
43
- # The first ones objects can be accessed as: http:// awesome-bucket.s3.amazonaws.com/key/object
44
- #
45
- # But the rest have to be accessed as:
46
- # http:// s3.amazonaws.com/awesome_bucket/key/object and http:// s3.amazonaws.com/AWEsomE-bucket/key/object
47
- #
48
- # See: http://docs.amazonwebservices.com/AmazonS3/2006-03-01/VirtualHosting.html for better explanation.
49
- #
50
- class S3
51
- attr_reader :interface
52
-
53
- # Create a new handle to an S3 account. All handles share the same per process or per thread
54
- # HTTP connection to Amazon S3. Each handle is for a specific account.
55
- # The +params+ are passed through as-is to Aws::S3Interface.new
56
- #
57
- # Params is a hash:
58
- #
59
- # {:server => 's3.amazonaws.com' # Amazon service host: 's3.amazonaws.com'(default)
60
- # :port => 443 # Amazon service port: 80 or 443(default)
61
- # :protocol => 'https' # Amazon service protocol: 'http' or 'https'(default)
62
- # :connection_mode => :default # options are
63
- # :default (will use best known safe (as in won't need explicit close) option, may change in the future)
64
- # :per_request (opens and closes a connection on every request)
65
- # :single (one thread across entire app)
66
- # :per_thread (one connection per thread)
67
- # :logger => Logger Object} # Logger instance: logs to STDOUT if omitted }
68
- def initialize(aws_access_key_id=nil, aws_secret_access_key=nil, params={})
69
- @interface = S3Interface.new(aws_access_key_id, aws_secret_access_key, params)
70
- end
71
-
72
- def close_connection
73
- @interface.close_connection
74
- end
75
-
76
- # Retrieve a list of buckets.
77
- # Returns an array of Aws::S3::Bucket instances.
78
- # # Create handle to S3 account
79
- # s3 = Aws::S3.new(aws_access_key_id, aws_secret_access_key)
80
- # my_buckets_names = s3.buckets.map{|b| b.name}
81
- # puts "Buckets on S3: #{my_bucket_names.join(', ')}"
82
- def buckets
83
- @interface.list_all_my_buckets.map! do |entry|
84
- owner = Owner.new(entry[:owner_id], entry[:owner_display_name])
85
- Bucket.new(self, entry[:name], entry[:creation_date], owner)
86
- end
87
- end
88
-
89
- # Retrieve an individual bucket.
90
- # If the bucket does not exist and +create+ is set, a new bucket
91
- # is created on S3. Launching this method with +create+=+true+ may
92
- # affect on the bucket's ACL if the bucket already exists.
93
- # Returns a Aws::S3::Bucket instance or +nil+ if the bucket does not exist
94
- # and +create+ is not set.
95
- #
96
- # s3 = Aws::S3.new(aws_access_key_id, aws_secret_access_key)
97
- # bucket1 = s3.bucket('my_awesome_bucket_1')
98
- # bucket1.keys #=> exception here if the bucket does not exists
99
- # ...
100
- # bucket2 = s3.bucket('my_awesome_bucket_2', true)
101
- # bucket2.keys #=> list of keys
102
- # # create a bucket at the European location with public read access
103
- # bucket3 = s3.bucket('my-awesome-bucket-3', true, 'public-read', :location => :eu)
104
- #
105
- # see http://docs.amazonwebservices.com/AmazonS3/2006-03-01/RESTAccessPolicy.html
106
- # (section: Canned Access Policies)
107
- #
108
- def bucket(name, create=false, perms=nil, headers={})
109
- headers['x-amz-acl'] = perms if perms
110
- @interface.create_bucket(name, headers) if create
111
- return Bucket.new(self, name)
112
- # The old way below was too slow and unnecessary because it retreived all the buckets every time.
113
- # owner = Owner.new(entry[:owner_id], entry[:owner_display_name])
114
- # buckets.each { |bucket| return bucket if bucket.name == name }
115
- # nil
116
- end
117
-
118
-
119
- class Bucket
120
- attr_reader :s3, :name, :owner, :creation_date
121
-
122
- # Create a Bucket instance.
123
- # If the bucket does not exist and +create+ is set, a new bucket
124
- # is created on S3. Launching this method with +create+=+true+ may
125
- # affect on the bucket's ACL if the bucket already exists.
126
- # Returns Bucket instance or +nil+ if the bucket does not exist
127
- # and +create+ is not set.
128
- #
129
- # s3 = Aws::S3.new(aws_access_key_id, aws_secret_access_key)
130
- # ...
131
- # bucket1 = Aws::S3::Bucket.create(s3, 'my_awesome_bucket_1')
132
- # bucket1.keys #=> exception here if the bucket does not exists
133
- # ...
134
- # bucket2 = Aws::S3::Bucket.create(s3, 'my_awesome_bucket_2', true)
135
- # bucket2.keys #=> list of keys
136
- # # create a bucket at the European location with public read access
137
- # bucket3 = Aws::S3::Bucket.create(s3,'my-awesome-bucket-3', true, 'public-read', :location => :eu)
138
- #
139
- # see http://docs.amazonwebservices.com/AmazonS3/2006-03-01/RESTAccessPolicy.html
140
- # (section: Canned Access Policies)
141
- #
142
- def self.create(s3, name, create=false, perms=nil, headers={})
143
- s3.bucket(name, create, perms, headers)
144
- end
145
-
146
-
147
- # Create a bucket instance. In normal use this method should
148
- # not be called directly.
149
- # Use Aws::S3::Bucket.create or Aws::S3.bucket instead.
150
- def initialize(s3, name, creation_date=nil, owner=nil)
151
- @s3 = s3
152
- @name = name
153
- @owner = owner
154
- @creation_date = creation_date
155
- if @creation_date && !@creation_date.is_a?(Time)
156
- @creation_date = Time.parse(@creation_date)
157
- end
158
- end
159
-
160
- # Return bucket name as a String.
161
- #
162
- # bucket = Aws::S3.bucket('my_awesome_bucket')
163
- # puts bucket #=> 'my_awesome_bucket'
164
- #
165
- def to_s
166
- @name.to_s
167
- end
168
-
169
- alias_method :full_name, :to_s
170
-
171
- # Return a public link to bucket.
172
- #
173
- # bucket.public_link #=> 'https://s3.amazonaws.com:443/my_awesome_bucket'
174
- #
175
- def public_link
176
- params = @s3.interface.params
177
- "#{params[:protocol]}://#{params[:server]}:#{params[:port]}/#{full_name}"
178
- end
179
-
180
- # Returns the bucket location
181
- def location
182
- @location ||= @s3.interface.bucket_location(@name)
183
- end
184
-
185
- # Retrieves the logging configuration for a bucket.
186
- # Returns a hash of {:enabled, :targetbucket, :targetprefix}
187
- #
188
- # bucket.logging_info()
189
- # => {:enabled=>true, :targetbucket=>"mylogbucket", :targetprefix=>"loggylogs/"}
190
- def logging_info
191
- @s3.interface.get_logging_parse(:bucket => @name)
192
- end
193
-
194
- # Enables S3 server access logging on a bucket. The target bucket must have been properly configured to receive server
195
- # access logs.
196
- # Params:
197
- # :targetbucket - either the target bucket object or the name of the target bucket
198
- # :targetprefix - the prefix under which all logs should be stored
199
- #
200
- # bucket.enable_logging(:targetbucket=>"mylogbucket", :targetprefix=>"loggylogs/")
201
- # => true
202
- def enable_logging(params)
203
- AwsUtils.mandatory_arguments([:targetbucket, :targetprefix], params)
204
- AwsUtils.allow_only([:targetbucket, :targetprefix], params)
205
- xmldoc = "<?xml version=\"1.0\" encoding=\"UTF-8\"?><BucketLoggingStatus xmlns=\"http://doc.s3.amazonaws.com/2006-03-01\"><LoggingEnabled><TargetBucket>#{params[:targetbucket]}</TargetBucket><TargetPrefix>#{params[:targetprefix]}</TargetPrefix></LoggingEnabled></BucketLoggingStatus>"
206
- @s3.interface.put_logging(:bucket => @name, :xmldoc => xmldoc)
207
- end
208
-
209
- # Disables S3 server access logging on a bucket. Takes no arguments.
210
- def disable_logging
211
- xmldoc = "<?xml version=\"1.0\" encoding=\"UTF-8\"?><BucketLoggingStatus xmlns=\"http://doc.s3.amazonaws.com/2006-03-01\"></BucketLoggingStatus>"
212
- @s3.interface.put_logging(:bucket => @name, :xmldoc => xmldoc)
213
- end
214
-
215
- # Retrieve a group of keys from Amazon.
216
- # +options+ is a hash: { 'prefix'=>'', 'marker'=>'', 'max-keys'=>5, 'delimiter'=>'' }).
217
- # Retrieves meta-headers information if +head+ it +true+.
218
- # Returns an array of Key instances.
219
- #
220
- # bucket.keys #=> # returns all keys from bucket
221
- # bucket.keys('prefix' => 'logs') #=> # returns all keys that starts with 'logs'
222
- #
223
- def keys(options={}, head=false)
224
- keys_and_service(options, head)[0]
225
- end
226
-
227
- # Same as +keys+ method but return an array of [keys, service_data].
228
- # where +service_data+ is a hash with additional output information.
229
- #
230
- # keys, service = bucket.keys_and_service({'max-keys'=> 2, 'prefix' => 'logs'})
231
- # p keys #=> # 2 keys array
232
- # p service #=> {"max-keys"=>"2", "prefix"=>"logs", "name"=>"my_awesome_bucket", "marker"=>"", "is_truncated"=>true}
233
- #
234
- def keys_and_service(options={}, head=false)
235
- opt = {}; options.each { |key, value| opt[key.to_s] = value }
236
- service_data = {}
237
- thislist = {}
238
- list = []
239
- @s3.interface.incrementally_list_bucket(@name, opt) do |thislist|
240
- thislist[:contents].each do |entry|
241
- owner = Owner.new(entry[:owner_id], entry[:owner_display_name])
242
- key = Key.new(self, entry[:key], nil, {}, {}, entry[:last_modified], entry[:e_tag], entry[:size], entry[:storage_class], owner)
243
- key.head if head
244
- list << key
245
- end
246
- end
247
- thislist.each_key do |key|
248
- service_data[key] = thislist[key] unless (key == :contents || key == :common_prefixes)
249
- end
250
- [list, service_data]
251
- end
252
-
253
- # Retrieve key information from Amazon.
254
- # The +key_name+ is a +String+ or Key instance.
255
- # Retrieves meta-header information if +head+ is +true+.
256
- # Returns new Key instance.
257
- #
258
- # key = bucket.key('logs/today/1.log', true) #=> #<Aws::S3::Key:0xb7b1e240 ... >
259
- # # is the same as:
260
- # key = Aws::S3::Key.create(bucket, 'logs/today/1.log')
261
- # key.head
262
- #
263
- def key(key_name, head=false)
264
- raise 'Key name can not be empty.' if key_name.blank?
265
- key_instance = nil
266
- # if this key exists - find it ....
267
- keys({'prefix'=>key_name}, head).each do |key|
268
- if key.name == key_name.to_s
269
- key_instance = key
270
- break
271
- end
272
- end
273
- # .... else this key is unknown
274
- unless key_instance
275
- key_instance = Key.create(self, key_name.to_s)
276
- end
277
- key_instance
278
- end
279
-
280
- # Store object data.
281
- # The +key+ is a +String+ or Key instance.
282
- # Returns +true+.
283
- #
284
- # bucket.put('logs/today/1.log', 'Olala!') #=> true
285
- #
286
- def put(key, data=nil, meta_headers={}, perms=nil, headers={})
287
- key = Key.create(self, key.to_s, data, meta_headers) unless key.is_a?(Key)
288
- key.put(data, perms, headers)
289
- end
290
-
291
- # Retrieve object data from Amazon.
292
- # The +key+ is a +String+ or Key.
293
- # Returns Key instance.
294
- #
295
- # key = bucket.get('logs/today/1.log') #=>
296
- # puts key.data #=> 'sasfasfasdf'
297
- #
298
- def get(key, headers={})
299
- key = Key.create(self, key.to_s) unless key.is_a?(Key)
300
- key.get(headers)
301
- end
302
-
303
- # Rename object. Returns Aws::S3::Key instance.
304
- #
305
- # new_key = bucket.rename_key('logs/today/1.log','logs/today/2.log') #=> #<Aws::S3::Key:0xb7b1e240 ... >
306
- # puts key.name #=> 'logs/today/2.log'
307
- # key.exists? #=> true
308
- #
309
- def rename_key(old_key_or_name, new_name)
310
- old_key_or_name = Key.create(self, old_key_or_name.to_s) unless old_key_or_name.is_a?(Key)
311
- old_key_or_name.rename(new_name)
312
- old_key_or_name
313
- end
314
-
315
- # Create an object copy. Returns a destination Aws::S3::Key instance.
316
- #
317
- # new_key = bucket.copy_key('logs/today/1.log','logs/today/2.log') #=> #<Aws::S3::Key:0xb7b1e240 ... >
318
- # puts key.name #=> 'logs/today/2.log'
319
- # key.exists? #=> true
320
- #
321
- def copy_key(old_key_or_name, new_key_or_name)
322
- old_key_or_name = Key.create(self, old_key_or_name.to_s) unless old_key_or_name.is_a?(Key)
323
- old_key_or_name.copy(new_key_or_name)
324
- end
325
-
326
- # Move an object to other location. Returns a destination Aws::S3::Key instance.
327
- #
328
- # new_key = bucket.copy_key('logs/today/1.log','logs/today/2.log') #=> #<Aws::S3::Key:0xb7b1e240 ... >
329
- # puts key.name #=> 'logs/today/2.log'
330
- # key.exists? #=> true
331
- #
332
- def move_key(old_key_or_name, new_key_or_name)
333
- old_key_or_name = Key.create(self, old_key_or_name.to_s) unless old_key_or_name.is_a?(Key)
334
- old_key_or_name.move(new_key_or_name)
335
- end
336
-
337
- # Remove all keys from a bucket.
338
- # Returns +true+.
339
- #
340
- # bucket.clear #=> true
341
- #
342
- def clear
343
- @s3.interface.clear_bucket(@name)
344
- end
345
-
346
- # Delete all keys where the 'folder_key' can be interpreted
347
- # as a 'folder' name.
348
- # Returns an array of string keys that have been deleted.
349
- #
350
- # bucket.keys.map{|key| key.name}.join(', ') #=> 'test, test/2/34, test/3, test1, test1/logs'
351
- # bucket.delete_folder('test') #=> ['test','test/2/34','test/3']
352
- #
353
- def delete_folder(folder, separator='/')
354
- @s3.interface.delete_folder(@name, folder, separator)
355
- end
356
-
357
- # Delete a bucket. Bucket must be empty.
358
- # If +force+ is set, clears and deletes the bucket.
359
- # Returns +true+.
360
- #
361
- # bucket.delete(true) #=> true
362
- #
363
- def delete(force=false)
364
- force ? @s3.interface.force_delete_bucket(@name) : @s3.interface.delete_bucket(@name)
365
- end
366
-
367
- # Deletes an object from s3 in this bucket.
368
- def delete_key(key)
369
- @s3.interface.delete(name, key)
370
- end
371
-
372
- # Return a list of grantees.
373
- #
374
- def grantees
375
- Grantee::grantees(self)
376
- end
377
-
378
- end
379
-
380
-
381
- class Key
382
- attr_reader :bucket, :name, :last_modified, :e_tag, :size, :storage_class, :owner
383
- attr_accessor :headers, :meta_headers
384
- attr_writer :data
385
-
386
- # Separate Amazon meta headers from other headers
387
- def self.split_meta(headers) #:nodoc:
388
- hash = headers.dup
389
- meta = {}
390
- hash.each do |key, value|
391
- if key[/^#{S3Interface::AMAZON_METADATA_PREFIX}/]
392
- meta[key.gsub(S3Interface::AMAZON_METADATA_PREFIX, '')] = value
393
- hash.delete(key)
394
- end
395
- end
396
- [hash, meta]
397
- end
398
-
399
- def self.add_meta_prefix(meta_headers, prefix=S3Interface::AMAZON_METADATA_PREFIX)
400
- meta = {}
401
- meta_headers.each do |meta_header, value|
402
- if meta_header[/#{prefix}/]
403
- meta[meta_header] = value
404
- else
405
- meta["#{S3Interface::AMAZON_METADATA_PREFIX}#{meta_header}"] = value
406
- end
407
- end
408
- meta
409
- end
410
-
411
-
412
- # Create a new Key instance, but do not create the actual key.
413
- # The +name+ is a +String+.
414
- # Returns a new Key instance.
415
- #
416
- # key = Aws::S3::Key.create(bucket, 'logs/today/1.log') #=> #<Aws::S3::Key:0xb7b1e240 ... >
417
- # key.exists? #=> true | false
418
- # key.put('Woohoo!') #=> true
419
- # key.exists? #=> true
420
- #
421
- def self.create(bucket, name, data=nil, meta_headers={})
422
- new(bucket, name, data, {}, meta_headers)
423
- end
424
-
425
- # Create a new Key instance, but do not create the actual key.
426
- # In normal use this method should not be called directly.
427
- # Use Aws::S3::Key.create or bucket.key() instead.
428
- #
429
- def initialize(bucket, name, data=nil, headers={}, meta_headers={},
430
- last_modified=nil, e_tag=nil, size=nil, storage_class=nil, owner=nil)
431
- raise 'Bucket must be a Bucket instance.' unless bucket.is_a?(Bucket)
432
- @bucket = bucket
433
- @name = name
434
- @data = data
435
- @e_tag = e_tag
436
- @size = size.to_i
437
- @storage_class = storage_class
438
- @owner = owner
439
- @last_modified = last_modified
440
- if @last_modified && !@last_modified.is_a?(Time)
441
- @last_modified = Time.parse(@last_modified)
442
- end
443
- @headers, @meta_headers = self.class.split_meta(headers)
444
- @meta_headers.merge!(meta_headers)
445
- end
446
-
447
- # Return key name as a String.
448
- #
449
- # key = Aws::S3::Key.create(bucket, 'logs/today/1.log') #=> #<Aws::S3::Key:0xb7b1e240 ... >
450
- # puts key #=> 'logs/today/1.log'
451
- #
452
- def to_s
453
- @name.to_s
454
- end
455
-
456
- # Return the full S3 path to this key (bucket/key).
457
- #
458
- # key.full_name #=> 'my_awesome_bucket/cool_key'
459
- #
460
- def full_name(separator='/')
461
- "#{@bucket.to_s}#{separator}#{@name}"
462
- end
463
-
464
- # Return a public link to a key.
465
- #
466
- # key.public_link #=> 'https://s3.amazonaws.com:443/my_awesome_bucket/cool_key'
467
- #
468
- def public_link
469
- params = @bucket.s3.interface.params
470
- "#{params[:protocol]}://#{params[:server]}:#{params[:port]}/#{full_name('/')}"
471
- end
472
-
473
- # Return Key data. Retrieve this data from Amazon if it is the first time call.
474
- # TODO TRB 6/19/07 What does the above mean? Clarify.
475
- #
476
- def data
477
- get if !@data and exists?
478
- @data
479
- end
480
-
481
- # Retrieve object data and attributes from Amazon.
482
- # Returns a +String+.
483
- #
484
- def get(headers={}, &block)
485
- response = @bucket.s3.interface.get(@bucket.name, @name, headers, &block)
486
- @data = response[:object]
487
- @headers, @meta_headers = self.class.split_meta(response[:headers])
488
- # refresh(false) Holy moly, this was doing two extra hits to s3 for making 3 hits for every get!!
489
- @data
490
- end
491
-
492
- # Store object data on S3.
493
- # Parameter +data+ is a +String+ or S3Object instance.
494
- # Returns +true+.
495
- #
496
- # key = Aws::S3::Key.create(bucket, 'logs/today/1.log')
497
- # key.data = 'Qwerty'
498
- # key.put #=> true
499
- # ...
500
- # key.put('Olala!') #=> true
501
- #
502
- def put(data=nil, perms=nil, headers={})
503
- headers['x-amz-acl'] = perms if perms
504
- @data = data || @data
505
- meta = self.class.add_meta_prefix(@meta_headers)
506
- @bucket.s3.interface.put(@bucket.name, @name, @data, meta.merge(headers))
507
- end
508
-
509
- # Rename an object. Returns new object name.
510
- #
511
- # key = Aws::S3::Key.create(bucket, 'logs/today/1.log') #=> #<Aws::S3::Key:0xb7b1e240 ... >
512
- # key.rename('logs/today/2.log') #=> 'logs/today/2.log'
513
- # puts key.name #=> 'logs/today/2.log'
514
- # key.exists? #=> true
515
- #
516
- def rename(new_name)
517
- @bucket.s3.interface.rename(@bucket.name, @name, new_name)
518
- @name = new_name
519
- end
520
-
521
- # Create an object copy. Returns a destination Aws::S3::Key instance.
522
- #
523
- # # Key instance as destination
524
- # key1 = Aws::S3::Key.create(bucket, 'logs/today/1.log') #=> #<Aws::S3::Key:0xb7b1e240 ... >
525
- # key2 = Aws::S3::Key.create(bucket, 'logs/today/2.log') #=> #<Aws::S3::Key:0xb7b5e240 ... >
526
- # key1.put('Olala!') #=> true
527
- # key1.copy(key2) #=> #<Aws::S3::Key:0xb7b5e240 ... >
528
- # key1.exists? #=> true
529
- # key2.exists? #=> true
530
- # puts key2.data #=> 'Olala!'
531
- #
532
- # # String as destination
533
- # key = Aws::S3::Key.create(bucket, 'logs/today/777.log') #=> #<Aws::S3::Key:0xb7b1e240 ... >
534
- # key.put('Olala!') #=> true
535
- # new_key = key.copy('logs/today/888.log') #=> #<Aws::S3::Key:0xb7b5e240 ... >
536
- # key.exists? #=> true
537
- # new_key.exists? #=> true
538
- #
539
- def copy(new_key_or_name)
540
- new_key_or_name = Key.create(@bucket, new_key_or_name.to_s) unless new_key_or_name.is_a?(Key)
541
- @bucket.s3.interface.copy(@bucket.name, @name, new_key_or_name.bucket.name, new_key_or_name.name)
542
- new_key_or_name
543
- end
544
-
545
- # Move an object to other location. Returns a destination Aws::S3::Key instance.
546
- #
547
- # # Key instance as destination
548
- # key1 = Aws::S3::Key.create(bucket, 'logs/today/1.log') #=> #<Aws::S3::Key:0xb7b1e240 ... >
549
- # key2 = Aws::S3::Key.create(bucket, 'logs/today/2.log') #=> #<Aws::S3::Key:0xb7b5e240 ... >
550
- # key1.put('Olala!') #=> true
551
- # key1.move(key2) #=> #<Aws::S3::Key:0xb7b5e240 ... >
552
- # key1.exists? #=> false
553
- # key2.exists? #=> true
554
- # puts key2.data #=> 'Olala!'
555
- #
556
- # # String as destination
557
- # key = Aws::S3::Key.create(bucket, 'logs/today/777.log') #=> #<Aws::S3::Key:0xb7b1e240 ... >
558
- # key.put('Olala!') #=> true
559
- # new_key = key.move('logs/today/888.log') #=> #<Aws::S3::Key:0xb7b5e240 ... >
560
- # key.exists? #=> false
561
- # new_key.exists? #=> true
562
- #
563
- def move(new_key_or_name)
564
- new_key_or_name = Key.create(@bucket, new_key_or_name.to_s) unless new_key_or_name.is_a?(Key)
565
- @bucket.s3.interface.move(@bucket.name, @name, new_key_or_name.bucket.name, new_key_or_name.name)
566
- new_key_or_name
567
- end
568
-
569
- # Retrieve key info from bucket and update attributes.
570
- # Refresh meta-headers (by calling +head+ method) if +head+ is set.
571
- # Returns +true+ if the key exists in bucket and +false+ otherwise.
572
- #
573
- # key = Aws::S3::Key.create(bucket, 'logs/today/1.log')
574
- # key.e_tag #=> nil
575
- # key.meta_headers #=> {}
576
- # key.refresh #=> true
577
- # key.e_tag #=> '12345678901234567890bf11094484b6'
578
- # key.meta_headers #=> {"family"=>"qwerty", "name"=>"asdfg"}
579
- #
580
- def refresh(head=true)
581
- new_key = @bucket.key(self)
582
- @last_modified = new_key.last_modified
583
- @e_tag = new_key.e_tag
584
- @size = new_key.size
585
- @storage_class = new_key.storage_class
586
- @owner = new_key.owner
587
- if @last_modified
588
- self.head
589
- true
590
- else
591
- @headers = @meta_headers = {}
592
- false
593
- end
594
- end
595
-
596
- # Updates headers and meta-headers from S3.
597
- # Returns +true+.
598
- #
599
- # key.meta_headers #=> {"family"=>"qwerty"}
600
- # key.head #=> true
601
- # key.meta_headers #=> {"family"=>"qwerty", "name"=>"asdfg"}
602
- #
603
- def head
604
- @headers, @meta_headers = self.class.split_meta(@bucket.s3.interface.head(@bucket, @name))
605
- true
606
- end
607
-
608
- # Reload meta-headers only. Returns meta-headers hash.
609
- #
610
- # key.reload_meta #=> {"family"=>"qwerty", "name"=>"asdfg"}
611
- #
612
- def reload_meta
613
- @meta_headers = self.class.split_meta(@bucket.s3.interface.head(@bucket, @name)).last
614
- end
615
-
616
- # Replace meta-headers by new hash at S3. Returns new meta-headers hash.
617
- #
618
- # key.reload_meta #=> {"family"=>"qwerty", "name"=>"asdfg"}
619
- # key.save_meta #=> {"family"=>"oops", "race" => "troll"}
620
- # key.reload_meta #=> {"family"=>"oops", "race" => "troll"}
621
- #
622
- def save_meta(meta_headers)
623
- meta = self.class.add_meta_prefix(meta_headers)
624
- @bucket.s3.interface.copy(@bucket.name, @name, @bucket.name, @name, :replace, meta)
625
- @meta_headers = self.class.split_meta(meta)[1]
626
- end
627
-
628
- # Check for existence of the key in the given bucket.
629
- # Returns +true+ or +false+.
630
- #
631
- # key = Aws::S3::Key.create(bucket,'logs/today/1.log')
632
- # key.exists? #=> false
633
- # key.put('Woohoo!') #=> true
634
- # key.exists? #=> true
635
- #
636
- def exists?
637
- @bucket.key(self).last_modified ? true : false
638
- end
639
-
640
- # Remove key from bucket.
641
- # Returns +true+.
642
- #
643
- # key.delete #=> true
644
- #
645
- def delete
646
- raise 'Key name must be specified.' if @name.blank?
647
- @bucket.s3.interface.delete(@bucket, @name)
648
- end
649
-
650
- # Return a list of grantees.
651
- #
652
- def grantees
653
- Grantee::grantees(self)
654
- end
655
-
656
- end
657
-
658
-
659
- class Owner
660
- attr_reader :id, :name
661
-
662
- def initialize(id, name)
663
- @id = id
664
- @name = name
665
- end
666
-
667
- # Return Owner name as a +String+.
668
- def to_s
669
- @name
670
- end
671
- end
672
-
673
-
674
- # There are 2 ways to set permissions for a bucket or key (called a +thing+ below):
675
- #
676
- # 1 . Use +perms+ param to set 'Canned Access Policies' when calling the <tt>bucket.create</tt>,
677
- # <tt>bucket.put</tt> and <tt>key.put</tt> methods.
678
- # The +perms+ param can take these values: 'private', 'public-read', 'public-read-write' and
679
- # 'authenticated-read'.
680
- # (see http://docs.amazonwebservices.com/AmazonS3/2006-03-01/RESTAccessPolicy.html).
681
- #
682
- # bucket = s3.bucket('bucket_for_kd_test_13', true, 'public-read')
683
- # key.put('Woohoo!','public-read-write' )
684
- #
685
- # 2 . Use Grantee instances (the permission is a +String+ or an +Array+ of: 'READ', 'WRITE',
686
- # 'READ_ACP', 'WRITE_ACP', 'FULL_CONTROL'):
687
- #
688
- # bucket = s3.bucket('my_awesome_bucket', true)
689
- # grantee1 = Aws::S3::Grantee.new(bucket, 'a123b...223c', FULL_CONTROL, :apply)
690
- # grantee2 = Aws::S3::Grantee.new(bucket, 'xy3v3...5fhp', [READ, WRITE], :apply)
691
- #
692
- # There is only one way to get and to remove permission (via Grantee instances):
693
- #
694
- # grantees = bucket.grantees # a list of Grantees that have any access for this bucket
695
- # grantee1 = Aws::S3::Grantee.new(bucket, 'a123b...223c')
696
- # grantee1.perms #=> returns a list of perms for this grantee to that bucket
697
- # ...
698
- # grantee1.drop # remove all perms for this grantee
699
- # grantee2.revoke('WRITE') # revoke write access only
700
- #
701
- class Grantee
702
- # A bucket or a key the grantee has an access to.
703
- attr_reader :thing
704
- # Grantee Amazon id.
705
- attr_reader :id
706
- # Grantee display name.
707
- attr_reader :name
708
- # Array of permissions.
709
- attr_accessor :perms
710
-
711
- # Retrieve Owner information and a list of Grantee instances that have
712
- # a access to this thing (bucket or key).
713
- #
714
- # bucket = s3.bucket('my_awesome_bucket', true, 'public-read')
715
- # ...
716
- # Aws::S3::Grantee.owner_and_grantees(bucket) #=> [owner, grantees]
717
- #
718
- def self.owner_and_grantees(thing)
719
- if thing.is_a?(Bucket)
720
- bucket, key = thing, ''
721
- else
722
- bucket, key = thing.bucket, thing
723
- end
724
- hash = bucket.s3.interface.get_acl_parse(bucket.to_s, key.to_s)
725
- owner = Owner.new(hash[:owner][:id], hash[:owner][:display_name])
726
-
727
- grantees = []
728
- hash[:grantees].each do |id, params|
729
- grantees << new(thing, id, params[:permissions], nil, params[:display_name])
730
- end
731
- [owner, grantees]
732
- end
733
-
734
- # Retrieves a list of Grantees instances that have an access to this thing(bucket or key).
735
- #
736
- # bucket = s3.bucket('my_awesome_bucket', true, 'public-read')
737
- # ...
738
- # Aws::S3::Grantee.grantees(bucket) #=> grantees
739
- #
740
- def self.grantees(thing)
741
- owner_and_grantees(thing)[1]
742
- end
743
-
744
- def self.put_acl(thing, owner, grantees) #:nodoc:
745
- if thing.is_a?(Bucket)
746
- bucket, key = thing, ''
747
- else
748
- bucket, key = thing.bucket, thing
749
- end
750
- body = "<AccessControlPolicy>" +
751
- "<Owner>" +
752
- "<ID>#{owner.id}</ID>" +
753
- "<DisplayName>#{owner.name}</DisplayName>" +
754
- "</Owner>" +
755
- "<AccessControlList>" +
756
- grantees.map { |grantee| grantee.to_xml }.join +
757
- "</AccessControlList>" +
758
- "</AccessControlPolicy>"
759
- bucket.s3.interface.put_acl(bucket.to_s, key.to_s, body)
760
- end
761
-
762
- # Create a new Grantee instance.
763
- # Grantee +id+ must exist on S3. If +action+ == :refresh, then retrieve
764
- # permissions from S3 and update @perms. If +action+ == :apply, then apply
765
- # perms to +thing+ at S3. If +action+ == :apply_and_refresh then it performs.
766
- # both the actions. This is used for the new grantees that had no perms to
767
- # this thing before. The default action is :refresh.
768
- #
769
- # bucket = s3.bucket('my_awesome_bucket', true, 'public-read')
770
- # grantee1 = Aws::S3::Grantee.new(bucket, 'a123b...223c', FULL_CONTROL)
771
- # ...
772
- # grantee2 = Aws::S3::Grantee.new(bucket, 'abcde...asdf', [FULL_CONTROL, READ], :apply)
773
- # grantee3 = Aws::S3::Grantee.new(bucket, 'aaaaa...aaaa', 'READ', :apply_and_refresh)
774
- #
775
- def initialize(thing, id, perms=[], action=:refresh, name=nil)
776
- @thing = thing
777
- @id = id
778
- @name = name
779
- @perms = perms.to_a
780
- case action
781
- when :apply then
782
- apply
783
- when :refresh then
784
- refresh
785
- when :apply_and_refresh then
786
- apply; refresh
787
- end
788
- end
789
-
790
- # Return +true+ if the grantee has any permissions to the thing.
791
- def exists?
792
- self.class.grantees(@thing).each do |grantee|
793
- return true if @id == grantee.id
794
- end
795
- false
796
- end
797
-
798
- # Return Grantee type (+String+): "Group" or "CanonicalUser".
799
- def type
800
- @id[/^http:/] ? "Group" : "CanonicalUser"
801
- end
802
-
803
- # Return a name or an id.
804
- def to_s
805
- @name || @id
806
- end
807
-
808
- # Add permissions for grantee.
809
- # Permissions: 'READ', 'WRITE', 'READ_ACP', 'WRITE_ACP', 'FULL_CONTROL'.
810
- # See http://docs.amazonwebservices.com/AmazonS3/2006-03-01/UsingPermissions.html .
811
- # Returns +true+.
812
- #
813
- # grantee.grant('FULL_CONTROL') #=> true
814
- # grantee.grant('FULL_CONTROL','WRITE','READ') #=> true
815
- # grantee.grant(['WRITE_ACP','READ','READ_ACP']) #=> true
816
- #
817
- def grant(*permissions)
818
- permissions.flatten!
819
- old_perms = @perms.dup
820
- @perms += permissions
821
- @perms.uniq!
822
- return true if @perms == old_perms
823
- apply
824
- end
825
-
826
- # Revoke permissions for grantee.
827
- # Permissions: 'READ', 'WRITE', 'READ_ACP', 'WRITE_ACP', 'FULL_CONTROL'
828
- # See http://docs.amazonwebservices.com/AmazonS3/2006-03-01/UsingPermissions.html .
829
- # Default value is 'FULL_CONTROL'.
830
- # Returns +true+.
831
- #
832
- # grantee.revoke('READ') #=> true
833
- # grantee.revoke('FULL_CONTROL','WRITE') #=> true
834
- # grantee.revoke(['READ_ACP','WRITE_ACP']) #=> true
835
- #
836
- def revoke(*permissions)
837
- permissions.flatten!
838
- old_perms = @perms.dup
839
- @perms -= permissions
840
- @perms.uniq!
841
- return true if @perms == old_perms
842
- apply
843
- end
844
-
845
- # Revoke all permissions for this grantee.
846
- # Returns +true+.
847
- #
848
- # grantee.drop #=> true
849
- #
850
- def drop
851
- @perms = []
852
- apply
853
- end
854
-
855
- # Refresh grantee perms for its +thing+.
856
- # Returns +true+ if the grantee has perms for this +thing+ or
857
- # +false+ otherwise, and updates @perms value as a side-effect.
858
- #
859
- # grantee.grant('FULL_CONTROL') #=> true
860
- # grantee.refresh #=> true
861
- # grantee.drop #=> true
862
- # grantee.refresh #=> false
863
- #
864
- def refresh
865
- @perms = []
866
- self.class.grantees(@thing).each do |grantee|
867
- if @id == grantee.id
868
- @name = grantee.name
869
- @perms = grantee.perms
870
- return true
871
- end
872
- end
873
- false
874
- end
875
-
876
- # Apply current grantee @perms to +thing+. This method is called internally by the +grant+
877
- # and +revoke+ methods. In normal use this method should not
878
- # be called directly.
879
- #
880
- # grantee.perms = ['FULL_CONTROL']
881
- # grantee.apply #=> true
882
- #
883
- def apply
884
- @perms.uniq!
885
- owner, grantees = self.class.owner_and_grantees(@thing)
886
- # walk through all the grantees and replace the data for the current one and ...
887
- grantees.map! { |grantee| grantee.id == @id ? self : grantee }
888
- # ... if this grantee is not known - add this bad boy to a list
889
- grantees << self unless grantees.include?(self)
890
- # set permissions
891
- self.class.put_acl(@thing, owner, grantees)
892
- end
893
-
894
- def to_xml # :nodoc:
895
- id_str = @id[/^http/] ? "<URI>#{@id}</URI>" : "<ID>#{@id}</ID>"
896
- grants = ''
897
- @perms.each do |perm|
898
- grants << "<Grant>" +
899
- "<Grantee xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" " +
900
- "xsi:type=\"#{type}\">#{id_str}</Grantee>" +
901
- "<Permission>#{perm}</Permission>" +
902
- "</Grant>"
903
- end
904
- grants
905
- end
906
-
907
- end
908
-
909
- end
910
-
911
- # Aws::S3Generator and Aws::S3Generator::Bucket methods:
912
- #
913
- # s3g = Aws::S3Generator.new('1...2', 'nx...Y6') #=> #<Aws::S3Generator:0xb7b5cc94>
914
- #
915
- # # List all buckets(method 'GET'):
916
- # buckets_list = s3g.buckets #=> 'https://s3.amazonaws.com:443/?Signature=Y...D&Expires=1180941864&AWSAccessKeyId=1...2'
917
- # # Create bucket link (method 'PUT'):
918
- # bucket = s3g.bucket('my_awesome_bucket') #=> #<Aws::S3Generator::Bucket:0xb7bcbda8>
919
- # link_to_create = bucket.create_link(1.hour) #=> https://s3.amazonaws.com:443/my_awesome_bucket?Signature=4...D&Expires=1180942132&AWSAccessKeyId=1...2
920
- # # ... or:
921
- # bucket = Aws::S3Generator::Bucket.create(s3g, 'my_awesome_bucket') #=> #<Aws::S3Generator::Bucket:0xb7bcbda8>
922
- # link_to_create = bucket.create_link(1.hour) #=> https://s3.amazonaws.com:443/my_awesome_bucket?Signature=4...D&Expires=1180942132&AWSAccessKeyId=1...2
923
- # # ... or:
924
- # bucket = Aws::S3Generator::Bucket.new(s3g, 'my_awesome_bucket') #=> #<Aws::S3Generator::Bucket:0xb7bcbda8>
925
- # link_to_create = bucket.create_link(1.hour) #=> https://s3.amazonaws.com:443/my_awesome_bucket?Signature=4...D&Expires=1180942132&AWSAccessKeyId=1...2
926
- # # List bucket(method 'GET'):
927
- # bucket.keys(1.day) #=> https://s3.amazonaws.com:443/my_awesome_bucket?Signature=i...D&Expires=1180942620&AWSAccessKeyId=1...2
928
- # # Create/put key (method 'PUT'):
929
- # bucket.put('my_cool_key') #=> https://s3.amazonaws.com:443/my_awesome_bucket/my_cool_key?Signature=q...D&Expires=1180943094&AWSAccessKeyId=1...2
930
- # # Get key data (method 'GET'):
931
- # bucket.get('logs/today/1.log', 1.hour) #=> https://s3.amazonaws.com:443/my_awesome_bucket/my_cool_key?Signature=h...M%3D&Expires=1180820032&AWSAccessKeyId=1...2
932
- # # Delete bucket (method 'DELETE'):
933
- # bucket.delete(2.hour) #=> https://s3.amazonaws.com:443/my_awesome_bucket/logs%2Ftoday%2F1.log?Signature=4...D&Expires=1180820032&AWSAccessKeyId=1...2
934
- #
935
- # Aws::S3Generator::Key methods:
936
- #
937
- # # Create Key instance:
938
- # key = Aws::S3Generator::Key.new(bicket, 'my_cool_key') #=> #<Aws::S3Generator::Key:0xb7b7394c>
939
- # # Put key data (method 'PUT'):
940
- # key.put #=> https://s3.amazonaws.com:443/my_awesome_bucket/my_cool_key?Signature=2...D&Expires=1180943302&AWSAccessKeyId=1...2
941
- # # Get key data (method 'GET'):
942
- # key.get #=> https://s3.amazonaws.com:443/my_awesome_bucket/my_cool_key?Signature=a...D&Expires=1180820032&AWSAccessKeyId=1...2
943
- # # Head key (method 'HEAD'):
944
- # key.head #=> https://s3.amazonaws.com:443/my_awesome_bucket/my_cool_key?Signature=b...D&Expires=1180820032&AWSAccessKeyId=1...2
945
- # # Delete key (method 'DELETE'):
946
- # key.delete #=> https://s3.amazonaws.com:443/my_awesome_bucket/my_cool_key?Signature=x...D&Expires=1180820032&AWSAccessKeyId=1...2
947
- #
948
- class S3Generator
949
- attr_reader :interface
950
-
951
- def initialize(aws_access_key_id, aws_secret_access_key, params={})
952
- @interface = S3Interface.new(aws_access_key_id, aws_secret_access_key, params)
953
- end
954
-
955
- # Generate link to list all buckets
956
- #
957
- # s3.buckets(1.hour)
958
- #
959
- def buckets(expires=nil, headers={})
960
- @interface.list_all_my_buckets_link(expires, headers)
961
- end
962
-
963
- # Create new S3LinkBucket instance and generate link to create it at S3.
964
- #
965
- # bucket= s3.bucket('my_owesome_bucket')
966
- #
967
- def bucket(name, expires=nil, headers={})
968
- Bucket.create(self, name.to_s)
969
- end
970
-
971
- class Bucket
972
- attr_reader :s3, :name
973
-
974
- def to_s
975
- @name
976
- end
977
-
978
- alias_method :full_name, :to_s
979
-
980
- # Return a public link to bucket.
981
- #
982
- # bucket.public_link #=> 'https://s3.amazonaws.com:443/my_awesome_bucket'
983
- #
984
- def public_link
985
- params = @s3.interface.params
986
- "#{params[:protocol]}://#{params[:server]}:#{params[:port]}/#{full_name}"
987
- end
988
-
989
- # Create new S3LinkBucket instance and generate creation link for it.
990
- def self.create(s3, name, expires=nil, headers={})
991
- new(s3, name.to_s)
992
- end
993
-
994
- # Create new S3LinkBucket instance.
995
- def initialize(s3, name)
996
- @s3, @name = s3, name.to_s
997
- end
998
-
999
- # Return a link to create this bucket.
1000
- #
1001
- def create_link(expires=nil, headers={})
1002
- @s3.interface.create_bucket_link(@name, expires, headers)
1003
- end
1004
-
1005
- # Generate link to list keys.
1006
- #
1007
- # bucket.keys
1008
- # bucket.keys('prefix'=>'logs')
1009
- #
1010
- def keys(options=nil, expires=nil, headers={})
1011
- @s3.interface.list_bucket_link(@name, options, expires, headers)
1012
- end
1013
-
1014
- # Return a S3Generator::Key instance.
1015
- #
1016
- # bucket.key('my_cool_key').get #=> https://s3.amazonaws.com:443/my_awesome_bucket/my_cool_key?Signature=B...D&Expires=1180820032&AWSAccessKeyId=1...2
1017
- # bucket.key('my_cool_key').delete #=> https://s3.amazonaws.com:443/my_awesome_bucket/my_cool_key?Signature=B...D&Expires=1180820098&AWSAccessKeyId=1...2
1018
- #
1019
- def key(name)
1020
- Key.new(self, name)
1021
- end
1022
-
1023
- # Generates link to PUT key data.
1024
- #
1025
- # puts bucket.put('logs/today/1.log', 2.hour)
1026
- #
1027
- def put(key, meta_headers={}, expires=nil, headers={})
1028
- meta = Aws::S3::Key.add_meta_prefix(meta_headers)
1029
- @s3.interface.put_link(@name, key.to_s, nil, expires, meta.merge(headers))
1030
- end
1031
-
1032
- # Generate link to GET key data.
1033
- #
1034
- # bucket.get('logs/today/1.log', 1.hour)
1035
- #
1036
- def get(key, expires=nil, headers={})
1037
- @s3.interface.get_link(@name, key.to_s, expires, headers)
1038
- end
1039
-
1040
- # Generate link to delete bucket.
1041
- #
1042
- # bucket.delete(2.hour)
1043
- #
1044
- def delete(expires=nil, headers={})
1045
- @s3.interface.delete_bucket_link(@name, expires, headers)
1046
- end
1047
- end
1048
-
1049
-
1050
- class Key
1051
- attr_reader :bucket, :name
1052
-
1053
- def to_s
1054
- @name
1055
- end
1056
-
1057
- # Return a full S# name (bucket/key).
1058
- #
1059
- # key.full_name #=> 'my_awesome_bucket/cool_key'
1060
- #
1061
- def full_name(separator='/')
1062
- "#{@bucket.to_s}#{separator}#{@name}"
1063
- end
1064
-
1065
- # Return a public link to key.
1066
- #
1067
- # key.public_link #=> 'https://s3.amazonaws.com:443/my_awesome_bucket/cool_key'
1068
- #
1069
- def public_link
1070
- params = @bucket.s3.interface.params
1071
- "#{params[:protocol]}://#{params[:server]}:#{params[:port]}/#{full_name('/')}"
1072
- end
1073
-
1074
- def initialize(bucket, name, meta_headers={})
1075
- @bucket = bucket
1076
- @name = name.to_s
1077
- @meta_headers = meta_headers
1078
- raise 'Key name can not be empty.' if @name.blank?
1079
- end
1080
-
1081
- # Generate link to PUT key data.
1082
- #
1083
- # puts bucket.put('logs/today/1.log', '123', 2.hour) #=> https://s3.amazonaws.com:443/my_awesome_bucket/logs%2Ftoday%2F1.log?Signature=B...D&Expires=1180820032&AWSAccessKeyId=1...2
1084
- #
1085
- def put(expires=nil, headers={})
1086
- @bucket.put(@name.to_s, @meta_headers, expires, headers)
1087
- end
1088
-
1089
- # Generate link to GET key data.
1090
- #
1091
- # bucket.get('logs/today/1.log', 1.hour) #=> https://s3.amazonaws.com:443/my_awesome_bucket/logs%2Ftoday%2F1.log?Signature=h...M%3D&Expires=1180820032&AWSAccessKeyId=1...2
1092
- #
1093
- def get(expires=nil, headers={})
1094
- @bucket.s3.interface.get_link(@bucket.to_s, @name, expires, headers)
1095
- end
1096
-
1097
- # Generate link to delete key.
1098
- #
1099
- # bucket.delete(2.hour) #=> https://s3.amazonaws.com:443/my_awesome_bucket/logs%2Ftoday%2F1.log?Signature=4...D&Expires=1180820032&AWSAccessKeyId=1...2
1100
- #
1101
- def delete(expires=nil, headers={})
1102
- @bucket.s3.interface.delete_link(@bucket.to_s, @name, expires, headers)
1103
- end
1104
-
1105
- # Generate link to head key.
1106
- #
1107
- # bucket.head(2.hour) #=> https://s3.amazonaws.com:443/my_awesome_bucket/logs%2Ftoday%2F1.log?Signature=4...D&Expires=1180820032&AWSAccessKeyId=1...2
1108
- #
1109
- def head(expires=nil, headers={})
1110
- @bucket.s3.interface.head_link(@bucket.to_s, @name, expires, headers)
1111
- end
1112
- end
1113
- end
1114
-
1115
- end