steamcannon-aws 2.3.26.1

Sign up to get free protection for your applications and to get access to all the features.
data/README.markdown ADDED
@@ -0,0 +1,187 @@
1
+ # Appoxy AWS Library
2
+
3
+ A Ruby gem for all Amazon Web Services.
4
+
5
+ Brought to you by: [![Appoxy](http://www.simpledeployr.com/images/global/appoxy-small.png)](http://www.appoxy.com)
6
+
7
+ ## Discussion Group
8
+
9
+ http://groups.google.com/group/ruby-aws
10
+
11
+ ## Issue Tracker
12
+
13
+ http://appoxy.lighthouseapp.com/projects/38441-aws/overview
14
+
15
+ ## Documentation
16
+
17
+ http://rdoc.info/projects/appoxy/aws
18
+
19
+ ## Appoxy Amazon Web Services Ruby Gems
20
+
21
+ Published by Appoxy LLC, under the MIT License. Special thanks to RightScale from which this project is forked.
22
+
23
+ ## INSTALL:
24
+
25
+ THEN (you should have http://gemcutter.org in your sources and it MUST be above rubyforge.org):
26
+
27
+ gem install aws
28
+
29
+
30
+ ## DESCRIPTION:
31
+
32
+ The RightScale AWS gems have been designed to provide a robust, fast, and secure interface to Amazon EC2, EBS, S3, SQS, SDB, and CloudFront.
33
+ These gems have been used in production by RightScale since late 2006 and are being maintained to track enhancements made by Amazon.
34
+ The RightScale AWS gems comprise:
35
+
36
+ - Aws::Ec2 -- interface to Amazon EC2 (Elastic Compute Cloud) and the associated EBS (Elastic Block Store)
37
+ - Aws::S3 and Aws::S3Interface -- interface to Amazon S3 (Simple Storage Service)
38
+ - Aws::Sqs and Aws::SqsInterface -- interface to Amazon SQS (Simple Queue Service)
39
+ - Aws::SdbInterface and Aws::ActiveSdb -- interface to Amazon SDB (SimpleDB)
40
+ - Aws::AcfInterface -- interface to Amazon CloudFront, a content distribution service
41
+ - Aws::ElbInterface -- interface to Amazon Load Balancing service
42
+ - Aws::MonInterface -- interface to Amazon CloudWatch monitoring service
43
+
44
+
45
+ ## FEATURES:
46
+
47
+ - Full programmmatic access to EC2, EBS, S3, SQS, SDB, ELB, and CloudFront.
48
+ - Complete error handling: all operations check for errors and report complete
49
+ error information by raising an AwsError.
50
+ - Persistent HTTP connections with robust network-level retry layer using
51
+ RightHttpConnection). This includes socket timeouts and retries.
52
+ - Robust HTTP-level retry layer. Certain (user-adjustable) HTTP errors returned
53
+ by Amazon's services are classified as temporary errors.
54
+ These errors are automaticallly retried using exponentially increasing intervals.
55
+ The number of retries is user-configurable.
56
+ - Fast REXML-based parsing of responses (as fast as a pure Ruby solution allows).
57
+ - Uses libxml (if available) for faster response parsing.
58
+ - Support for large S3 list operations. Buckets and key subfolders containing
59
+ many (> 1000) keys are listed in entirety. Operations based on list (like
60
+ bucket clear) work on arbitrary numbers of keys.
61
+ - Support for streaming GETs from S3, and streaming PUTs to S3 if the data source is a file.
62
+ - Support for single-threaded usage, multithreaded usage, as well as usage with multiple
63
+ AWS accounts.
64
+ - Support for both first- and second-generation SQS (API versions 2007-05-01
65
+ and 2008-01-01). These versions of SQS are not compatible.
66
+ - Support for signature versions 0, 1 and 2 on all services.
67
+ - Interoperability with any cloud running Eucalyptus (http://eucalyptus.cs.ucsb.edu)
68
+ - Test suite (requires AWS account to do "live" testing).
69
+
70
+ ## THREADING:
71
+
72
+ All AWS interfaces offer three threading options:
73
+ 1. Use a single persistent HTTP connection per process. :single
74
+ 2. Use a persistent HTTP connection per Ruby thread. :per_thread
75
+ 3. Open a new connection for each request. :per_request
76
+
77
+ Either way, it doesn't matter how many (for example) Aws::S3 objects you create,
78
+ they all use the same per-program or per-thread
79
+ connection. The purpose of sharing the connection is to keep a single
80
+ persistent HTTP connection open to avoid paying connection
81
+ overhead on every request. However, if you have multiple concurrent
82
+ threads, you may want or need an HTTP connection per thread to enable
83
+ concurrent requests to AWS. The way this plays out in practice is:
84
+ 1. If you have a non-multithreaded Ruby program, use the non-multithreaded setting.
85
+ 2. If you have a multi-threaded Ruby program, use the multithreaded setting to enable
86
+ concurrent requests to S3 (or SQS, or SDB, or EC2).
87
+ 3. For running under Mongrel/Rails, use the non-multithreaded setting even though
88
+ mongrel is multithreaded. This is because only one Rails handler is invoked at
89
+ time (i.e. it acts like a single-threaded program)
90
+
91
+ Note that due to limitations in the I/O of the Ruby interpreter you
92
+ may not get the degree of parallelism you may expect with the multi-threaded setting.
93
+
94
+ By default, EC2/S3/SQS/SDB/ACF interface instances are created in single-threaded mode. Set
95
+ params[:connection_mode] to :per_thread in the initialization arguments to use
96
+ multithreaded mode.
97
+
98
+ ## GETTING STARTED:
99
+
100
+ * For EC2 read Aws::Ec2 and consult the Amazon EC2 API documentation at
101
+ http://developer.amazonwebservices.com/connect/kbcategory.jspa?categoryID=87
102
+ * For S3 read Aws::S3 and consult the Amazon S3 API documentation at
103
+ http://developer.amazonwebservices.com/connect/kbcategory.jspa?categoryID=48
104
+ * For SQS read Aws::Sqs and consult the Amazon SQS API documentation at
105
+ http://developer.amazonwebservices.com/connect/kbcategory.jspa?categoryID=31
106
+
107
+ Amazon's Migration Guide for moving from first to second generation SQS is
108
+ avalable at:
109
+ http://developer.amazonwebservices.com/connect/entry.jspa?externalID=1148
110
+ * For SDB read Aws::SdbInterface, Aws::ActiveSdb, and consult the Amazon SDB API documentation at
111
+ http://developer.amazonwebservices.com/connect/kbcategory.jspa?categoryID=141
112
+ * For CloudFront (ACF) read Aws::AcfInterface and consult the Amazon CloudFront API documentation at
113
+ http://developer.amazonwebservices.com/connect/kbcategory.jspa?categoryID=213
114
+
115
+ ## KNOWN ISSUES:
116
+
117
+ - 7/08: A user has reported that uploads of large files on Windows may be broken on some
118
+ Win platforms due to a buggy File.lstat.size. Use the following monkey-patch at your own risk,
119
+ as it has been proven to break Rails 2.0 on Windows:
120
+
121
+ require 'win32/file'
122
+ class File
123
+ def lstat
124
+ self.stat
125
+ end
126
+ end
127
+
128
+
129
+ - Attempting to use the Gibberish plugin (used by the Beast forum app)
130
+ will break right_aws as well as lots of other code. Gibberish
131
+ changes the semantics of core Ruby (specifically, the String class) and thus presents a reliability
132
+ problem for most Ruby programs.
133
+
134
+ - 2/11/08: If you use Aws in conjunction with attachment_fu, the
135
+ right_aws gem must be included (using the require statement) AFTER
136
+ attachment_fu. If right_aws is loaded before attachment_fu, you'll
137
+ encounter errors similar to:
138
+
139
+ s3.amazonaws.com temporarily unavailable: (wrong number of arguments (5 for 4))
140
+
141
+ or
142
+
143
+ 'incompatible Net::HTTP monkey-patch'
144
+
145
+ This is due to a conflict between the right_http_connection gem and another
146
+ gem required by attachment_fu. It may be possible to require right_aws (and
147
+ thus right_http_connection) in the .after_initialize method of the config object in
148
+ environment.rb (check the docs for Rails::Configuration.after_initialize).
149
+
150
+ - 8/07: Amazon has changed the semantics of the SQS service. A
151
+ new queue may not be created within 60 seconds of the destruction of any
152
+ older queue with the same name. Certain methods of Aws::Sqs and
153
+ Aws::SqsInterface will fail with the message:
154
+ "AWS.SimpleQueueService.QueueDeletedRecently: You must wait 60 seconds after deleting a queue before you can create another with the same name."
155
+
156
+ ## REQUIREMENTS:
157
+
158
+ Aws requires REXML and the right_http_connection gem.
159
+ If libxml and its Ruby bindings (distributed in the libxml-ruby gem) are
160
+ present, Aws can be configured to use them:
161
+ Aws::AwsParser.xml_lib = 'libxml'
162
+ Any error with the libxml installation will result in Aws failing-safe to
163
+ REXML parsing.
164
+
165
+
166
+ == LICENSE:
167
+
168
+ Copyright (c) 2007-2009 RightScale, Inc.
169
+
170
+ Permission is hereby granted, free of charge, to any person obtaining
171
+ a copy of this software and associated documentation files (the
172
+ 'Software'), to deal in the Software without restriction, including
173
+ without limitation the rights to use, copy, modify, merge, publish,
174
+ distribute, sublicense, and/or sell copies of the Software, and to
175
+ permit persons to whom the Software is furnished to do so, subject to
176
+ the following conditions:
177
+
178
+ The above copyright notice and this permission notice shall be
179
+ included in all copies or substantial portions of the Software.
180
+
181
+ THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
182
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
183
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
184
+ IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
185
+ CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
186
+ TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
187
+ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
@@ -0,0 +1,413 @@
1
+ #
2
+ # Copyright (c) 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::AcfInterface -- RightScale Amazon's CloudFront interface
27
+ # The AcfInterface class provides a complete interface to Amazon's
28
+ # CloudFront service.
29
+ #
30
+ # For explanations of the semantics of each call, please refer to
31
+ # Amazon's documentation at
32
+ # http://developer.amazonwebservices.com/connect/kbcategory.jspa?categoryID=211
33
+ #
34
+ # Example:
35
+ #
36
+ # acf = Aws::AcfInterface.new('1E3GDYEOGFJPIT7XXXXXX','hgTHt68JY07JKUY08ftHYtERkjgtfERn57XXXXXX')
37
+ #
38
+ # list = acf.list_distributions #=>
39
+ # [{:status => "Deployed",
40
+ # :domain_name => "d74zzrxmpmygb.6hops.net",
41
+ # :aws_id => "E4U91HCJHGXVC",
42
+ # :origin => "my-bucket.s3.amazonaws.com",
43
+ # :cnames => ["x1.my-awesome-site.net", "x1.my-awesome-site.net"]
44
+ # :comment => "My comments",
45
+ # :last_modified_time => Wed Sep 10 17:00:04 UTC 2008 }, ..., {...} ]
46
+ #
47
+ # distibution = list.first
48
+ #
49
+ # info = acf.get_distribution(distibution[:aws_id]) #=>
50
+ # {:enabled => true,
51
+ # :caller_reference => "200809102100536497863003",
52
+ # :e_tag => "E39OHHU1ON65SI",
53
+ # :status => "Deployed",
54
+ # :domain_name => "d3dxv71tbbt6cd.6hops.net",
55
+ # :cnames => ["web1.my-awesome-site.net", "web2.my-awesome-site.net"]
56
+ # :aws_id => "E2REJM3VUN5RSI",
57
+ # :comment => "Woo-Hoo!",
58
+ # :origin => "my-bucket.s3.amazonaws.com",
59
+ # :last_modified_time => Wed Sep 10 17:00:54 UTC 2008 }
60
+ #
61
+ # config = acf.get_distribution_config(distibution[:aws_id]) #=>
62
+ # {:enabled => true,
63
+ # :caller_reference => "200809102100536497863003",
64
+ # :e_tag => "E39OHHU1ON65SI",
65
+ # :cnames => ["web1.my-awesome-site.net", "web2.my-awesome-site.net"]
66
+ # :comment => "Woo-Hoo!",
67
+ # :origin => "my-bucket.s3.amazonaws.com"}
68
+ #
69
+ # config[:comment] = 'Olah-lah!'
70
+ # config[:enabled] = false
71
+ # config[:cnames] << "web3.my-awesome-site.net"
72
+ #
73
+ # acf.set_distribution_config(distibution[:aws_id], config) #=> true
74
+ #
75
+ class AcfInterface < AwsBase
76
+
77
+ include AwsBaseInterface
78
+
79
+ API_VERSION = "2010-08-01"
80
+ DEFAULT_HOST = 'cloudfront.amazonaws.com'
81
+ DEFAULT_PORT = 443
82
+ DEFAULT_PROTOCOL = 'https'
83
+ DEFAULT_PATH = '/'
84
+
85
+ @@bench = AwsBenchmarkingBlock.new
86
+ def self.bench_xml
87
+ @@bench.xml
88
+ end
89
+ def self.bench_service
90
+ @@bench.service
91
+ end
92
+
93
+ # Create a new handle to a CloudFront account. All handles share the same per process or per thread
94
+ # HTTP connection to CloudFront. Each handle is for a specific account. The params have the
95
+ # following options:
96
+ # * <tt>:server</tt>: CloudFront service host, default: DEFAULT_HOST
97
+ # * <tt>:port</tt>: CloudFront service port, default: DEFAULT_PORT
98
+ # * <tt>:protocol</tt>: 'http' or 'https', default: DEFAULT_PROTOCOL
99
+ # * <tt>:multi_thread</tt>: true=HTTP connection per thread, false=per process
100
+ # * <tt>:logger</tt>: for log messages, default: Rails.logger else STDOUT
101
+ # * <tt>:cache</tt>: true/false: caching for list_distributions method, default: false.
102
+ #
103
+ # acf = Aws::AcfInterface.new('1E3GDYEOGFJPIT7XXXXXX','hgTHt68JY07JKUY08ftHYtERkjgtfERn57XXXXXX',
104
+ # {:multi_thread => true, :logger => Logger.new('/tmp/x.log')}) #=> #<Aws::AcfInterface::0xb7b3c30c>
105
+ #
106
+ def initialize(aws_access_key_id=nil, aws_secret_access_key=nil, params={})
107
+ init({ :name => 'ACF',
108
+ :default_host => ENV['ACF_URL'] ? URI.parse(ENV['ACF_URL']).host : DEFAULT_HOST,
109
+ :default_port => ENV['ACF_URL'] ? URI.parse(ENV['ACF_URL']).port : DEFAULT_PORT,
110
+ :default_service => ENV['ACF_URL'] ? URI.parse(ENV['ACF_URL']).path : DEFAULT_PATH,
111
+ :default_protocol => ENV['ACF_URL'] ? URI.parse(ENV['ACF_URL']).scheme : DEFAULT_PROTOCOL },
112
+ aws_access_key_id || ENV['AWS_ACCESS_KEY_ID'],
113
+ aws_secret_access_key || ENV['AWS_SECRET_ACCESS_KEY'],
114
+ params)
115
+ end
116
+
117
+ #-----------------------------------------------------------------
118
+ # Requests
119
+ #-----------------------------------------------------------------
120
+
121
+ # Generates request hash for REST API.
122
+ def generate_request(method, path, body=nil, headers={}) # :nodoc:
123
+ headers['content-type'] ||= 'text/xml' if body
124
+ headers['date'] = Time.now.httpdate
125
+ # Auth
126
+ signature = AwsUtils::sign(@aws_secret_access_key, headers['date'])
127
+ headers['Authorization'] = "AWS #{@aws_access_key_id}:#{signature}"
128
+ # Request
129
+ path = "#{@params[:default_service]}/#{API_VERSION}/#{path}"
130
+ request = "Net::HTTP::#{method.capitalize}".constantize.new(path)
131
+ request.body = body if body
132
+ # Set request headers
133
+ headers.each { |key, value| request[key.to_s] = value }
134
+ # prepare output hash
135
+ { :request => request,
136
+ :server => @params[:server],
137
+ :port => @params[:port],
138
+ :protocol => @params[:protocol] }
139
+ end
140
+
141
+ # Sends request to Amazon and parses the response.
142
+ # Raises AwsError if any banana happened.
143
+ def request_info(request, parser, &block) # :nodoc:
144
+ thread = @params[:multi_thread] ? Thread.current : Thread.main
145
+ thread[:acf_connection] ||= Rightscale::HttpConnection.new(:exception => Aws::AwsError, :logger => @logger)
146
+ request_info_impl(thread[:acf_connection], @@bench, request, parser, &block)
147
+ end
148
+
149
+ #-----------------------------------------------------------------
150
+ # Helpers:
151
+ #-----------------------------------------------------------------
152
+
153
+ def self.escape(text) # :nodoc:
154
+ REXML::Text::normalize(text)
155
+ end
156
+
157
+ def self.unescape(text) # :nodoc:
158
+ REXML::Text::unnormalize(text)
159
+ end
160
+
161
+ def xmlns # :nodoc:
162
+ %Q{"http://#{@params[:server]}/doc/#{API_VERSION}/"}
163
+ end
164
+
165
+ def generate_call_reference # :nodoc:
166
+ result = Time.now.strftime('%Y%m%d%H%M%S')
167
+ 10.times{ result << rand(10).to_s }
168
+ result
169
+ end
170
+
171
+ def merge_headers(hash) # :nodoc:
172
+ hash[:location] = @last_response['Location'] if @last_response['Location']
173
+ hash[:e_tag] = @last_response['ETag'] if @last_response['ETag']
174
+ hash
175
+ end
176
+
177
+ #-----------------------------------------------------------------
178
+ # API Calls:
179
+ #-----------------------------------------------------------------
180
+
181
+ # List distributions.
182
+ # Returns an array of distributions or Aws::AwsError exception.
183
+ #
184
+ # acf.list_distributions #=>
185
+ # [{:status => "Deployed",
186
+ # :domain_name => "d74zzrxmpmygb.6hops.net",
187
+ # :aws_id => "E4U91HCJHGXVC",
188
+ # :cnames => ["web1.my-awesome-site.net", "web2.my-awesome-site.net"]
189
+ # :origin => "my-bucket.s3.amazonaws.com",
190
+ # :comment => "My comments",
191
+ # :last_modified_time => Wed Sep 10 17:00:04 UTC 2008 }, ..., {...} ]
192
+ #
193
+ def list_distributions
194
+ request_hash = generate_request('GET', 'distribution')
195
+ request_cache_or_info :list_distributions, request_hash, AcfDistributionListParser, @@bench
196
+ end
197
+
198
+ def list_streaming_distributions
199
+ request_hash = generate_request('GET', 'streaming-distribution')
200
+ request_cache_or_info :list_streaming_distributions, request_hash, AcfStreamingDistributionListParser, @@bench
201
+ end
202
+
203
+ # Create a new distribution.
204
+ # Returns the just created distribution or Aws::AwsError exception.
205
+ #
206
+ # acf.create_distribution('bucket-for-k-dzreyev.s3.amazonaws.com', 'Woo-Hoo!', true, ['web1.my-awesome-site.net'] ) #=>
207
+ # {:comment => "Woo-Hoo!",
208
+ # :enabled => true,
209
+ # :location => "https://cloudfront.amazonaws.com/2008-06-30/distribution/E2REJM3VUN5RSI",
210
+ # :status => "InProgress",
211
+ # :aws_id => "E2REJM3VUN5RSI",
212
+ # :domain_name => "d3dxv71tbbt6cd.6hops.net",
213
+ # :origin => "my-bucket.s3.amazonaws.com",
214
+ # :cnames => ["web1.my-awesome-site.net"]
215
+ # :last_modified_time => Wed Sep 10 17:00:54 UTC 2008,
216
+ # :caller_reference => "200809102100536497863003"}
217
+ #
218
+ def create_distribution(origin, comment='', enabled=true, cnames=[], caller_reference=nil, default_root_object=nil)
219
+ body = distribution_config_for(origin, comment, enabled, cnames, caller_reference, false, default_root_object)
220
+ request_hash = generate_request('POST', 'distribution', body.strip)
221
+ merge_headers(request_info(request_hash, AcfDistributionParser.new))
222
+ end
223
+
224
+ def create_streaming_distribution(origin, comment='', enabled=true, cnames=[], caller_reference=nil, default_root_object=nil)
225
+ body = distribution_config_for(origin, comment, enabled, cnames, caller_reference, true, default_root_object)
226
+ request_hash = generate_request('POST', 'streaming-distribution', body.strip)
227
+ merge_headers(request_info(request_hash, AcfDistributionParser.new))
228
+ end
229
+
230
+ def distribution_config_for(origin, comment='', enabled=true, cnames=[], caller_reference=nil, streaming = false, default_root_object=nil)
231
+ rootElement = streaming ? "StreamingDistributionConfig" : "DistributionConfig"
232
+ # join CNAMES
233
+ cnames_str = ''
234
+ unless cnames.blank?
235
+ cnames.to_a.each { |cname| cnames_str += "\n <CNAME>#{cname}</CNAME>" }
236
+ end
237
+ caller_reference ||= generate_call_reference
238
+ root_ob = default_root_object ? "<DefaultRootObject>#{config[:default_root_object]}</DefaultRootObject>" : ""
239
+ body = <<-EOXML
240
+ <?xml version="1.0" encoding="UTF-8"?>
241
+ <#{rootElement} xmlns=#{xmlns}>
242
+ <Origin>#{origin}</Origin>
243
+ <CallerReference>#{caller_reference}</CallerReference>
244
+ #{cnames_str.lstrip}
245
+ <Comment>#{AcfInterface::escape(comment.to_s)}</Comment>
246
+ <Enabled>#{enabled}</Enabled>
247
+ #{root_ob}
248
+ </#{rootElement}>
249
+ EOXML
250
+ end
251
+
252
+ # Get a distribution's information.
253
+ # Returns a distribution's information or Aws::AwsError exception.
254
+ #
255
+ # acf.get_distribution('E2REJM3VUN5RSI') #=>
256
+ # {:enabled => true,
257
+ # :caller_reference => "200809102100536497863003",
258
+ # :e_tag => "E39OHHU1ON65SI",
259
+ # :status => "Deployed",
260
+ # :domain_name => "d3dxv71tbbt6cd.6hops.net",
261
+ # :cnames => ["web1.my-awesome-site.net", "web2.my-awesome-site.net"]
262
+ # :aws_id => "E2REJM3VUN5RSI",
263
+ # :comment => "Woo-Hoo!",
264
+ # :origin => "my-bucket.s3.amazonaws.com",
265
+ # :last_modified_time => Wed Sep 10 17:00:54 UTC 2008 }
266
+ #
267
+ def get_distribution(aws_id)
268
+ request_hash = generate_request('GET', "distribution/#{aws_id}")
269
+ merge_headers(request_info(request_hash, AcfDistributionParser.new))
270
+ end
271
+
272
+ def get_streaming_distribution(aws_id)
273
+ request_hash = generate_request('GET', "streaming-distribution/#{aws_id}")
274
+ merge_headers(request_info(request_hash, AcfDistributionParser.new))
275
+ end
276
+
277
+ # Get a distribution's configuration.
278
+ # Returns a distribution's configuration or Aws::AwsError exception.
279
+ #
280
+ # acf.get_distribution_config('E2REJM3VUN5RSI') #=>
281
+ # {:enabled => true,
282
+ # :caller_reference => "200809102100536497863003",
283
+ # :e_tag => "E39OHHU1ON65SI",
284
+ # :cnames => ["web1.my-awesome-site.net", "web2.my-awesome-site.net"]
285
+ # :comment => "Woo-Hoo!",
286
+ # :origin => "my-bucket.s3.amazonaws.com"}
287
+ #
288
+ def get_distribution_config(aws_id)
289
+ request_hash = generate_request('GET', "distribution/#{aws_id}/config")
290
+ merge_headers(request_info(request_hash, AcfDistributionConfigParser.new))
291
+ end
292
+
293
+ # Set a distribution's configuration
294
+ # (the :origin and the :caller_reference cannot be changed).
295
+ # Returns +true+ on success or Aws::AwsError exception.
296
+ #
297
+ # config = acf.get_distribution_config('E2REJM3VUN5RSI') #=>
298
+ # {:enabled => true,
299
+ # :caller_reference => "200809102100536497863003",
300
+ # :e_tag => "E39OHHU1ON65SI",
301
+ # :cnames => ["web1.my-awesome-site.net", "web2.my-awesome-site.net"]
302
+ # :comment => "Woo-Hoo!",
303
+ # :origin => "my-bucket.s3.amazonaws.com",
304
+ # :default_root_object =>
305
+ # }
306
+ # config[:comment] = 'Olah-lah!'
307
+ # config[:enabled] = false
308
+ # acf.set_distribution_config('E2REJM3VUN5RSI', config) #=> true
309
+ #
310
+ def set_distribution_config(aws_id, config)
311
+ body = distribution_config_for(config[:origin], config[:comment], config[:enabled], config[:cnames], config[:caller_reference], false)
312
+ request_hash = generate_request('PUT', "distribution/#{aws_id}/config", body.strip,
313
+ 'If-Match' => config[:e_tag])
314
+ request_info(request_hash, RightHttp2xxParser.new)
315
+ end
316
+
317
+ def set_streaming_distribution_config(aws_id, config)
318
+ body = distribution_config_for(config[:origin], config[:comment], config[:enabled], config[:cnames], config[:caller_reference], true)
319
+ request_hash = generate_request('PUT', "streaming-distribution/#{aws_id}/config", body.strip,
320
+ 'If-Match' => config[:e_tag])
321
+ request_info(request_hash, RightHttp2xxParser.new)
322
+ end
323
+
324
+ # Delete a distribution. The enabled distribution cannot be deleted.
325
+ # Returns +true+ on success or Aws::AwsError exception.
326
+ #
327
+ # acf.delete_distribution('E2REJM3VUN5RSI', 'E39OHHU1ON65SI') #=> true
328
+ #
329
+ def delete_distribution(aws_id, e_tag)
330
+ request_hash = generate_request('DELETE', "distribution/#{aws_id}", nil,
331
+ 'If-Match' => e_tag)
332
+ request_info(request_hash, RightHttp2xxParser.new)
333
+ end
334
+
335
+ def delete_streaming_distribution(aws_id, e_tag)
336
+ request_hash = generate_request('DELETE', "streaming-distribution/#{aws_id}", nil,
337
+ 'If-Match' => e_tag)
338
+ request_info(request_hash, RightHttp2xxParser.new)
339
+ end
340
+
341
+ #-----------------------------------------------------------------
342
+ # PARSERS:
343
+ #-----------------------------------------------------------------
344
+
345
+ # Parses attributes common to many CF distribution API calls
346
+ class AcfBaseDistributionParser < AwsParser # :nodoc:
347
+ def reset
348
+ @distribution = { :cnames => [] }
349
+ @result = []
350
+ end
351
+ def tagend(name)
352
+ case name
353
+ when 'Id' then @distribution[:aws_id] = @text
354
+ when 'Status' then @distribution[:status] = @text
355
+ when 'LastModifiedTime' then @distribution[:last_modified_time] = Time.parse(@text)
356
+ when 'DomainName' then @distribution[:domain_name] = @text
357
+ when 'Origin' then @distribution[:origin] = @text
358
+ when 'CallerReference' then @distribution[:caller_reference] = @text
359
+ when 'Comment' then @distribution[:comment] = AcfInterface::unescape(@text)
360
+ when 'Enabled' then @distribution[:enabled] = @text == 'true' ? true : false
361
+ when 'CNAME' then @distribution[:cnames] << @text
362
+ end
363
+ end
364
+ end
365
+
366
+ class AcfDistributionParser < AcfBaseDistributionParser # :nodoc:
367
+ def tagend(name)
368
+ super
369
+ @result = @distribution
370
+ end
371
+ end
372
+
373
+ class AcfDistributionListParser < AcfBaseDistributionParser # :nodoc:
374
+ def tagstart(name, attributes)
375
+ @distribution = { :cnames => [] } if name == 'DistributionSummary'
376
+ end
377
+ def tagend(name)
378
+ super(name)
379
+ case name
380
+ when 'DistributionSummary' then @result << @distribution
381
+ end
382
+ end
383
+ end
384
+
385
+ class AcfDistributionConfigParser < AwsParser # :nodoc:
386
+ def reset
387
+ @result = { :cnames => [] }
388
+ end
389
+ def tagend(name)
390
+ case name
391
+ when 'Origin' then @result[:origin] = @text
392
+ when 'CallerReference' then @result[:caller_reference] = @text
393
+ when 'Comment' then @result[:comment] = AcfInterface::unescape(@text)
394
+ when 'Enabled' then @result[:enabled] = @text == 'true' ? true : false
395
+ when 'CNAME' then @result[:cnames] << @text
396
+ end
397
+ end
398
+ end
399
+
400
+ class AcfStreamingDistributionListParser < AcfBaseDistributionParser # :nodoc:
401
+ def tagstart(name, attributes)
402
+ @distribution = { :cnames => [] } if name == 'StreamingDistributionSummary'
403
+ end
404
+ def tagend(name)
405
+ super(name)
406
+ case name
407
+ when 'StreamingDistributionSummary' then @result << @distribution
408
+ end
409
+ end
410
+ end
411
+
412
+ end
413
+ end