talaris-right_aws 2.1.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (66) hide show
  1. data/History.txt +305 -0
  2. data/Manifest.txt +60 -0
  3. data/README.txt +163 -0
  4. data/Rakefile +104 -0
  5. data/lib/acf/right_acf_interface.rb +549 -0
  6. data/lib/acf/right_acf_invalidations.rb +144 -0
  7. data/lib/acf/right_acf_origin_access_identities.rb +230 -0
  8. data/lib/acf/right_acf_streaming_interface.rb +229 -0
  9. data/lib/acw/right_acw_interface.rb +248 -0
  10. data/lib/as/right_as_interface.rb +698 -0
  11. data/lib/awsbase/benchmark_fix.rb +39 -0
  12. data/lib/awsbase/right_awsbase.rb +1174 -0
  13. data/lib/awsbase/support.rb +35 -0
  14. data/lib/awsbase/version.rb +9 -0
  15. data/lib/ec2/right_ec2.rb +458 -0
  16. data/lib/ec2/right_ec2_ebs.rb +465 -0
  17. data/lib/ec2/right_ec2_images.rb +413 -0
  18. data/lib/ec2/right_ec2_instances.rb +785 -0
  19. data/lib/ec2/right_ec2_monitoring.rb +70 -0
  20. data/lib/ec2/right_ec2_placement_groups.rb +108 -0
  21. data/lib/ec2/right_ec2_reserved_instances.rb +174 -0
  22. data/lib/ec2/right_ec2_security_groups.rb +396 -0
  23. data/lib/ec2/right_ec2_spot_instances.rb +425 -0
  24. data/lib/ec2/right_ec2_tags.rb +139 -0
  25. data/lib/ec2/right_ec2_vpc.rb +583 -0
  26. data/lib/ec2/right_ec2_windows_mobility.rb +84 -0
  27. data/lib/elb/right_elb_interface.rb +571 -0
  28. data/lib/iam/right_iam_access_keys.rb +71 -0
  29. data/lib/iam/right_iam_groups.rb +195 -0
  30. data/lib/iam/right_iam_interface.rb +341 -0
  31. data/lib/iam/right_iam_mfa_devices.rb +67 -0
  32. data/lib/iam/right_iam_users.rb +251 -0
  33. data/lib/rds/right_rds_interface.rb +1309 -0
  34. data/lib/right_aws.rb +83 -0
  35. data/lib/route_53/right_route_53_interface.rb +630 -0
  36. data/lib/s3/right_s3.rb +1123 -0
  37. data/lib/s3/right_s3_interface.rb +1198 -0
  38. data/lib/sdb/active_sdb.rb +1107 -0
  39. data/lib/sdb/right_sdb_interface.rb +753 -0
  40. data/lib/sqs/right_sqs.rb +387 -0
  41. data/lib/sqs/right_sqs_gen2.rb +342 -0
  42. data/lib/sqs/right_sqs_gen2_interface.rb +523 -0
  43. data/lib/sqs/right_sqs_interface.rb +593 -0
  44. data/right_aws.gemspec +91 -0
  45. data/test/acf/test_helper.rb +2 -0
  46. data/test/acf/test_right_acf.rb +138 -0
  47. data/test/awsbase/test_helper.rb +2 -0
  48. data/test/awsbase/test_right_awsbase.rb +12 -0
  49. data/test/ec2/test_helper.rb +2 -0
  50. data/test/ec2/test_right_ec2.rb +108 -0
  51. data/test/http_connection.rb +87 -0
  52. data/test/rds/test_helper.rb +2 -0
  53. data/test/rds/test_right_rds.rb +120 -0
  54. data/test/s3/test_helper.rb +2 -0
  55. data/test/s3/test_right_s3.rb +421 -0
  56. data/test/s3/test_right_s3_stubbed.rb +97 -0
  57. data/test/sdb/test_active_sdb.rb +357 -0
  58. data/test/sdb/test_batch_put_attributes.rb +54 -0
  59. data/test/sdb/test_helper.rb +3 -0
  60. data/test/sdb/test_right_sdb.rb +253 -0
  61. data/test/sqs/test_helper.rb +2 -0
  62. data/test/sqs/test_right_sqs.rb +285 -0
  63. data/test/sqs/test_right_sqs_gen2.rb +264 -0
  64. data/test/test_credentials.rb +37 -0
  65. data/test/ts_right_aws.rb +14 -0
  66. metadata +214 -0
@@ -0,0 +1,104 @@
1
+ # -*- ruby -*-
2
+
3
+ require 'rubygems'
4
+ require "rake/testtask"
5
+ # require 'rcov/rcovtask'
6
+ require 'rake/gempackagetask'
7
+ require 'rake/clean'
8
+ $: << File.dirname(__FILE__)
9
+ testglobs = ["test/ts_right_aws.rb"]
10
+
11
+ begin
12
+ require 'bundler'
13
+ rescue LoadError => e
14
+ STDERR.puts("Bundler is not available, some rake tasks will not be defined: #{e.message}")
15
+ else
16
+ Bundler::GemHelper.install_tasks
17
+ end
18
+
19
+ # == Gem == #
20
+
21
+ gemtask = Rake::GemPackageTask.new(Gem::Specification.load("right_aws.gemspec")) do |package|
22
+ package.package_dir = ENV['PACKAGE_DIR'] || 'pkg'
23
+ package.need_zip = true
24
+ package.need_tar = true
25
+ end
26
+
27
+ directory gemtask.package_dir
28
+
29
+ CLEAN.include(gemtask.package_dir)
30
+
31
+ # desc "Analyze code coverage of the unit tests."
32
+ # Rcov::RcovTask.new do |t|
33
+ # t.test_files = FileList[testglobs]
34
+ # #t.verbose = true # uncomment to see the executed command
35
+ # end
36
+
37
+ desc "Test just the SQS interface"
38
+ task :testsqs do
39
+ require 'test/test_credentials'
40
+ require 'test/http_connection'
41
+ TestCredentials.get_credentials
42
+ require 'test/sqs/test_right_sqs.rb'
43
+ end
44
+
45
+ desc "Test just the second generation SQS interface"
46
+ task :testsqs2 do
47
+ require 'test/test_credentials'
48
+ require 'test/http_connection'
49
+ TestCredentials.get_credentials
50
+ require 'test/sqs/test_right_sqs_gen2.rb'
51
+ end
52
+
53
+ desc "Test just the S3 interface"
54
+ task :tests3 do
55
+ require 'test/test_credentials'
56
+ require 'test/http_connection'
57
+ TestCredentials.get_credentials
58
+ require 'test/s3/test_right_s3.rb'
59
+ end
60
+
61
+ desc "Test just the S3 interface using local stubs"
62
+ task :tests3local do
63
+ require 'test/test_credentials'
64
+ require 'test/http_connection'
65
+ TestCredentials.get_credentials
66
+ require 'test/s3/test_right_s3_stubbed.rb'
67
+ end
68
+
69
+ desc "Test just the EC2 interface"
70
+ task :testec2 do
71
+ require 'test/test_credentials'
72
+ TestCredentials.get_credentials
73
+ require 'test/ec2/test_right_ec2.rb'
74
+ end
75
+
76
+ desc "Test just the SDB interface"
77
+ task :testsdb do
78
+ require 'test/test_credentials'
79
+ TestCredentials.get_credentials
80
+ require 'test/sdb/test_right_sdb.rb'
81
+ end
82
+
83
+ desc "Test active SDB interface"
84
+ task :testactivesdb do
85
+ require 'test/test_credentials'
86
+ TestCredentials.get_credentials
87
+ require 'test/sdb/test_active_sdb.rb'
88
+ end
89
+
90
+ desc "Test CloudFront interface"
91
+ task :testacf do
92
+ require 'test/test_credentials'
93
+ TestCredentials.get_credentials
94
+ require 'test/acf/test_right_acf.rb'
95
+ end
96
+
97
+ desc "Test RDS interface"
98
+ task :testrds do
99
+ require 'test/test_credentials'
100
+ TestCredentials.get_credentials
101
+ require 'test/rds/test_right_rds.rb'
102
+ end
103
+
104
+ # vim: syntax=Ruby
@@ -0,0 +1,549 @@
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
+ module RightAws
24
+
25
+ # = RightAws::AcfInterface -- RightScale Amazon's CloudFront interface
26
+ # The AcfInterface class provides a complete interface to Amazon's
27
+ # CloudFront service.
28
+ #
29
+ # For explanations of the semantics of each call, please refer to
30
+ # Amazon's documentation at
31
+ # http://developer.amazonwebservices.com/connect/kbcategory.jspa?categoryID=211
32
+ #
33
+ # Example:
34
+ #
35
+ # acf = RightAws::AcfInterface.new('1E3GDYEOGFJPIT7XXXXXX','hgTHt68JY07JKUY08ftHYtERkjgtfERn57XXXXXX')
36
+ #
37
+ # list = acf.list_distributions #=>
38
+ # [{:status => "Deployed",
39
+ # :domain_name => "d74zzrxmpmygb.6hops.net",
40
+ # :aws_id => "E4U91HCJHGXVC",
41
+ # :s3_origin => {:dns_name=>"bucket-for-konstantin-00.s3.amazonaws.com"},
42
+ # :cnames => ["x1.my-awesome-site.net", "x1.my-awesome-site.net"]
43
+ # :comment => "My comments",
44
+ # :last_modified_time => "2008-09-10T17:00:04.000Z" }, ..., {...} ]
45
+ #
46
+ # distibution = list.first
47
+ #
48
+ # info = acf.get_distribution(distibution[:aws_id]) #=>
49
+ # {:last_modified_time=>"2010-05-19T18:54:38.242Z",
50
+ # :status=>"Deployed",
51
+ # :domain_name=>"dpzl38cuix402.cloudfront.net",
52
+ # :caller_reference=>"201005181943052207677116",
53
+ # :e_tag=>"EJSXFGM5JL8ER",
54
+ # :s3_origin=>
55
+ # {:dns_name=>"bucket-for-konstantin-eu.s3.amazonaws.com",
56
+ # :origin_access_identity=>
57
+ # "origin-access-identity/cloudfront/E3JPJZ80ZBX24G"},
58
+ # :aws_id=>"E5P8HQ3ZAZIXD",
59
+ # :enabled=>false}
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
+ # :s3_origin => {:dns_name => "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 < RightAwsBase
76
+
77
+ include RightAwsBaseInterface
78
+
79
+ API_VERSION = "2010-11-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>:endpoint_url</tt> a fully qualified url to Amazon API endpoint (this overwrites: :server, :port, :service, :protocol). Example: 'https://cloudfront.amazonaws.com'
97
+ # * <tt>:server</tt>: CloudFront service host, default: DEFAULT_HOST
98
+ # * <tt>:port</tt>: CloudFront service port, default: DEFAULT_PORT
99
+ # * <tt>:protocol</tt>: 'http' or 'https', default: DEFAULT_PROTOCOL
100
+ # * <tt>:logger</tt>: for log messages, default: RAILS_DEFAULT_LOGGER else STDOUT
101
+ #
102
+ # acf = RightAws::AcfInterface.new('1E3GDYEOGFJPIT7XXXXXX','hgTHt68JY07JKUY08ftHYtERkjgtfERn57XXXXXX',
103
+ # {:logger => Logger.new('/tmp/x.log')}) #=> #<RightAws::AcfInterface::0xb7b3c30c>
104
+ #
105
+ def initialize(aws_access_key_id=nil, aws_secret_access_key=nil, params={})
106
+ init({ :name => 'ACF',
107
+ :default_host => ENV['ACF_URL'] ? URI.parse(ENV['ACF_URL']).host : DEFAULT_HOST,
108
+ :default_port => ENV['ACF_URL'] ? URI.parse(ENV['ACF_URL']).port : DEFAULT_PORT,
109
+ :default_service => ENV['ACF_URL'] ? URI.parse(ENV['ACF_URL']).path : DEFAULT_PATH,
110
+ :default_protocol => ENV['ACF_URL'] ? URI.parse(ENV['ACF_URL']).scheme : DEFAULT_PROTOCOL,
111
+ :default_api_version => ENV['ACF_API_VERSION'] || API_VERSION },
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, params={}, body=nil, headers={}) # :nodoc:
123
+ # Params
124
+ params.delete_if{ |key, val| val.right_blank? }
125
+ unless params.right_blank?
126
+ path += "?" + params.to_a.collect{ |key,val| "#{AwsUtils::amz_escape(key)}=#{AwsUtils::amz_escape(val.to_s)}" }.join("&")
127
+ end
128
+ # Headers
129
+ headers['content-type'] ||= 'text/xml' if body
130
+ headers['date'] = Time.now.httpdate
131
+ # Auth
132
+ signature = AwsUtils::sign(@aws_secret_access_key, headers['date'])
133
+ headers['Authorization'] = "AWS #{@aws_access_key_id}:#{signature}"
134
+ # Request
135
+ path = "#{@params[:service]}#{@params[:api_version]}/#{path}"
136
+ request = "Net::HTTP::#{method.capitalize}".right_constantize.new(path)
137
+ request.body = body if body
138
+ # Set request headers
139
+ headers.each { |key, value| request[key.to_s] = value }
140
+ # prepare output hash
141
+ { :request => request,
142
+ :server => @params[:server],
143
+ :port => @params[:port],
144
+ :protocol => @params[:protocol] }
145
+ end
146
+
147
+ # Sends request to Amazon and parses the response.
148
+ # Raises AwsError if any banana happened.
149
+ def request_info(request, parser, &block) # :nodoc:
150
+ request_info_impl(:acf_connection, @@bench, request, parser, &block)
151
+ end
152
+
153
+ #-----------------------------------------------------------------
154
+ # Helpers:
155
+ #-----------------------------------------------------------------
156
+
157
+ def generate_call_reference # :nodoc:
158
+ result = Time.now.strftime('%Y%m%d%H%M%S')
159
+ 10.times{ result << rand(10).to_s }
160
+ result
161
+ end
162
+
163
+ def merge_headers(hash) # :nodoc:
164
+ hash[:location] = @last_response['Location'] if @last_response['Location']
165
+ hash[:e_tag] = @last_response['ETag'] if @last_response['ETag']
166
+ hash
167
+ end
168
+
169
+ def distribution_config_to_xml(config, xml_wrapper='DistributionConfig') # :nodoc:
170
+ cnames = logging = trusted_signers = s3_origin = custom_origin = default_root_object = ''
171
+ # CNAMES
172
+ unless config[:cnames].right_blank?
173
+ Array(config[:cnames]).each { |cname| cnames += " <CNAME>#{cname}</CNAME>\n" }
174
+ end
175
+ # Logging
176
+ unless config[:logging].right_blank?
177
+ logging = " <Logging>\n" +
178
+ " <Bucket>#{config[:logging][:bucket]}</Bucket>\n" +
179
+ " <Prefix>#{config[:logging][:prefix]}</Prefix>\n" +
180
+ " </Logging>\n"
181
+ end
182
+ unless config[:required_protocols].right_blank?
183
+ required_protocols = " <RequiredProtocols>\n" +
184
+ " <Protocol>#{config[:required_protocols]}</Protocol>\n" +
185
+ " </RequiredProtocols>\n"
186
+ else required_protocols = ""
187
+ end
188
+ # Default Root Object
189
+ unless config[:default_root_object].right_blank?
190
+ default_root_object = " <DefaultRootObject>#{config[:default_root_object]}</DefaultRootObject>\n" unless config[:default_root_object].right_blank?
191
+ end
192
+ # Trusted Signers
193
+ unless config[:trusted_signers].right_blank?
194
+ trusted_signers = " <TrustedSigners>\n"
195
+ Array(config[:trusted_signers]).each do |trusted_signer|
196
+ trusted_signers += if trusted_signer.to_s[/self/i]
197
+ " <Self/>\n"
198
+ else
199
+ " <AwsAccountNumber>#{trusted_signer}</AwsAccountNumber>\n"
200
+ end
201
+ end
202
+ trusted_signers += " </TrustedSigners>\n"
203
+ end
204
+ # S3Origin
205
+ unless config[:s3_origin].right_blank?
206
+ origin_access_identity = ''
207
+ # Origin Access Identity
208
+ unless config[:s3_origin][:origin_access_identity].right_blank?
209
+ origin_access_identity = config[:s3_origin][:origin_access_identity]
210
+ unless origin_access_identity[%r{^origin-access-identity}]
211
+ origin_access_identity = "origin-access-identity/cloudfront/#{origin_access_identity}"
212
+ end
213
+ origin_access_identity = " <OriginAccessIdentity>#{origin_access_identity}</OriginAccessIdentity>\n"
214
+ end
215
+ s3_origin = " <S3Origin>\n" +
216
+ " <DNSName>#{config[:s3_origin][:dns_name]}</DNSName>\n" +
217
+ "#{origin_access_identity}" +
218
+ " </S3Origin>\n"
219
+ end
220
+ # Custom Origin
221
+ unless config[:custom_origin].right_blank?
222
+ http_port = https_port = origin_protocol_policy = ''
223
+ http_port = " <HTTPPort>#{config[:custom_origin][:http_port]}</HTTPPort>\n" unless config[:custom_origin][:http_port].right_blank?
224
+ https_port = " <HTTPSPort>#{config[:custom_origin][:https_port]}</HTTPSPort>" unless config[:custom_origin][:https_port].right_blank?
225
+ origin_protocol_policy = " <OriginProtocolPolicy>#{config[:custom_origin][:origin_protocol_policy]}</OriginProtocolPolicy>\n" unless config[:custom_origin][:origin_protocol_policy].right_blank?
226
+ custom_origin = " <CustomOrigin>\n" +
227
+ " <DNSName>#{config[:custom_origin][:dns_name]}</DNSName>\n" +
228
+ "#{http_port}" +
229
+ "#{https_port}" +
230
+ "#{origin_protocol_policy}" +
231
+ " </CustomOrigin>\n"
232
+ end
233
+ # XML
234
+ "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n" +
235
+ "<#{xml_wrapper} xmlns=\"http://#{@params[:server]}/doc/#{API_VERSION}/\">\n" +
236
+ " <CallerReference>#{config[:caller_reference]}</CallerReference>\n" +
237
+ " <Comment>#{AwsUtils::xml_escape(config[:comment].to_s)}</Comment>\n" +
238
+ " <Enabled>#{config[:enabled]}</Enabled>\n" +
239
+ s3_origin +
240
+ custom_origin +
241
+ default_root_object +
242
+ cnames +
243
+ logging +
244
+ required_protocols +
245
+ trusted_signers +
246
+ "</#{xml_wrapper}>"
247
+ end
248
+
249
+ #-----------------------------------------------------------------
250
+ # API Calls:
251
+ #-----------------------------------------------------------------
252
+
253
+ # List all distributions.
254
+ # Returns an array of distributions or RightAws::AwsError exception.
255
+ #
256
+ # acf.list_distributions #=>
257
+ # [{:status=>"Deployed",
258
+ # :domain_name=>"dgmde.6os.net",
259
+ # :comment=>"ONE LINE OF COMMENT",
260
+ # :last_modified_time=>"2009-06-16T16:10:02.210Z",
261
+ # :s3_origin=>{:dns_name=>"example.s3.amazonaws.com"},
262
+ # :aws_id=>"12Q05OOMFN7SYL",
263
+ # :enabled=>true}, ... ]
264
+ #
265
+ def list_distributions
266
+ result = []
267
+ incrementally_list_distributions do |response|
268
+ result += response[:distributions]
269
+ true
270
+ end
271
+ result
272
+ end
273
+
274
+ # Incrementally list distributions.
275
+ #
276
+ # Optional params: +:marker+ and +:max_items+.
277
+ #
278
+ # # get first distribution
279
+ # incrementally_list_distributions(:max_items => 1) #=>
280
+ # {:distributions=>
281
+ # [{:status=>"Deployed",
282
+ # :aws_id=>"E2Q0AOOMFNPSYL",
283
+ # :s3_origin=>{:dns_name=>"example.s3.amazonaws.com"},
284
+ # :domain_name=>"d1s5gmdtmafnre.6hops.net",
285
+ # :comment=>"ONE LINE OF COMMENT",
286
+ # :last_modified_time=>"2008-10-22T19:31:23.000Z",
287
+ # :enabled=>true,
288
+ # :cnames=>[]}],
289
+ # :is_truncated=>true,
290
+ # :max_items=>1,
291
+ # :marker=>"",
292
+ # :next_marker=>"E2Q0AOOMFNPSYL"}
293
+ #
294
+ # # get max 100 distributions (the list will be restricted by a default MaxItems value ==100 )
295
+ # incrementally_list_distributions
296
+ #
297
+ # # list distributions by 10
298
+ # incrementally_list_distributions(:max_items => 10) do |response|
299
+ # puts response.inspect # a list of 10 distributions
300
+ # true # return false if the listing should be broken otherwise use true
301
+ # end
302
+ #
303
+ def incrementally_list_distributions(params={}, &block)
304
+ opts = {}
305
+ opts['MaxItems'] = params[:max_items] if params[:max_items]
306
+ opts['Marker'] = params[:marker] if params[:marker]
307
+ last_response = nil
308
+ loop do
309
+ link = generate_request('GET', 'distribution', opts)
310
+ last_response = request_info(link, AcfDistributionListParser.new(:logger => @logger))
311
+ opts['Marker'] = last_response[:next_marker]
312
+ break unless block && block.call(last_response) && !last_response[:next_marker].right_blank?
313
+ end
314
+ last_response
315
+ end
316
+
317
+ # Create a new distribution.
318
+ # Returns the just created distribution or RightAws::AwsError exception.
319
+ #
320
+ # # S3 Origin
321
+ #
322
+ # config = { :comment => "kd: delete me please",
323
+ # :s3_origin => { :dns_name => "devs-us-east.s3.amazonaws.com",
324
+ # :origin_access_identity => "origin-access-identity/cloudfront/E3JPJZ80ZBX24G"},
325
+ # :enabled => true,
326
+ # :logging => { :prefix => "kd/log/",
327
+ # :bucket => "devs-us-west.s3.amazonaws.com"}}
328
+ # acf.create_distribution(config) #=>
329
+ # { :status=>"InProgress",
330
+ # :enabled=>true,
331
+ # :caller_reference=>"201012071910051044304704",
332
+ # :logging=>{:prefix=>"kd/log/", :bucket=>"devs-us-west.s3.amazonaws.com"},
333
+ # :e_tag=>"ESCTG5WJCFWJK",
334
+ # :location=> "https://cloudfront.amazonaws.com/2010-11-01/distribution/E3KUBANZ7N1B2",
335
+ # :comment=>"kd: delete me please",
336
+ # :domain_name=>"d3stykk6upgs20.cloudfront.net",
337
+ # :aws_id=>"E3KUBANZ7N1B2",
338
+ # :s3_origin=>
339
+ # {:origin_access_identity=>"origin-access-identity/cloudfront/E3JPJZ80ZBX24G",
340
+ # :dns_name=>"devs-us-east.s3.amazonaws.com"},
341
+ # :last_modified_time=>"2010-12-07T16:10:07.087Z",
342
+ # :in_progress_invalidation_batches=>0}
343
+ #
344
+ # # Custom Origin
345
+ #
346
+ # custom_config = { :comment => "kd: delete me please",
347
+ # :custom_origin => { :dns_name => "custom_origin.my-site.com",
348
+ # :http_port => 80,
349
+ # :https_port => 443,
350
+ # :origin_protocol_policy => 'match-viewer' },
351
+ # :enabled => true,
352
+ # :logging => { :prefix => "kd/log/",
353
+ # :bucket => "my-bucket.s3.amazonaws.com"}} #=>
354
+ # { :last_modified_time=>"2010-12-08T14:23:43.522Z",
355
+ # :status=>"InProgress",
356
+ # :custom_origin=>
357
+ # {:http_port=>"80",
358
+ # :https_port=>"443",
359
+ # :origin_protocol_policy=>"match-viewer",
360
+ # :dns_name=>"custom_origin.my-site.com"},
361
+ # :enabled=>true,
362
+ # :caller_reference=>"201012081723428499167245",
363
+ # :in_progress_invalidation_batches=>0,
364
+ # :e_tag=>"E1ZCJ8N5E52KO6",
365
+ # :location=>
366
+ # "https://cloudfront.amazonaws.com/2010-11-01/distribution/EK0AJ4RMNIF2P",
367
+ # :logging=>{:prefix=>"kd/log/", :bucket=>"my-bucket.s3.amazonaws.com"},
368
+ # :domain_name=>"do36k7s2wxklg.cloudfront.net",
369
+ # :comment=>"kd: delete me please",
370
+ # :aws_id=>"EK0AJ4RMNIF2P"}
371
+ #
372
+ def create_distribution(config)
373
+ config[:caller_reference] ||= generate_call_reference
374
+ link = generate_request('POST', 'distribution', {}, distribution_config_to_xml(config))
375
+ merge_headers(request_info(link, AcfDistributionListParser.new(:logger => @logger))[:distributions].first)
376
+ end
377
+ alias_method :create_distribution_by_config, :create_distribution
378
+
379
+ # Get a distribution's information.
380
+ # Returns a distribution's information or RightAws::AwsError exception.
381
+ #
382
+ # acf.get_distribution('E2REJM3VUN5RSI') #=>
383
+ # {:last_modified_time=>"2010-05-19T18:54:38.242Z",
384
+ # :status=>"Deployed",
385
+ # :domain_name=>"dpzl38cuix402.cloudfront.net",
386
+ # :caller_reference=>"201005181943052207677116",
387
+ # :e_tag=>"EJSXFGM5JL8ER",
388
+ # :s3_origin=>
389
+ # {:dns_name=>"bucket-for-konstantin-eu.s3.amazonaws.com",
390
+ # :origin_access_identity=>
391
+ # "origin-access-identity/cloudfront/E3JPJZ80ZBX24G"},
392
+ # :aws_id=>"E5P8HQ3ZAZIXD",
393
+ # :enabled=>false}
394
+ #
395
+ # acf.get_distribution('E2FNSBHNVVF11E') #=>
396
+ # {:e_tag=>"E1Q2DJEPTQOLJD",
397
+ # :status=>"InProgress",
398
+ # :last_modified_time=>"2010-04-17T17:24:25.000Z",
399
+ # :cnames=>["web1.my-awesome-site.net", "web2.my-awesome-site.net"],
400
+ # :aws_id=>"E2FNSBHNVVF11E",
401
+ # :logging=>{:prefix=>"xlog/", :bucket=>"my-bucket.s3.amazonaws.com"},
402
+ # :enabled=>true,
403
+ # :active_trusted_signers=>
404
+ # [{:aws_account_number=>"120288270000",
405
+ # :key_pair_ids=>["APKAJTD5OHNDX0000000", "APKAIK74BJWCL0000000"]},
406
+ # {:aws_account_number=>"self"},
407
+ # {:aws_account_number=>"648772220000"}],
408
+ # :caller_reference=>"201004171154450740700072",
409
+ # :domain_name=>"d1f6lpevremt5m.cloudfront.net",
410
+ # :s3_origin=>
411
+ # {:dns_name=>"bucket-for-konstantin-eu.s3.amazonaws.com",
412
+ # :origin_access_identity=>
413
+ # "origin-access-identity/cloudfront/E3JPJZ80ZBX24G"},
414
+ # :trusted_signers=>["self", "648772220000", "120288270000"]}
415
+ #
416
+ def get_distribution(aws_id)
417
+ link = generate_request('GET', "distribution/#{aws_id}")
418
+ merge_headers(request_info(link, AcfDistributionListParser.new(:logger => @logger))[:distributions].first)
419
+ end
420
+
421
+ # Get a distribution's configuration.
422
+ # Returns a distribution's configuration or RightAws::AwsError exception.
423
+ #
424
+ # acf.get_distribution_config('E2REJM3VUN5RSI') #=>
425
+ # {:caller_reference=>"201005181943052207677116",
426
+ # :e_tag=>"EJSXFGM5JL8ER",
427
+ # :s3_origin=>
428
+ # {:dns_name=>"bucket-for-konstantin-eu.s3.amazonaws.com",
429
+ # :origin_access_identity=>
430
+ # "origin-access-identity/cloudfront/E3JPJZ80ZBX24G"},
431
+ # :enabled=>false}
432
+ #
433
+ # acf.get_distribution_config('E2FNSBHNVVF11E') #=>
434
+ # {:e_tag=>"E1Q2DJEPTQOLJD",
435
+ # :logging=>{:prefix=>"xlog/", :bucket=>"my-bucket.s3.amazonaws.com"},
436
+ # :enabled=>true,
437
+ # :caller_reference=>"201004171154450740700072",
438
+ # :trusted_signers=>["self", "648772220000", "120288270000"],
439
+ # :s3_origin=>
440
+ # {:dns_name=>"bucket-for-konstantin-eu.s3.amazonaws.com",
441
+ # :origin_access_identity=>
442
+ # "origin-access-identity/cloudfront/E3JPJZ80ZBX24G"}}
443
+ #
444
+ def get_distribution_config(aws_id)
445
+ link = generate_request('GET', "distribution/#{aws_id}/config")
446
+ merge_headers(request_info(link, AcfDistributionListParser.new(:logger => @logger))[:distributions].first)
447
+ end
448
+
449
+ # Set a distribution's configuration
450
+ # Returns +true+ on success or RightAws::AwsError exception.
451
+ #
452
+ # config = acf.get_distribution_config('E2REJM3VUN5RSI') #=>
453
+ # {:enabled => true,
454
+ # :caller_reference => "200809102100536497863003",
455
+ # :e_tag => "E39OHHU1ON65SI",
456
+ # :cnames => ["web1.my-awesome-site.net", "web2.my-awesome-site.net"]
457
+ # :comment => "Woo-Hoo!",
458
+ # :s3_origin => { :dns_name => "my-bucket.s3.amazonaws.com"}}
459
+ #
460
+ # config[:comment] = 'Olah-lah!'
461
+ # config[:enabled] = false
462
+ # config[:s3_origin][:origin_access_identity] = "origin-access-identity/cloudfront/E3JPJZ80ZBX24G"
463
+ # # or just
464
+ # # config[:s3_origin][:origin_access_identity] = "E3JPJZ80ZBX24G"
465
+ # config[:trusted_signers] = ['self', '648772220000', '120288270000']
466
+ # config[:logging] = { :bucket => 'my-bucket.s3.amazonaws.com', :prefix => 'xlog/' }
467
+ #
468
+ # acf.set_distribution_config('E2REJM3VUN5RSI', config) #=> true
469
+ #
470
+ def set_distribution_config(aws_id, config)
471
+ link = generate_request('PUT', "distribution/#{aws_id}/config", {}, distribution_config_to_xml(config),
472
+ 'If-Match' => config[:e_tag])
473
+ request_info(link, RightHttp2xxParser.new(:logger => @logger))
474
+ end
475
+
476
+ # Delete a distribution. The enabled distribution cannot be deleted.
477
+ # Returns +true+ on success or RightAws::AwsError exception.
478
+ #
479
+ # acf.delete_distribution('E2REJM3VUN5RSI', 'E39OHHU1ON65SI') #=> true
480
+ #
481
+ def delete_distribution(aws_id, e_tag)
482
+ link = generate_request('DELETE', "distribution/#{aws_id}", {}, nil,
483
+ 'If-Match' => e_tag)
484
+ request_info(link, RightHttp2xxParser.new(:logger => @logger))
485
+ end
486
+
487
+ #-----------------------------------------------------------------
488
+ # PARSERS:
489
+ #-----------------------------------------------------------------
490
+
491
+ class AcfDistributionListParser < RightAWSParser # :nodoc:
492
+ def reset
493
+ @result = { :distributions => [] }
494
+ end
495
+ def tagstart(name, attributes)
496
+ case full_tag_name
497
+ when %r{/Signer$}
498
+ @active_signer = {}
499
+ when %r{(Streaming)?DistributionSummary$},
500
+ %r{^(Streaming)?Distribution$},
501
+ %r{^(Streaming)?DistributionConfig$}
502
+ @distribution = { }
503
+ when %r{/S3Origin$} then @distribution[:s3_origin] = {}
504
+ when %r{/CustomOrigin$} then @distribution[:custom_origin] = {}
505
+ end
506
+ end
507
+ def tagend(name)
508
+ case name
509
+ when 'Marker' then @result[:marker] = @text
510
+ when 'NextMarker' then @result[:next_marker] = @text
511
+ when 'MaxItems' then @result[:max_items] = @text.to_i
512
+ when 'IsTruncated' then @result[:is_truncated] = (@text == 'true')
513
+ when 'Id' then @distribution[:aws_id] = @text
514
+ when 'Status' then @distribution[:status] = @text
515
+ when 'LastModifiedTime' then @distribution[:last_modified_time] = @text
516
+ when 'DomainName' then @distribution[:domain_name] = @text
517
+ when 'Comment' then @distribution[:comment] = AwsUtils::xml_unescape(@text)
518
+ when 'CallerReference' then @distribution[:caller_reference] = @text
519
+ when 'CNAME' then (@distribution[:cnames] ||= []) << @text
520
+ when 'Enabled' then @distribution[:enabled] = (@text == 'true')
521
+ when 'Bucket' then (@distribution[:logging] ||= {})[:bucket] = @text
522
+ when 'Prefix' then (@distribution[:logging] ||= {})[:prefix] = @text
523
+ when 'Protocol' then (@distribution[:required_protocols] ||= {})[:protocol] = @text
524
+ when 'InProgressInvalidationBatches' then @distribution[:in_progress_invalidation_batches] = @text.to_i
525
+ when 'DefaultRootObject' then @distribution[:default_root_object] = @text
526
+ else
527
+ case full_tag_name
528
+ when %r{/S3Origin/DNSName$} then @distribution[:s3_origin][:dns_name] = @text
529
+ when %r{/S3Origin/OriginAccessIdentity$} then @distribution[:s3_origin][:origin_access_identity] = @text
530
+ when %r{/CustomOrigin/DNSName$} then @distribution[:custom_origin][:dns_name] = @text
531
+ when %r{/CustomOrigin/HTTPPort} then @distribution[:custom_origin][:http_port] = @text
532
+ when %r{/CustomOrigin/HTTPSPort$} then @distribution[:custom_origin][:https_port] = @text
533
+ when %r{/CustomOrigin/OriginProtocolPolicy$} then @distribution[:custom_origin][:origin_protocol_policy] = @text
534
+ when %r{/TrustedSigners/Self$} then (@distribution[:trusted_signers] ||= []) << 'self'
535
+ when %r{/TrustedSigners/AwsAccountNumber$} then (@distribution[:trusted_signers] ||= []) << @text
536
+ when %r{/Signer/Self$} then @active_signer[:aws_account_number] = 'self'
537
+ when %r{/Signer/AwsAccountNumber$} then @active_signer[:aws_account_number] = @text
538
+ when %r{/Signer/KeyPairId$} then (@active_signer[:key_pair_ids] ||= []) << @text
539
+ when %r{/Signer$} then (@distribution[:active_trusted_signers] ||= []) << @active_signer
540
+ when %r{(Streaming)?DistributionSummary$},
541
+ %r{^(Streaming)?Distribution$},
542
+ %r{^(Streaming)?DistributionConfig$}
543
+ @result[:distributions] << @distribution
544
+ end
545
+ end
546
+ end
547
+ end
548
+ end
549
+ end