aws 2.3.34 → 2.4.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -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