aws-sdk 1.0.0
Sign up to get free protection for your applications and to get access to all the features.
- data/.yardopts +6 -0
- data/LICENSE.txt +171 -0
- data/NOTICE.txt +2 -0
- data/README.rdoc +189 -0
- data/lib/aws-sdk.rb +14 -0
- data/lib/aws.rb +63 -0
- data/lib/aws/api_config.rb +45 -0
- data/lib/aws/api_config/.document +0 -0
- data/lib/aws/api_config/EC2-2011-02-28.yml +2314 -0
- data/lib/aws/api_config/SNS-2010-03-31.yml +171 -0
- data/lib/aws/api_config/SQS-2009-02-01.yml +161 -0
- data/lib/aws/api_config/SimpleDB-2009-04-15.yml +278 -0
- data/lib/aws/api_config/SimpleEmailService-2010-12-01.yml +147 -0
- data/lib/aws/api_config_transform.rb +32 -0
- data/lib/aws/async_handle.rb +90 -0
- data/lib/aws/authorize_v2.rb +37 -0
- data/lib/aws/authorize_v3.rb +37 -0
- data/lib/aws/base_client.rb +524 -0
- data/lib/aws/cacheable.rb +92 -0
- data/lib/aws/common.rb +228 -0
- data/lib/aws/configurable.rb +36 -0
- data/lib/aws/configuration.rb +272 -0
- data/lib/aws/configured_client_methods.rb +81 -0
- data/lib/aws/configured_grammars.rb +65 -0
- data/lib/aws/configured_option_grammars.rb +46 -0
- data/lib/aws/configured_xml_grammars.rb +47 -0
- data/lib/aws/default_signer.rb +38 -0
- data/lib/aws/ec2.rb +321 -0
- data/lib/aws/ec2/attachment.rb +149 -0
- data/lib/aws/ec2/attachment_collection.rb +57 -0
- data/lib/aws/ec2/availability_zone.rb +80 -0
- data/lib/aws/ec2/availability_zone_collection.rb +47 -0
- data/lib/aws/ec2/block_device_mappings.rb +53 -0
- data/lib/aws/ec2/client.rb +54 -0
- data/lib/aws/ec2/client/xml.rb +127 -0
- data/lib/aws/ec2/collection.rb +39 -0
- data/lib/aws/ec2/config_transform.rb +63 -0
- data/lib/aws/ec2/elastic_ip.rb +107 -0
- data/lib/aws/ec2/elastic_ip_collection.rb +85 -0
- data/lib/aws/ec2/errors.rb +29 -0
- data/lib/aws/ec2/filtered_collection.rb +65 -0
- data/lib/aws/ec2/has_permissions.rb +46 -0
- data/lib/aws/ec2/image.rb +245 -0
- data/lib/aws/ec2/image_collection.rb +235 -0
- data/lib/aws/ec2/instance.rb +515 -0
- data/lib/aws/ec2/instance_collection.rb +276 -0
- data/lib/aws/ec2/key_pair.rb +86 -0
- data/lib/aws/ec2/key_pair_collection.rb +102 -0
- data/lib/aws/ec2/permission_collection.rb +177 -0
- data/lib/aws/ec2/region.rb +81 -0
- data/lib/aws/ec2/region_collection.rb +55 -0
- data/lib/aws/ec2/request.rb +27 -0
- data/lib/aws/ec2/reserved_instances.rb +50 -0
- data/lib/aws/ec2/reserved_instances_collection.rb +44 -0
- data/lib/aws/ec2/reserved_instances_offering.rb +55 -0
- data/lib/aws/ec2/reserved_instances_offering_collection.rb +43 -0
- data/lib/aws/ec2/resource.rb +340 -0
- data/lib/aws/ec2/resource_tag_collection.rb +218 -0
- data/lib/aws/ec2/security_group.rb +246 -0
- data/lib/aws/ec2/security_group/ip_permission.rb +70 -0
- data/lib/aws/ec2/security_group/ip_permission_collection.rb +59 -0
- data/lib/aws/ec2/security_group_collection.rb +132 -0
- data/lib/aws/ec2/snapshot.rb +138 -0
- data/lib/aws/ec2/snapshot_collection.rb +90 -0
- data/lib/aws/ec2/tag.rb +88 -0
- data/lib/aws/ec2/tag_collection.rb +114 -0
- data/lib/aws/ec2/tagged_collection.rb +48 -0
- data/lib/aws/ec2/tagged_item.rb +87 -0
- data/lib/aws/ec2/volume.rb +190 -0
- data/lib/aws/ec2/volume_collection.rb +95 -0
- data/lib/aws/errors.rb +129 -0
- data/lib/aws/http/builtin_handler.rb +69 -0
- data/lib/aws/http/curb_handler.rb +123 -0
- data/lib/aws/http/handler.rb +77 -0
- data/lib/aws/http/httparty_handler.rb +61 -0
- data/lib/aws/http/request.rb +136 -0
- data/lib/aws/http/request_param.rb +63 -0
- data/lib/aws/http/response.rb +75 -0
- data/lib/aws/ignore_result_element.rb +38 -0
- data/lib/aws/indifferent_hash.rb +86 -0
- data/lib/aws/inflection.rb +46 -0
- data/lib/aws/lazy_error_classes.rb +64 -0
- data/lib/aws/meta_utils.rb +43 -0
- data/lib/aws/model.rb +57 -0
- data/lib/aws/naming.rb +32 -0
- data/lib/aws/option_grammar.rb +544 -0
- data/lib/aws/policy.rb +912 -0
- data/lib/aws/rails.rb +209 -0
- data/lib/aws/record.rb +79 -0
- data/lib/aws/record/attribute.rb +94 -0
- data/lib/aws/record/attribute_macros.rb +288 -0
- data/lib/aws/record/attributes/boolean.rb +49 -0
- data/lib/aws/record/attributes/datetime.rb +86 -0
- data/lib/aws/record/attributes/float.rb +48 -0
- data/lib/aws/record/attributes/integer.rb +68 -0
- data/lib/aws/record/attributes/sortable_float.rb +60 -0
- data/lib/aws/record/attributes/sortable_integer.rb +95 -0
- data/lib/aws/record/attributes/string.rb +69 -0
- data/lib/aws/record/base.rb +728 -0
- data/lib/aws/record/conversion.rb +38 -0
- data/lib/aws/record/dirty_tracking.rb +286 -0
- data/lib/aws/record/errors.rb +153 -0
- data/lib/aws/record/exceptions.rb +48 -0
- data/lib/aws/record/finder_methods.rb +262 -0
- data/lib/aws/record/naming.rb +31 -0
- data/lib/aws/record/scope.rb +157 -0
- data/lib/aws/record/validations.rb +653 -0
- data/lib/aws/record/validator.rb +237 -0
- data/lib/aws/record/validators/acceptance.rb +51 -0
- data/lib/aws/record/validators/block.rb +38 -0
- data/lib/aws/record/validators/confirmation.rb +43 -0
- data/lib/aws/record/validators/count.rb +108 -0
- data/lib/aws/record/validators/exclusion.rb +43 -0
- data/lib/aws/record/validators/format.rb +57 -0
- data/lib/aws/record/validators/inclusion.rb +56 -0
- data/lib/aws/record/validators/length.rb +107 -0
- data/lib/aws/record/validators/numericality.rb +138 -0
- data/lib/aws/record/validators/presence.rb +45 -0
- data/lib/aws/resource_cache.rb +39 -0
- data/lib/aws/response.rb +113 -0
- data/lib/aws/response_cache.rb +50 -0
- data/lib/aws/s3.rb +109 -0
- data/lib/aws/s3/access_control_list.rb +252 -0
- data/lib/aws/s3/acl_object.rb +266 -0
- data/lib/aws/s3/bucket.rb +320 -0
- data/lib/aws/s3/bucket_collection.rb +122 -0
- data/lib/aws/s3/bucket_version_collection.rb +85 -0
- data/lib/aws/s3/client.rb +999 -0
- data/lib/aws/s3/client/xml.rb +190 -0
- data/lib/aws/s3/data_options.rb +99 -0
- data/lib/aws/s3/errors.rb +43 -0
- data/lib/aws/s3/multipart_upload.rb +318 -0
- data/lib/aws/s3/multipart_upload_collection.rb +78 -0
- data/lib/aws/s3/object_collection.rb +159 -0
- data/lib/aws/s3/object_metadata.rb +67 -0
- data/lib/aws/s3/object_upload_collection.rb +83 -0
- data/lib/aws/s3/object_version.rb +141 -0
- data/lib/aws/s3/object_version_collection.rb +78 -0
- data/lib/aws/s3/paginated_collection.rb +94 -0
- data/lib/aws/s3/policy.rb +76 -0
- data/lib/aws/s3/prefix_and_delimiter_collection.rb +56 -0
- data/lib/aws/s3/prefixed_collection.rb +84 -0
- data/lib/aws/s3/presigned_post.rb +504 -0
- data/lib/aws/s3/request.rb +198 -0
- data/lib/aws/s3/s3_object.rb +794 -0
- data/lib/aws/s3/tree.rb +116 -0
- data/lib/aws/s3/tree/branch_node.rb +71 -0
- data/lib/aws/s3/tree/child_collection.rb +108 -0
- data/lib/aws/s3/tree/leaf_node.rb +99 -0
- data/lib/aws/s3/tree/node.rb +22 -0
- data/lib/aws/s3/tree/parent.rb +90 -0
- data/lib/aws/s3/uploaded_part.rb +82 -0
- data/lib/aws/s3/uploaded_part_collection.rb +86 -0
- data/lib/aws/service_interface.rb +60 -0
- data/lib/aws/simple_db.rb +202 -0
- data/lib/aws/simple_db/attribute.rb +159 -0
- data/lib/aws/simple_db/attribute_collection.rb +227 -0
- data/lib/aws/simple_db/client.rb +52 -0
- data/lib/aws/simple_db/client/options.rb +34 -0
- data/lib/aws/simple_db/client/xml.rb +68 -0
- data/lib/aws/simple_db/consistent_read_option.rb +42 -0
- data/lib/aws/simple_db/delete_attributes.rb +64 -0
- data/lib/aws/simple_db/domain.rb +118 -0
- data/lib/aws/simple_db/domain_collection.rb +116 -0
- data/lib/aws/simple_db/domain_metadata.rb +112 -0
- data/lib/aws/simple_db/errors.rb +46 -0
- data/lib/aws/simple_db/expect_condition_option.rb +45 -0
- data/lib/aws/simple_db/item.rb +84 -0
- data/lib/aws/simple_db/item_collection.rb +594 -0
- data/lib/aws/simple_db/item_data.rb +70 -0
- data/lib/aws/simple_db/put_attributes.rb +62 -0
- data/lib/aws/simple_db/request.rb +27 -0
- data/lib/aws/simple_email_service.rb +373 -0
- data/lib/aws/simple_email_service/client.rb +39 -0
- data/lib/aws/simple_email_service/client/options.rb +24 -0
- data/lib/aws/simple_email_service/client/xml.rb +38 -0
- data/lib/aws/simple_email_service/email_address_collection.rb +66 -0
- data/lib/aws/simple_email_service/errors.rb +29 -0
- data/lib/aws/simple_email_service/quotas.rb +64 -0
- data/lib/aws/simple_email_service/request.rb +27 -0
- data/lib/aws/sns.rb +69 -0
- data/lib/aws/sns/client.rb +37 -0
- data/lib/aws/sns/client/options.rb +24 -0
- data/lib/aws/sns/client/xml.rb +38 -0
- data/lib/aws/sns/errors.rb +29 -0
- data/lib/aws/sns/policy.rb +49 -0
- data/lib/aws/sns/request.rb +27 -0
- data/lib/aws/sns/subscription.rb +100 -0
- data/lib/aws/sns/subscription_collection.rb +84 -0
- data/lib/aws/sns/topic.rb +384 -0
- data/lib/aws/sns/topic_collection.rb +70 -0
- data/lib/aws/sns/topic_subscription_collection.rb +58 -0
- data/lib/aws/sqs.rb +70 -0
- data/lib/aws/sqs/client.rb +38 -0
- data/lib/aws/sqs/client/xml.rb +36 -0
- data/lib/aws/sqs/errors.rb +33 -0
- data/lib/aws/sqs/policy.rb +50 -0
- data/lib/aws/sqs/queue.rb +507 -0
- data/lib/aws/sqs/queue_collection.rb +105 -0
- data/lib/aws/sqs/received_message.rb +184 -0
- data/lib/aws/sqs/received_sns_message.rb +112 -0
- data/lib/aws/sqs/request.rb +44 -0
- data/lib/aws/xml_grammar.rb +923 -0
- data/rails/init.rb +15 -0
- metadata +298 -0
@@ -0,0 +1,266 @@
|
|
1
|
+
# Copyright 2011 Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
2
|
+
#
|
3
|
+
# Licensed under the Apache License, Version 2.0 (the "License"). You
|
4
|
+
# may not use this file except in compliance with the License. A copy of
|
5
|
+
# the License is located at
|
6
|
+
#
|
7
|
+
# http://aws.amazon.com/apache2.0/
|
8
|
+
#
|
9
|
+
# or in the "license" file accompanying this file. This file is
|
10
|
+
# distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF
|
11
|
+
# ANY KIND, either express or implied. See the License for the specific
|
12
|
+
# language governing permissions and limitations under the License.
|
13
|
+
|
14
|
+
require 'aws/meta_utils'
|
15
|
+
require 'aws/inflection'
|
16
|
+
require 'rexml/text'
|
17
|
+
|
18
|
+
module AWS
|
19
|
+
class S3
|
20
|
+
|
21
|
+
# Common methods for AccessControlList and related objects.
|
22
|
+
module ACLObject
|
23
|
+
|
24
|
+
# @private
|
25
|
+
def initialize(opts = {}); end
|
26
|
+
|
27
|
+
# @private
|
28
|
+
def body_xml; ""; end
|
29
|
+
|
30
|
+
# @private
|
31
|
+
def stag
|
32
|
+
element_name
|
33
|
+
end
|
34
|
+
|
35
|
+
# @private
|
36
|
+
def element_name
|
37
|
+
self.class.name[/::([^:]*)$/, 1]
|
38
|
+
end
|
39
|
+
|
40
|
+
# Returns the XML representation of the object. Generally
|
41
|
+
# you'll want to call this on an AccessControlList object,
|
42
|
+
# which will yield an XML representation of the ACL that you
|
43
|
+
# can send to S3.
|
44
|
+
def to_s
|
45
|
+
if body_xml.empty?
|
46
|
+
"<#{stag}/>"
|
47
|
+
else
|
48
|
+
"<#{stag}>#{body_xml}</#{element_name}>"
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
# (see #to_s)
|
53
|
+
def to_xml
|
54
|
+
to_s
|
55
|
+
end
|
56
|
+
|
57
|
+
# Returns true if and only if this object is valid according
|
58
|
+
# to S3's published ACL schema. In particular, this will
|
59
|
+
# check that all required attributes are provided and that
|
60
|
+
# they are of the correct type.
|
61
|
+
def valid?
|
62
|
+
validate!
|
63
|
+
rescue => e
|
64
|
+
false
|
65
|
+
else
|
66
|
+
true
|
67
|
+
end
|
68
|
+
|
69
|
+
# Raises an exception unless this object is valid according to
|
70
|
+
# S3's published ACL schema.
|
71
|
+
# @see #valid?
|
72
|
+
def validate!; end
|
73
|
+
|
74
|
+
# @private
|
75
|
+
def validate_input(name, value, context = nil)
|
76
|
+
send("validate_#{name}_input!", value, context)
|
77
|
+
end
|
78
|
+
|
79
|
+
# @private
|
80
|
+
module ClassMethods
|
81
|
+
|
82
|
+
def string_attr(element_name, options = {})
|
83
|
+
method_name = options[:method_name] ||
|
84
|
+
Inflection.ruby_name(element_name)
|
85
|
+
|
86
|
+
attr_accessor(method_name)
|
87
|
+
setter_option(method_name)
|
88
|
+
string_input_validator(method_name)
|
89
|
+
validate_string(method_name) if options[:required]
|
90
|
+
body_xml_string_content(element_name, method_name)
|
91
|
+
end
|
92
|
+
|
93
|
+
def object_attr(klass, options = {})
|
94
|
+
base_name = klass.name[/::([^:]*)$/, 1]
|
95
|
+
method_name = Inflection.ruby_name(base_name)
|
96
|
+
cast = options[:cast] || Hash
|
97
|
+
|
98
|
+
attr_reader(method_name)
|
99
|
+
setter_option(method_name)
|
100
|
+
object_setter(klass, method_name, cast)
|
101
|
+
object_input_validator(klass, base_name, method_name, cast)
|
102
|
+
validate_object(method_name) if options[:required]
|
103
|
+
body_xml_content(method_name)
|
104
|
+
end
|
105
|
+
|
106
|
+
def object_list_attr(list_element, klass, options = {})
|
107
|
+
base_name = klass.name[/::([^:]*)$/, 1]
|
108
|
+
method_name = Inflection.ruby_name(options[:method_name].to_s || list_element)
|
109
|
+
default_value = nil
|
110
|
+
default_value = [] if options[:required]
|
111
|
+
|
112
|
+
attr_reader(method_name)
|
113
|
+
setter_option(method_name) { [] if options[:required] }
|
114
|
+
object_list_setter(klass, method_name)
|
115
|
+
object_list_input_validator(klass, base_name, method_name)
|
116
|
+
validate_list(method_name)
|
117
|
+
body_xml_list_content(list_element, method_name)
|
118
|
+
end
|
119
|
+
|
120
|
+
def setter_option(method_name)
|
121
|
+
MetaUtils.class_extend_method(self, :initialize) do |*args|
|
122
|
+
opts = args.last || {}
|
123
|
+
instance_variable_set("@#{method_name}", yield) if block_given?
|
124
|
+
key = method_name.to_sym
|
125
|
+
|
126
|
+
if opts.has_key?(key)
|
127
|
+
value = opts[key]
|
128
|
+
validate_input(method_name, value, "for #{method_name} option")
|
129
|
+
self.send("#{method_name}=", value)
|
130
|
+
end
|
131
|
+
super(opts)
|
132
|
+
end
|
133
|
+
end
|
134
|
+
|
135
|
+
def string_input_validator(method_name)
|
136
|
+
input_validator(method_name) do |value, context|
|
137
|
+
raise ArgumentError.new("expected string"+context) unless
|
138
|
+
value.respond_to?(:to_str)
|
139
|
+
end
|
140
|
+
end
|
141
|
+
|
142
|
+
def object_input_validator(klass, base_name, method_name, cast)
|
143
|
+
input_validator(method_name) do |value, context|
|
144
|
+
if value.kind_of?(cast)
|
145
|
+
klass.new(value).validate!
|
146
|
+
else
|
147
|
+
raise ArgumentError.new("expected #{base_name} object or hash"+context) unless
|
148
|
+
value.nil? or value.kind_of? klass
|
149
|
+
end
|
150
|
+
end
|
151
|
+
end
|
152
|
+
|
153
|
+
def object_list_input_validator(klass, base_name, method_name)
|
154
|
+
input_validator(method_name) do |value, context|
|
155
|
+
raise ArgumentError.new("expected array"+context) unless value.kind_of?(Array)
|
156
|
+
value.each do |member|
|
157
|
+
if member.kind_of?(Hash)
|
158
|
+
klass.new(member).validate!
|
159
|
+
else
|
160
|
+
raise ArgumentError.new("expected array#{context} "+
|
161
|
+
"to contain #{base_name} objects "+
|
162
|
+
"or hashes") unless
|
163
|
+
member.kind_of? klass
|
164
|
+
end
|
165
|
+
end
|
166
|
+
end
|
167
|
+
end
|
168
|
+
|
169
|
+
def input_validator(method_name, &blk)
|
170
|
+
validator = "__validator__#{blk.object_id}"
|
171
|
+
MetaUtils.class_extend_method(self, validator, &blk)
|
172
|
+
MetaUtils.class_extend_method(self, "validate_#{method_name}_input!") do |*args|
|
173
|
+
(value, context) = args
|
174
|
+
context = " "+context if context
|
175
|
+
context ||= ""
|
176
|
+
send(validator, value, context)
|
177
|
+
end
|
178
|
+
end
|
179
|
+
|
180
|
+
def object_setter(klass, method_name, cast)
|
181
|
+
define_method("#{method_name}=") do |value|
|
182
|
+
validate_input(method_name, value)
|
183
|
+
if value.kind_of?(cast)
|
184
|
+
value = klass.new(value)
|
185
|
+
end
|
186
|
+
instance_variable_set("@#{method_name}", value)
|
187
|
+
end
|
188
|
+
end
|
189
|
+
|
190
|
+
def object_list_setter(klass, method_name)
|
191
|
+
define_method("#{method_name}=") do |value|
|
192
|
+
validate_input(method_name, value)
|
193
|
+
list = value.map do |member|
|
194
|
+
if member.kind_of?(Hash)
|
195
|
+
klass.new(member)
|
196
|
+
else
|
197
|
+
member
|
198
|
+
end
|
199
|
+
end
|
200
|
+
instance_variable_set("@#{method_name}", list)
|
201
|
+
end
|
202
|
+
end
|
203
|
+
|
204
|
+
def validate_string(method_name)
|
205
|
+
MetaUtils.class_extend_method(self, :validate!) do
|
206
|
+
super()
|
207
|
+
raise "missing #{method_name}" unless send(method_name)
|
208
|
+
end
|
209
|
+
end
|
210
|
+
|
211
|
+
def validate_object(method_name)
|
212
|
+
MetaUtils.class_extend_method(self, :validate!) do
|
213
|
+
super()
|
214
|
+
raise "missing #{method_name}" unless send(method_name)
|
215
|
+
send(method_name).validate!
|
216
|
+
end
|
217
|
+
end
|
218
|
+
|
219
|
+
def validate_list(method_name)
|
220
|
+
MetaUtils.class_extend_method(self, :validate!) do
|
221
|
+
super()
|
222
|
+
raise "missing #{method_name}" unless send(method_name)
|
223
|
+
send(method_name).each { |member| member.validate! }
|
224
|
+
end
|
225
|
+
end
|
226
|
+
|
227
|
+
def body_xml_string_content(element_name, method_name)
|
228
|
+
add_xml_child(method_name) do |value|
|
229
|
+
normalized = REXML::Text.normalize(value.to_s)
|
230
|
+
"<#{element_name}>#{normalized}</#{element_name}>"
|
231
|
+
end
|
232
|
+
end
|
233
|
+
|
234
|
+
def body_xml_content(method_name)
|
235
|
+
add_xml_child(method_name) { |value| value.to_s }
|
236
|
+
end
|
237
|
+
|
238
|
+
def body_xml_list_content(list_element, method_name)
|
239
|
+
add_xml_child(method_name) do |list|
|
240
|
+
list_content = list.map { |member| member.to_s }.join
|
241
|
+
if list_content.empty?
|
242
|
+
"<#{list_element}/>"
|
243
|
+
else
|
244
|
+
"<#{list_element}>#{list_content}</#{list_element}>"
|
245
|
+
end
|
246
|
+
end
|
247
|
+
end
|
248
|
+
|
249
|
+
def add_xml_child(method_name)
|
250
|
+
MetaUtils.class_extend_method(self, :body_xml) do
|
251
|
+
xml = super()
|
252
|
+
value = send(method_name)
|
253
|
+
xml += yield(value) if value
|
254
|
+
xml
|
255
|
+
end
|
256
|
+
end
|
257
|
+
|
258
|
+
end
|
259
|
+
|
260
|
+
def self.included(m)
|
261
|
+
m.extend(ClassMethods)
|
262
|
+
end
|
263
|
+
|
264
|
+
end
|
265
|
+
end
|
266
|
+
end
|
@@ -0,0 +1,320 @@
|
|
1
|
+
# Copyright 2011 Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
2
|
+
#
|
3
|
+
# Licensed under the Apache License, Version 2.0 (the "License"). You
|
4
|
+
# may not use this file except in compliance with the License. A copy of
|
5
|
+
# the License is located at
|
6
|
+
#
|
7
|
+
# http://aws.amazon.com/apache2.0/
|
8
|
+
#
|
9
|
+
# or in the "license" file accompanying this file. This file is
|
10
|
+
# distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF
|
11
|
+
# ANY KIND, either express or implied. See the License for the specific
|
12
|
+
# language governing permissions and limitations under the License.
|
13
|
+
|
14
|
+
require 'aws/model'
|
15
|
+
require 'aws/s3/object_collection'
|
16
|
+
require 'aws/s3/bucket_version_collection'
|
17
|
+
require 'aws/s3/object_version_collection'
|
18
|
+
require 'aws/s3/multipart_upload_collection'
|
19
|
+
require 'aws/s3/tree'
|
20
|
+
require 'aws/meta_utils'
|
21
|
+
|
22
|
+
module AWS
|
23
|
+
class S3
|
24
|
+
|
25
|
+
# Represents a single S3 bucket.
|
26
|
+
#
|
27
|
+
# @example Creating a Bucket
|
28
|
+
#
|
29
|
+
# bucket = s3.buckets.create('mybucket')
|
30
|
+
#
|
31
|
+
# @example Getting an Existing Bucket
|
32
|
+
#
|
33
|
+
# bucket = s3.buckets['mybucket']
|
34
|
+
#
|
35
|
+
class Bucket
|
36
|
+
|
37
|
+
include Model
|
38
|
+
|
39
|
+
# @param [String] name
|
40
|
+
# @param [Hash] options
|
41
|
+
# @option options [String] :owner (nil) The owner id of this bucket.
|
42
|
+
def initialize(name, options = {})
|
43
|
+
# the S3 docs disagree with what the service allows,
|
44
|
+
# so it's not safe to toss out invalid bucket names
|
45
|
+
# S3::Client.validate_bucket_name!(name)
|
46
|
+
@name = name
|
47
|
+
@owner = options[:owner]
|
48
|
+
super
|
49
|
+
end
|
50
|
+
|
51
|
+
# @return [String] The bucket name
|
52
|
+
attr_reader :name
|
53
|
+
|
54
|
+
# Returns the url for this bucket.
|
55
|
+
# @return [String] url to the bucket
|
56
|
+
def url
|
57
|
+
if client.dns_compatible_bucket_name?(name)
|
58
|
+
"http://#{name}.s3.amazonaws.com/"
|
59
|
+
else
|
60
|
+
"http://s3.amazonaws.com/#{name}/"
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
64
|
+
# @return [Boolean] Returns true if the bucket has no objects
|
65
|
+
# (this includes versioned objects that are delete markers).
|
66
|
+
def empty?
|
67
|
+
versions.first ? false : true
|
68
|
+
end
|
69
|
+
|
70
|
+
# @return [String,nil] Returns the location constraint for a bucket
|
71
|
+
# (if it has one), nil otherwise.
|
72
|
+
def location_constraint
|
73
|
+
client.get_bucket_location(:bucket_name => name).location_constraint
|
74
|
+
end
|
75
|
+
|
76
|
+
# Enables versioning on this bucket.
|
77
|
+
# @return [nil]
|
78
|
+
def enable_versioning
|
79
|
+
client.set_bucket_versioning(
|
80
|
+
:bucket_name => @name,
|
81
|
+
:state => :enabled)
|
82
|
+
nil
|
83
|
+
end
|
84
|
+
|
85
|
+
# Suspends versioning on this bucket.
|
86
|
+
# @return [nil]
|
87
|
+
def suspend_versioning
|
88
|
+
client.set_bucket_versioning(
|
89
|
+
:bucket_name => @name,
|
90
|
+
:state => :suspended)
|
91
|
+
nil
|
92
|
+
end
|
93
|
+
|
94
|
+
# @return [Boolean] returns +true+ if version is enabled on this bucket.
|
95
|
+
def versioning_enabled?
|
96
|
+
versioning_state == :enabled
|
97
|
+
end
|
98
|
+
alias_method :versioned?, :versioning_enabled?
|
99
|
+
|
100
|
+
# Returns the versioning status for this bucket. States include:
|
101
|
+
#
|
102
|
+
# * +:enabled+ - currently enabled
|
103
|
+
# * +:suspended+ - currently suspended
|
104
|
+
# * +:unversioned+ - versioning has never been enabled
|
105
|
+
#
|
106
|
+
# @return [Symbol] the versioning state
|
107
|
+
def versioning_state
|
108
|
+
client.get_bucket_versioning(:bucket_name => @name).status
|
109
|
+
end
|
110
|
+
|
111
|
+
# Deletes the current bucket.
|
112
|
+
#
|
113
|
+
# @note the bucket *must* be empty.
|
114
|
+
# @return [nil]
|
115
|
+
def delete
|
116
|
+
client.delete_bucket(:bucket_name => @name)
|
117
|
+
nil
|
118
|
+
end
|
119
|
+
|
120
|
+
# Deletes any objects and versions which may be in the bucket,
|
121
|
+
# then deletes the bucket.
|
122
|
+
# @return [nil]
|
123
|
+
def delete!
|
124
|
+
versions.each{|version| version.delete }
|
125
|
+
delete
|
126
|
+
end
|
127
|
+
|
128
|
+
# @return [String] bucket owner id
|
129
|
+
def owner
|
130
|
+
@owner || client.list_buckets.owner
|
131
|
+
end
|
132
|
+
|
133
|
+
# @private
|
134
|
+
def inspect
|
135
|
+
"#<AWS::S3::Bucket:#{name}>"
|
136
|
+
end
|
137
|
+
|
138
|
+
# @return [Boolean] Returns true if the two buckets have the same name.
|
139
|
+
def ==(other)
|
140
|
+
other.kind_of?(Bucket) && other.name == name
|
141
|
+
end
|
142
|
+
|
143
|
+
# @return [Boolean] Returns true if the two buckets have the same name
|
144
|
+
def eql?(other_bucket)
|
145
|
+
self == other_bucket
|
146
|
+
end
|
147
|
+
|
148
|
+
# @note This method only indicates if there is a bucket in S3, not
|
149
|
+
# if you have permissions to work with the bucket or not.
|
150
|
+
# @return [Boolean] Returns true if the bucket exists in S3.
|
151
|
+
def exists?
|
152
|
+
begin
|
153
|
+
versioned? # makes a get bucket request without listing contents
|
154
|
+
# raises a client error if the bucket doesn't exist or
|
155
|
+
# if you don't have permission to get the bucket
|
156
|
+
# versioning status.
|
157
|
+
true
|
158
|
+
rescue Errors::NoSuchBucket => e
|
159
|
+
false # bucket does not exist
|
160
|
+
rescue Errors::ClientError => e
|
161
|
+
true # bucket exists
|
162
|
+
end
|
163
|
+
end
|
164
|
+
|
165
|
+
# @return [ObjectCollection] Represents all objects(keys) in
|
166
|
+
# this bucket.
|
167
|
+
def objects
|
168
|
+
ObjectCollection.new(self)
|
169
|
+
end
|
170
|
+
|
171
|
+
# @return [BucketVersionCollection] Represents all of the versioned
|
172
|
+
# objects stored in this bucket.
|
173
|
+
def versions
|
174
|
+
BucketVersionCollection.new(self)
|
175
|
+
end
|
176
|
+
|
177
|
+
# @return [MultipartUploadCollection] Represents all of the
|
178
|
+
# multipart uploads that are in progress for this bucket.
|
179
|
+
def multipart_uploads
|
180
|
+
MultipartUploadCollection.new(self)
|
181
|
+
end
|
182
|
+
|
183
|
+
# @private
|
184
|
+
module ACLProxy
|
185
|
+
|
186
|
+
attr_accessor :bucket
|
187
|
+
|
188
|
+
def change
|
189
|
+
yield(self)
|
190
|
+
bucket.acl = self
|
191
|
+
end
|
192
|
+
|
193
|
+
end
|
194
|
+
|
195
|
+
# Returns the bucket's access control list. This will be an
|
196
|
+
# instance of AccessControlList, plus an additional +change+
|
197
|
+
# method:
|
198
|
+
#
|
199
|
+
# bucket.acl.change do |acl|
|
200
|
+
# acl.grants.reject! do |g|
|
201
|
+
# g.grantee.canonical_user_id != bucket.owner.id
|
202
|
+
# end
|
203
|
+
# end
|
204
|
+
#
|
205
|
+
# @return [AccessControlList]
|
206
|
+
def acl
|
207
|
+
acl = client.get_bucket_acl(:bucket_name => name).acl
|
208
|
+
acl.extend ACLProxy
|
209
|
+
acl.bucket = self
|
210
|
+
acl
|
211
|
+
end
|
212
|
+
|
213
|
+
# Sets the bucket's access control list. +acl+ can be:
|
214
|
+
#
|
215
|
+
# * An XML policy as a string (which is passed to S3 uninterpreted)
|
216
|
+
# * An AccessControlList object
|
217
|
+
# * Any object that responds to +to_xml+
|
218
|
+
# * Any Hash that is acceptable as an argument to
|
219
|
+
# AccessControlList#initialize.
|
220
|
+
#
|
221
|
+
# @param [AccessControlList] acl
|
222
|
+
# @return [nil]
|
223
|
+
def acl=(acl)
|
224
|
+
client.set_bucket_acl(:bucket_name => name, :acl => acl)
|
225
|
+
nil
|
226
|
+
end
|
227
|
+
|
228
|
+
# @private
|
229
|
+
module PolicyProxy
|
230
|
+
|
231
|
+
attr_accessor :bucket
|
232
|
+
|
233
|
+
def change
|
234
|
+
yield(self)
|
235
|
+
bucket.policy = self
|
236
|
+
end
|
237
|
+
|
238
|
+
def delete
|
239
|
+
bucket.client.delete_bucket_policy(:bucket_name => bucket.name)
|
240
|
+
end
|
241
|
+
|
242
|
+
end
|
243
|
+
|
244
|
+
# Returns the bucket policy. This will be an instance of
|
245
|
+
# Policy. The returned policy will also have the methods of
|
246
|
+
# PolicyProxy mixed in, so you can use it to change the
|
247
|
+
# current policy or delete it, for example:
|
248
|
+
#
|
249
|
+
# if policy = bucket.policy
|
250
|
+
# # add a statement
|
251
|
+
# policy.change do |p|
|
252
|
+
# p.allow(...)
|
253
|
+
# end
|
254
|
+
#
|
255
|
+
# # delete the policy
|
256
|
+
# policy.delete
|
257
|
+
# end
|
258
|
+
#
|
259
|
+
# Note that changing the policy is not an atomic operation; it
|
260
|
+
# fetches the current policy, yields it to the block, and then
|
261
|
+
# sets it again. Therefore, it's possible that you may
|
262
|
+
# overwrite a concurrent update to the policy using this
|
263
|
+
# method.
|
264
|
+
#
|
265
|
+
# @return [Policy,nil] Returns the bucket policy (if it has one),
|
266
|
+
# or it returns +nil+ otherwise.
|
267
|
+
def policy
|
268
|
+
policy = client.get_bucket_policy(:bucket_name => name).policy
|
269
|
+
policy.extend(PolicyProxy)
|
270
|
+
policy.bucket = self
|
271
|
+
policy
|
272
|
+
rescue Errors::NoSuchBucketPolicy => e
|
273
|
+
nil
|
274
|
+
end
|
275
|
+
|
276
|
+
# Sets the bucket's policy.
|
277
|
+
#
|
278
|
+
# @param policy The new policy. This can be a string (which
|
279
|
+
# is assumed to contain a valid policy expressed in JSON), a
|
280
|
+
# Policy object or any object that responds to +to_json+.
|
281
|
+
# @see Policy
|
282
|
+
# @return [nil]
|
283
|
+
def policy=(policy)
|
284
|
+
client.set_bucket_policy(:bucket_name => name, :policy => policy)
|
285
|
+
nil
|
286
|
+
end
|
287
|
+
|
288
|
+
# Returns a tree that allows you to expose the bucket contents
|
289
|
+
# like a directory structure.
|
290
|
+
#
|
291
|
+
# @see Tree
|
292
|
+
# @param [Hash] options
|
293
|
+
# @option options [String] :prefix (nil) Set prefix to choose where
|
294
|
+
# the top of the tree will be. A value of +nil+ means
|
295
|
+
# that the tree will include all objects in the collection.
|
296
|
+
#
|
297
|
+
# @option options [String] :delimiter ('/') The string that separates
|
298
|
+
# each level of the tree. This is usually a directory separator.
|
299
|
+
#
|
300
|
+
# @option options [Boolean] :append (true) If true, the delimiter is
|
301
|
+
# appended to the prefix when the prefix does not already end
|
302
|
+
# with the delimiter.
|
303
|
+
#
|
304
|
+
# @return [Tree]
|
305
|
+
def as_tree options = {}
|
306
|
+
objects.as_tree(options)
|
307
|
+
end
|
308
|
+
|
309
|
+
# Generates fields for a presigned POST to this object. All
|
310
|
+
# options are sent to the PresignedPost constructor.
|
311
|
+
#
|
312
|
+
# @see PresignedPost
|
313
|
+
def presigned_post(options = {})
|
314
|
+
PresignedPost.new(self, options)
|
315
|
+
end
|
316
|
+
|
317
|
+
end
|
318
|
+
|
319
|
+
end
|
320
|
+
end
|