aws-sdk 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (205) hide show
  1. data/.yardopts +6 -0
  2. data/LICENSE.txt +171 -0
  3. data/NOTICE.txt +2 -0
  4. data/README.rdoc +189 -0
  5. data/lib/aws-sdk.rb +14 -0
  6. data/lib/aws.rb +63 -0
  7. data/lib/aws/api_config.rb +45 -0
  8. data/lib/aws/api_config/.document +0 -0
  9. data/lib/aws/api_config/EC2-2011-02-28.yml +2314 -0
  10. data/lib/aws/api_config/SNS-2010-03-31.yml +171 -0
  11. data/lib/aws/api_config/SQS-2009-02-01.yml +161 -0
  12. data/lib/aws/api_config/SimpleDB-2009-04-15.yml +278 -0
  13. data/lib/aws/api_config/SimpleEmailService-2010-12-01.yml +147 -0
  14. data/lib/aws/api_config_transform.rb +32 -0
  15. data/lib/aws/async_handle.rb +90 -0
  16. data/lib/aws/authorize_v2.rb +37 -0
  17. data/lib/aws/authorize_v3.rb +37 -0
  18. data/lib/aws/base_client.rb +524 -0
  19. data/lib/aws/cacheable.rb +92 -0
  20. data/lib/aws/common.rb +228 -0
  21. data/lib/aws/configurable.rb +36 -0
  22. data/lib/aws/configuration.rb +272 -0
  23. data/lib/aws/configured_client_methods.rb +81 -0
  24. data/lib/aws/configured_grammars.rb +65 -0
  25. data/lib/aws/configured_option_grammars.rb +46 -0
  26. data/lib/aws/configured_xml_grammars.rb +47 -0
  27. data/lib/aws/default_signer.rb +38 -0
  28. data/lib/aws/ec2.rb +321 -0
  29. data/lib/aws/ec2/attachment.rb +149 -0
  30. data/lib/aws/ec2/attachment_collection.rb +57 -0
  31. data/lib/aws/ec2/availability_zone.rb +80 -0
  32. data/lib/aws/ec2/availability_zone_collection.rb +47 -0
  33. data/lib/aws/ec2/block_device_mappings.rb +53 -0
  34. data/lib/aws/ec2/client.rb +54 -0
  35. data/lib/aws/ec2/client/xml.rb +127 -0
  36. data/lib/aws/ec2/collection.rb +39 -0
  37. data/lib/aws/ec2/config_transform.rb +63 -0
  38. data/lib/aws/ec2/elastic_ip.rb +107 -0
  39. data/lib/aws/ec2/elastic_ip_collection.rb +85 -0
  40. data/lib/aws/ec2/errors.rb +29 -0
  41. data/lib/aws/ec2/filtered_collection.rb +65 -0
  42. data/lib/aws/ec2/has_permissions.rb +46 -0
  43. data/lib/aws/ec2/image.rb +245 -0
  44. data/lib/aws/ec2/image_collection.rb +235 -0
  45. data/lib/aws/ec2/instance.rb +515 -0
  46. data/lib/aws/ec2/instance_collection.rb +276 -0
  47. data/lib/aws/ec2/key_pair.rb +86 -0
  48. data/lib/aws/ec2/key_pair_collection.rb +102 -0
  49. data/lib/aws/ec2/permission_collection.rb +177 -0
  50. data/lib/aws/ec2/region.rb +81 -0
  51. data/lib/aws/ec2/region_collection.rb +55 -0
  52. data/lib/aws/ec2/request.rb +27 -0
  53. data/lib/aws/ec2/reserved_instances.rb +50 -0
  54. data/lib/aws/ec2/reserved_instances_collection.rb +44 -0
  55. data/lib/aws/ec2/reserved_instances_offering.rb +55 -0
  56. data/lib/aws/ec2/reserved_instances_offering_collection.rb +43 -0
  57. data/lib/aws/ec2/resource.rb +340 -0
  58. data/lib/aws/ec2/resource_tag_collection.rb +218 -0
  59. data/lib/aws/ec2/security_group.rb +246 -0
  60. data/lib/aws/ec2/security_group/ip_permission.rb +70 -0
  61. data/lib/aws/ec2/security_group/ip_permission_collection.rb +59 -0
  62. data/lib/aws/ec2/security_group_collection.rb +132 -0
  63. data/lib/aws/ec2/snapshot.rb +138 -0
  64. data/lib/aws/ec2/snapshot_collection.rb +90 -0
  65. data/lib/aws/ec2/tag.rb +88 -0
  66. data/lib/aws/ec2/tag_collection.rb +114 -0
  67. data/lib/aws/ec2/tagged_collection.rb +48 -0
  68. data/lib/aws/ec2/tagged_item.rb +87 -0
  69. data/lib/aws/ec2/volume.rb +190 -0
  70. data/lib/aws/ec2/volume_collection.rb +95 -0
  71. data/lib/aws/errors.rb +129 -0
  72. data/lib/aws/http/builtin_handler.rb +69 -0
  73. data/lib/aws/http/curb_handler.rb +123 -0
  74. data/lib/aws/http/handler.rb +77 -0
  75. data/lib/aws/http/httparty_handler.rb +61 -0
  76. data/lib/aws/http/request.rb +136 -0
  77. data/lib/aws/http/request_param.rb +63 -0
  78. data/lib/aws/http/response.rb +75 -0
  79. data/lib/aws/ignore_result_element.rb +38 -0
  80. data/lib/aws/indifferent_hash.rb +86 -0
  81. data/lib/aws/inflection.rb +46 -0
  82. data/lib/aws/lazy_error_classes.rb +64 -0
  83. data/lib/aws/meta_utils.rb +43 -0
  84. data/lib/aws/model.rb +57 -0
  85. data/lib/aws/naming.rb +32 -0
  86. data/lib/aws/option_grammar.rb +544 -0
  87. data/lib/aws/policy.rb +912 -0
  88. data/lib/aws/rails.rb +209 -0
  89. data/lib/aws/record.rb +79 -0
  90. data/lib/aws/record/attribute.rb +94 -0
  91. data/lib/aws/record/attribute_macros.rb +288 -0
  92. data/lib/aws/record/attributes/boolean.rb +49 -0
  93. data/lib/aws/record/attributes/datetime.rb +86 -0
  94. data/lib/aws/record/attributes/float.rb +48 -0
  95. data/lib/aws/record/attributes/integer.rb +68 -0
  96. data/lib/aws/record/attributes/sortable_float.rb +60 -0
  97. data/lib/aws/record/attributes/sortable_integer.rb +95 -0
  98. data/lib/aws/record/attributes/string.rb +69 -0
  99. data/lib/aws/record/base.rb +728 -0
  100. data/lib/aws/record/conversion.rb +38 -0
  101. data/lib/aws/record/dirty_tracking.rb +286 -0
  102. data/lib/aws/record/errors.rb +153 -0
  103. data/lib/aws/record/exceptions.rb +48 -0
  104. data/lib/aws/record/finder_methods.rb +262 -0
  105. data/lib/aws/record/naming.rb +31 -0
  106. data/lib/aws/record/scope.rb +157 -0
  107. data/lib/aws/record/validations.rb +653 -0
  108. data/lib/aws/record/validator.rb +237 -0
  109. data/lib/aws/record/validators/acceptance.rb +51 -0
  110. data/lib/aws/record/validators/block.rb +38 -0
  111. data/lib/aws/record/validators/confirmation.rb +43 -0
  112. data/lib/aws/record/validators/count.rb +108 -0
  113. data/lib/aws/record/validators/exclusion.rb +43 -0
  114. data/lib/aws/record/validators/format.rb +57 -0
  115. data/lib/aws/record/validators/inclusion.rb +56 -0
  116. data/lib/aws/record/validators/length.rb +107 -0
  117. data/lib/aws/record/validators/numericality.rb +138 -0
  118. data/lib/aws/record/validators/presence.rb +45 -0
  119. data/lib/aws/resource_cache.rb +39 -0
  120. data/lib/aws/response.rb +113 -0
  121. data/lib/aws/response_cache.rb +50 -0
  122. data/lib/aws/s3.rb +109 -0
  123. data/lib/aws/s3/access_control_list.rb +252 -0
  124. data/lib/aws/s3/acl_object.rb +266 -0
  125. data/lib/aws/s3/bucket.rb +320 -0
  126. data/lib/aws/s3/bucket_collection.rb +122 -0
  127. data/lib/aws/s3/bucket_version_collection.rb +85 -0
  128. data/lib/aws/s3/client.rb +999 -0
  129. data/lib/aws/s3/client/xml.rb +190 -0
  130. data/lib/aws/s3/data_options.rb +99 -0
  131. data/lib/aws/s3/errors.rb +43 -0
  132. data/lib/aws/s3/multipart_upload.rb +318 -0
  133. data/lib/aws/s3/multipart_upload_collection.rb +78 -0
  134. data/lib/aws/s3/object_collection.rb +159 -0
  135. data/lib/aws/s3/object_metadata.rb +67 -0
  136. data/lib/aws/s3/object_upload_collection.rb +83 -0
  137. data/lib/aws/s3/object_version.rb +141 -0
  138. data/lib/aws/s3/object_version_collection.rb +78 -0
  139. data/lib/aws/s3/paginated_collection.rb +94 -0
  140. data/lib/aws/s3/policy.rb +76 -0
  141. data/lib/aws/s3/prefix_and_delimiter_collection.rb +56 -0
  142. data/lib/aws/s3/prefixed_collection.rb +84 -0
  143. data/lib/aws/s3/presigned_post.rb +504 -0
  144. data/lib/aws/s3/request.rb +198 -0
  145. data/lib/aws/s3/s3_object.rb +794 -0
  146. data/lib/aws/s3/tree.rb +116 -0
  147. data/lib/aws/s3/tree/branch_node.rb +71 -0
  148. data/lib/aws/s3/tree/child_collection.rb +108 -0
  149. data/lib/aws/s3/tree/leaf_node.rb +99 -0
  150. data/lib/aws/s3/tree/node.rb +22 -0
  151. data/lib/aws/s3/tree/parent.rb +90 -0
  152. data/lib/aws/s3/uploaded_part.rb +82 -0
  153. data/lib/aws/s3/uploaded_part_collection.rb +86 -0
  154. data/lib/aws/service_interface.rb +60 -0
  155. data/lib/aws/simple_db.rb +202 -0
  156. data/lib/aws/simple_db/attribute.rb +159 -0
  157. data/lib/aws/simple_db/attribute_collection.rb +227 -0
  158. data/lib/aws/simple_db/client.rb +52 -0
  159. data/lib/aws/simple_db/client/options.rb +34 -0
  160. data/lib/aws/simple_db/client/xml.rb +68 -0
  161. data/lib/aws/simple_db/consistent_read_option.rb +42 -0
  162. data/lib/aws/simple_db/delete_attributes.rb +64 -0
  163. data/lib/aws/simple_db/domain.rb +118 -0
  164. data/lib/aws/simple_db/domain_collection.rb +116 -0
  165. data/lib/aws/simple_db/domain_metadata.rb +112 -0
  166. data/lib/aws/simple_db/errors.rb +46 -0
  167. data/lib/aws/simple_db/expect_condition_option.rb +45 -0
  168. data/lib/aws/simple_db/item.rb +84 -0
  169. data/lib/aws/simple_db/item_collection.rb +594 -0
  170. data/lib/aws/simple_db/item_data.rb +70 -0
  171. data/lib/aws/simple_db/put_attributes.rb +62 -0
  172. data/lib/aws/simple_db/request.rb +27 -0
  173. data/lib/aws/simple_email_service.rb +373 -0
  174. data/lib/aws/simple_email_service/client.rb +39 -0
  175. data/lib/aws/simple_email_service/client/options.rb +24 -0
  176. data/lib/aws/simple_email_service/client/xml.rb +38 -0
  177. data/lib/aws/simple_email_service/email_address_collection.rb +66 -0
  178. data/lib/aws/simple_email_service/errors.rb +29 -0
  179. data/lib/aws/simple_email_service/quotas.rb +64 -0
  180. data/lib/aws/simple_email_service/request.rb +27 -0
  181. data/lib/aws/sns.rb +69 -0
  182. data/lib/aws/sns/client.rb +37 -0
  183. data/lib/aws/sns/client/options.rb +24 -0
  184. data/lib/aws/sns/client/xml.rb +38 -0
  185. data/lib/aws/sns/errors.rb +29 -0
  186. data/lib/aws/sns/policy.rb +49 -0
  187. data/lib/aws/sns/request.rb +27 -0
  188. data/lib/aws/sns/subscription.rb +100 -0
  189. data/lib/aws/sns/subscription_collection.rb +84 -0
  190. data/lib/aws/sns/topic.rb +384 -0
  191. data/lib/aws/sns/topic_collection.rb +70 -0
  192. data/lib/aws/sns/topic_subscription_collection.rb +58 -0
  193. data/lib/aws/sqs.rb +70 -0
  194. data/lib/aws/sqs/client.rb +38 -0
  195. data/lib/aws/sqs/client/xml.rb +36 -0
  196. data/lib/aws/sqs/errors.rb +33 -0
  197. data/lib/aws/sqs/policy.rb +50 -0
  198. data/lib/aws/sqs/queue.rb +507 -0
  199. data/lib/aws/sqs/queue_collection.rb +105 -0
  200. data/lib/aws/sqs/received_message.rb +184 -0
  201. data/lib/aws/sqs/received_sns_message.rb +112 -0
  202. data/lib/aws/sqs/request.rb +44 -0
  203. data/lib/aws/xml_grammar.rb +923 -0
  204. data/rails/init.rb +15 -0
  205. metadata +298 -0
@@ -0,0 +1,43 @@
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/ec2/collection'
15
+ require 'aws/ec2/tagged_collection'
16
+ require 'aws/ec2/reserved_instances_offering'
17
+
18
+ module AWS
19
+ class EC2
20
+ class ReservedInstancesOfferingCollection < Collection
21
+
22
+ include TaggedCollection
23
+
24
+ def member_class
25
+ ReservedInstancesOffering
26
+ end
27
+
28
+ def each &block
29
+ response = filtered_request(:describe_reserved_instances_offerings)
30
+ response.reserved_instances_offerings_set.each do |item|
31
+
32
+ reserved_instance_offering = ReservedInstancesOffering.new(
33
+ item.reserved_instances_offering_id,
34
+ :config => config)
35
+
36
+ yield(reserved_instance_offering)
37
+
38
+ end
39
+ end
40
+
41
+ end
42
+ end
43
+ end
@@ -0,0 +1,340 @@
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/cacheable'
16
+
17
+ module AWS
18
+ class EC2
19
+
20
+ # @private
21
+ class Resource
22
+
23
+ include Model
24
+ include Cacheable
25
+
26
+ def initialize(*args)
27
+ super
28
+ @memoized_attributes = {}
29
+ if options = args.last and
30
+ options.kind_of?(Hash)
31
+ self.class.memoized_attributes.each do |att|
32
+ @memoized_attributes[att] = options[att] if
33
+ options.key?(att)
34
+ end
35
+ end
36
+ end
37
+
38
+ def inspect
39
+ "<#{self.class}:#{__resource_id__}>"
40
+ end
41
+
42
+ def local_cache_key
43
+ "#{self.class}:#{__resource_id__}"
44
+ end
45
+
46
+ def attributes_from_response(response)
47
+ if atts = super
48
+ self.class.memoized_attributes.each do |att|
49
+ @memoized_attributes[att] = atts[att]
50
+ end
51
+ atts
52
+ end
53
+ end
54
+
55
+ def ==(other)
56
+ other.kind_of?(self.class) and
57
+ __resource_id__ == other.__resource_id__
58
+ end
59
+
60
+ alias_method :eql?, :==
61
+
62
+ protected
63
+ def __resource_id__
64
+ send(resource_id_method)
65
+ end
66
+
67
+ protected
68
+ def find_in_response(resp)
69
+ resp.send(plural_name + "_set").find do |obj|
70
+ obj.send(response_id_method) == __resource_id__
71
+ end
72
+ end
73
+
74
+ protected
75
+ def response_id_method
76
+ # e.g. instance_id
77
+ inflected_name + "_" + resource_id_method.to_s
78
+ end
79
+
80
+ protected
81
+ def resource_id_method
82
+ @resource_id_method ||=
83
+ case
84
+ when respond_to?(:id) && method(:id).owner != Kernel
85
+ # id isn't defined on Object in some Ruby versions, in
86
+ # others it is an alias for object_id; if the method is
87
+ # not owned by Kernel we can assume that it has been
88
+ # overridden in a subclass
89
+ :id
90
+ when respond_to?(:name)
91
+ :name
92
+ else
93
+ raise NotImplementedError
94
+ end
95
+ end
96
+
97
+ protected
98
+ def describe_call
99
+ name = self.class.describe_call_name
100
+ if client.respond_to?(name)
101
+ client.send(name, Hash[[[(response_id_method.to_s + "s").to_sym,
102
+ [__resource_id__]]]])
103
+ else
104
+ raise NotImplementedError
105
+ end
106
+ end
107
+
108
+ protected
109
+ def describe_attribute_call(attribute_name)
110
+ name = describe_attribute_call_name
111
+ client.send(name, Hash[[[response_id_method.to_sym,
112
+ __resource_id__],
113
+ [:attribute, attribute_name]]])
114
+ end
115
+
116
+ protected
117
+ def get_mutable_attribute(name)
118
+ att_name = Inflection.class_name(name.to_s)
119
+ att_name = att_name[0,1].downcase + att_name[1..-1]
120
+ method_name = "describe_#{inflected_name}_attribute"
121
+ resp = client.send(method_name,
122
+ Hash[[[:"#{inflected_name}_id", __resource_id__],
123
+ [:attribute, att_name]]])
124
+ if att = resp.send(name) and
125
+ att.respond_to?(:value)
126
+ att.value
127
+ else
128
+ nil
129
+ end
130
+ end
131
+
132
+ protected
133
+ def set_mutable_attribute(name, input_value)
134
+ value = send("translate_input_for_#{name}", input_value) if
135
+ respond_to?("translate_input_for_#{name}")
136
+ opts = {}
137
+ opts[name] = { :value => value }
138
+ opts["#{inflected_name}_id".to_sym] = __resource_id__
139
+ method_name = "modify_#{inflected_name}_attribute"
140
+ resp = client.send(method_name, opts)
141
+ input_value
142
+ end
143
+
144
+ protected
145
+ def attributes_from_response_object(obj)
146
+ atts = {}
147
+ self.class.describe_call_attributes.each do |att, response_att|
148
+ raw_value = (obj.send(response_att) if obj.respond_to?(response_att))
149
+ translated = send("translate_describe_output_for_#{response_att}", raw_value)
150
+ atts[att] = translated
151
+ end
152
+ atts
153
+ end
154
+
155
+ protected
156
+ def attributes_from_describe_attribute_response(resp)
157
+ requested_att = resp.request_options[:attribute]
158
+ return nil unless
159
+ resp.request_options[response_id_method.to_sym] == __resource_id__
160
+
161
+ response_att = Inflection.ruby_name(requested_att)
162
+ if getter = self.class.mutable_attributes[response_att.to_sym]
163
+ raw_value = resp.send(response_att)
164
+ translated = send("translate_describe_attribute_output_for_#{response_att}", raw_value)
165
+ Hash[[[getter, translated]]]
166
+ end
167
+ end
168
+
169
+ module InflectionMethods
170
+
171
+ protected
172
+ def describe_call_name
173
+ name = "describe_#{plural_name}"
174
+ end
175
+
176
+ protected
177
+ def describe_attribute_call_name
178
+ "describe_#{inflected_name}_attribute"
179
+ end
180
+
181
+ protected
182
+ def inflected_name
183
+ Inflection.ruby_name(class_name)
184
+ end
185
+
186
+ protected
187
+ def class_name
188
+ self.kind_of?(Class) ? name : self.class.name
189
+ end
190
+
191
+ protected
192
+ def plural_name
193
+ name = inflected_name
194
+ name[-1..-1] == 's' ? name : name + "s"
195
+ end
196
+
197
+ protected
198
+ def output_translator(name, type)
199
+ "translate_#{type}_output_for_#{name}"
200
+ end
201
+
202
+ end
203
+
204
+ extend InflectionMethods
205
+ include InflectionMethods
206
+
207
+ # @private
208
+ class AttributeBuilder
209
+
210
+ include InflectionMethods
211
+
212
+ def initialize(klass, name, type)
213
+ @klass = klass
214
+ @name = name
215
+ @type = type
216
+ translate_input { |v| v }
217
+ translate_output { |v| v }
218
+ end
219
+
220
+ def translate_input(&blk)
221
+ @klass.send(:define_method, "translate_input_for_#{@name}", &blk)
222
+ end
223
+
224
+ def translate_output(&blk)
225
+ @klass.send(:define_method, output_translator(@name, @type), &blk)
226
+ end
227
+
228
+ def self.eval(klass, name, type, opts = {}, &blk)
229
+ i = new(klass, name, type)
230
+ i.instance_eval do
231
+ translate_output { |v| v.tr("-","_").to_sym if v } if opts[:to_sym]
232
+ translate_output { |v| v.value if v } if opts[:value_wrapper]
233
+ instance_eval(&blk) if blk
234
+ end
235
+ end
236
+ end
237
+
238
+ class NotFound < StandardError; end
239
+
240
+ class << self
241
+
242
+ def memoized_attributes; []; end
243
+
244
+ # @private
245
+ protected
246
+ def describe_call_attribute(name, opts = {}, &blk)
247
+ getter_name = opts[:getter] || name
248
+
249
+ # define the accessor
250
+ define_describe_call_getter(getter_name, opts) do |*args|
251
+ begin
252
+ retrieve_attribute(getter_name) { describe_call }
253
+ rescue Cacheable::NoData => e
254
+ name = Inflection.ruby_name(self.class.name).tr("_", " ")
255
+ raise NotFound, "unable to find the #{name}"
256
+ end
257
+ end
258
+
259
+ # ensure we are populating from the describe call
260
+ populate_from describe_call_name do |resp|
261
+ if obj = find_in_response(resp)
262
+ attributes_from_response_object(obj)
263
+ end
264
+ end
265
+
266
+ # add it to the list of attributes to populate from the response object
267
+ add_to_attribute_map(:describe_call_attributes, getter_name, name)
268
+
269
+ if opts[:memoize]
270
+ all_memoized = memoized_attributes
271
+ all_memoized << getter_name
272
+ MetaUtils.extend_method(self, :memoized_attributes) { all_memoized }
273
+ end
274
+
275
+ # evaluate translators
276
+ AttributeBuilder.eval(self, name, :describe, opts, &blk)
277
+ end
278
+
279
+ protected
280
+ def add_to_attribute_map(map_name, key, value)
281
+ all_attributes = {}
282
+ all_attributes = send(map_name) if respond_to?(map_name)
283
+ all_attributes[key] = value
284
+ MetaUtils.extend_method(self, map_name) do
285
+ all_attributes
286
+ end
287
+ end
288
+
289
+ protected
290
+ def define_describe_call_getter(getter_name, opts, &block)
291
+ if opts[:memoize]
292
+ original_block = block
293
+ block = lambda do
294
+ if @memoized_attributes.has_key?(getter_name)
295
+ @memoized_attributes[getter_name]
296
+ else
297
+ instance_eval(&original_block)
298
+ end
299
+ end
300
+ end
301
+ define_method(getter_name, &block)
302
+ end
303
+
304
+ # @private
305
+ def mutable_attribute(name, opts = {}, &blk)
306
+ getter = opts[:getter] || name
307
+ setter = opts[:setter] || "#{name}="
308
+
309
+ # e.g. "instanceType" or "blockDeviceMapping"
310
+ # as passed to the :attribute option of the service call
311
+ request_name = Inflection.class_name(name.to_s)
312
+ request_name = request_name[0,1].downcase + request_name[1..-1]
313
+
314
+ # define the getter and setter
315
+ define_method(getter) do
316
+ retrieve_attribute(getter) { describe_attribute_call(request_name) }
317
+ end
318
+ define_method(setter) do |input_value|
319
+ set_mutable_attribute(name, input_value)
320
+ end unless opts[:setter] == false
321
+
322
+ # make sure we will populate from this type of response
323
+ populate_from describe_attribute_call_name do |resp|
324
+ attributes_from_describe_attribute_response(resp)
325
+ end
326
+
327
+ # describe how to populate this attribute
328
+ add_to_attribute_map(:mutable_attributes, name, getter)
329
+
330
+ # evaluate translations, etc.
331
+ AttributeBuilder.eval(self, name, :describe_attribute,
332
+ { :value_wrapper => true }.merge(opts), &blk)
333
+ end
334
+
335
+ end
336
+
337
+ end
338
+
339
+ end
340
+ end
@@ -0,0 +1,218 @@
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/inflection'
16
+ require 'aws/ec2/resource'
17
+ require 'aws/ec2/tag'
18
+
19
+ module AWS
20
+ class EC2
21
+
22
+ # Represents the EC2 tags associated with a single resource.
23
+ #
24
+ # @example Manipulating the tags of an EC2 instance
25
+ # i = ec2.instances["i-123"]
26
+ # i.tags.to_h # => { "foo" => "bar", ... }
27
+ # i.tags.clear
28
+ # i.tags.stage = "production"
29
+ # i.tags.stage # => "production"
30
+ class ResourceTagCollection
31
+
32
+ include Model
33
+ include Enumerable
34
+
35
+ # @private
36
+ def initialize(resource, opts = {})
37
+ @resource = resource
38
+ super(opts)
39
+ @tags = TagCollection.new(:config => config).
40
+ filter("resource-id", @resource.send(:__resource_id__)).
41
+ filter("resource-type", @resource.tagging_resource_type)
42
+ end
43
+
44
+ # @return [String] The value of the tag with the given key, or
45
+ # nil if no such tag exists.
46
+ #
47
+ # @param [String or Symbol] key The key of the tag to return.
48
+ def [](key)
49
+ if cached = cached_tags
50
+ return cached[key.to_s]
51
+ end
52
+ Tag.new(@resource, key, :config => config).value
53
+ rescue Resource::NotFound => e
54
+ nil
55
+ end
56
+
57
+ # @return [Boolean] True if the resource has no tags.
58
+ def empty?
59
+ if cached = cached_tags
60
+ return cached.empty?
61
+ end
62
+ @tags.to_a.empty?
63
+ end
64
+
65
+ # @return [Boolean] True if the resource has a tag for the given key.
66
+ #
67
+ # @param [String or Symbol] The key of the tag to check.
68
+ def has_key?(key)
69
+ if cached = cached_tags
70
+ return cached.has_key?(key.to_s)
71
+ end
72
+ !@tags.filter("key", key.to_s).to_a.empty?
73
+ end
74
+ alias_method :key?, :has_key?
75
+ alias_method :include?, :has_key?
76
+ alias_method :member?, :has_key?
77
+
78
+ # @return [Boolean] True if the resource has a tag with the given value.
79
+ #
80
+ # @param [String or Symbol] The value to check.
81
+ def has_value?(value)
82
+ if cached = cached_tags
83
+ return cached.values.include?(value)
84
+ end
85
+ !@tags.filter("value", value.to_s).to_a.empty?
86
+ end
87
+ alias_method :value?, :has_value?
88
+
89
+ # Changes the value of a tag.
90
+ #
91
+ # @param [String or Symbol] The key of the tag to set.
92
+ #
93
+ # @param [String] The new value. If this is nil, the tag will
94
+ # be deleted.
95
+ def []=(key, value)
96
+ if value
97
+ @tags.create(@resource, key.to_s, :value => value)
98
+ else
99
+ delete(key)
100
+ end
101
+ end
102
+ alias_method :store, :[]=
103
+
104
+ # Adds a tag with a blank value.
105
+ #
106
+ # @param [String or Symbol] key The key of the new tag.
107
+ def add(key)
108
+ @tags.create(@resource, key.to_s)
109
+ end
110
+ alias_method :<<, :add
111
+
112
+ # Sets multiple tags in a single request.
113
+ #
114
+ # @param [Hash] tags The tags to set. The keys of the hash
115
+ # may be strings or symbols, and the values must be strings.
116
+ # Note that there is no way to both set and delete tags
117
+ # simultaneously.
118
+ def set(tags)
119
+ client.create_tags(:resources => [@resource.send(:__resource_id__)],
120
+ :tags => tags.map do |(key, value)|
121
+ { :key => key.to_s,
122
+ :value => value }
123
+ end)
124
+ end
125
+ alias_method :update, :set
126
+
127
+ # Allows setting and getting individual tags through instance
128
+ # methods. For example:
129
+ #
130
+ # tags.color = "red"
131
+ # tags.color # => "red"
132
+ def method_missing(m, *args)
133
+ if m.to_s[-1,1] == "="
134
+ send(:[]=, m.to_s[0...-1], *args)
135
+ else
136
+ super
137
+ end
138
+ end
139
+
140
+ # Deletes the tags with the given keys (which may be strings
141
+ # or symbols).
142
+ def delete(*keys)
143
+ return if keys.empty?
144
+ client.delete_tags(:resources => [@resource.send(:__resource_id__)],
145
+ :tags => keys.map do |key|
146
+ { :key => key.to_s }
147
+ end)
148
+ end
149
+
150
+ # Removes all tags from the resource.
151
+ def clear
152
+ client.delete_tags(:resources => [@resource.send(:__resource_id__)])
153
+ end
154
+
155
+ # @yield [key, value] The key/value pairs of each tag
156
+ # associated with the resource. If the block has an arity
157
+ # of 1, the key and value will be yielded in an aray.
158
+ def each(&blk)
159
+ if cached = cached_tags
160
+ cached.each(&blk)
161
+ return
162
+ end
163
+ @tags.filtered_request(:describe_tags).tag_set.each do |tag|
164
+ if blk.arity == 2
165
+ yield(tag.key, tag.value)
166
+ else
167
+ yield([tag.key, tag.value])
168
+ end
169
+ end
170
+ nil
171
+ end
172
+ alias_method :each_pair, :each
173
+
174
+ # @return [Array] An array of the tag values associated with
175
+ # the given keys. An entry for a key that has no value
176
+ # (i.e. there is no such tag) will be nil.
177
+ def values_at(*keys)
178
+ if cached = cached_tags
179
+ return cached.values_at(*keys.map { |k| k.to_s })
180
+ end
181
+ keys = keys.map { |k| k.to_s }
182
+ tag_set = @tags.
183
+ filter("key", *keys).
184
+ filtered_request(:describe_tags).tag_set
185
+ hash = tag_set.inject({}) do |hash, tag|
186
+ hash[tag.key] = tag.value
187
+ hash
188
+ end
189
+ keys.map do |key|
190
+ hash[key]
191
+ end
192
+ end
193
+
194
+ # @return [Hash] The current tags as a hash, where the keys
195
+ # are the tag keys as strings and the values are the tag
196
+ # values as strings.
197
+ def to_h
198
+ if cached = cached_tags
199
+ return cached
200
+ end
201
+ @tags.filtered_request(:describe_tags).tag_set.inject({}) do |hash, tag|
202
+ hash[tag.key] = tag.value
203
+ hash
204
+ end
205
+ end
206
+
207
+ private
208
+ def cached_tags
209
+ if @resource.respond_to?(:cached_tags) and
210
+ cached = @resource.cached_tags
211
+ cached
212
+ end
213
+ end
214
+
215
+ end
216
+
217
+ end
218
+ end