right_aws 2.0.0 → 2.1.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.
- data/History.txt +22 -1
- data/Manifest.txt +11 -1
- data/README.txt +0 -4
- data/Rakefile +19 -25
- data/lib/acf/right_acf_interface.rb +199 -135
- data/lib/acf/right_acf_invalidations.rb +144 -0
- data/lib/acf/right_acf_origin_access_identities.rb +4 -4
- data/lib/acf/right_acf_streaming_interface.rb +19 -26
- data/lib/acw/right_acw_interface.rb +1 -2
- data/lib/as/right_as_interface.rb +6 -7
- data/lib/awsbase/right_awsbase.rb +287 -91
- data/lib/awsbase/support.rb +2 -82
- data/lib/awsbase/version.rb +9 -0
- data/lib/ec2/right_ec2.rb +101 -38
- data/lib/ec2/right_ec2_ebs.rb +71 -58
- data/lib/ec2/right_ec2_images.rb +82 -42
- data/lib/ec2/right_ec2_instances.rb +74 -44
- data/lib/ec2/right_ec2_placement_groups.rb +108 -0
- data/lib/ec2/right_ec2_reserved_instances.rb +50 -46
- data/lib/ec2/right_ec2_security_groups.rb +148 -32
- data/lib/ec2/right_ec2_spot_instances.rb +53 -27
- data/lib/ec2/right_ec2_tags.rb +139 -0
- data/lib/ec2/right_ec2_vpc.rb +151 -139
- data/lib/ec2/right_ec2_windows_mobility.rb +84 -0
- data/lib/elb/right_elb_interface.rb +93 -18
- data/lib/iam/right_iam_access_keys.rb +71 -0
- data/lib/iam/right_iam_groups.rb +195 -0
- data/lib/iam/right_iam_interface.rb +341 -0
- data/lib/iam/right_iam_mfa_devices.rb +67 -0
- data/lib/iam/right_iam_users.rb +251 -0
- data/lib/rds/right_rds_interface.rb +513 -202
- data/lib/right_aws.rb +12 -12
- data/lib/route_53/right_route_53_interface.rb +630 -0
- data/lib/s3/right_s3.rb +9 -12
- data/lib/s3/right_s3_interface.rb +10 -11
- data/lib/sdb/active_sdb.rb +18 -33
- data/lib/sdb/right_sdb_interface.rb +36 -4
- data/lib/sqs/right_sqs.rb +1 -2
- data/lib/sqs/right_sqs_gen2.rb +0 -1
- data/lib/sqs/right_sqs_gen2_interface.rb +4 -5
- data/lib/sqs/right_sqs_interface.rb +6 -7
- data/right_aws.gemspec +91 -0
- data/test/awsbase/test_helper.rb +2 -0
- data/test/awsbase/test_right_awsbase.rb +12 -0
- data/test/s3/test_right_s3.rb +1 -1
- data/test/sdb/test_active_sdb.rb +1 -1
- data/test/sdb/test_batch_put_attributes.rb +54 -0
- data/test/sqs/test_right_sqs.rb +0 -6
- data/test/sqs/test_right_sqs_gen2.rb +1 -1
- metadata +109 -58
data/lib/right_aws.rb
CHANGED
@@ -35,8 +35,9 @@ require 'rubygems'
|
|
35
35
|
require 'right_http_connection'
|
36
36
|
|
37
37
|
$:.unshift(File.dirname(__FILE__))
|
38
|
-
require 'awsbase/
|
38
|
+
require 'awsbase/version'
|
39
39
|
require 'awsbase/support'
|
40
|
+
require 'awsbase/benchmark_fix'
|
40
41
|
require 'awsbase/right_awsbase'
|
41
42
|
require 'ec2/right_ec2'
|
42
43
|
require 'ec2/right_ec2_images'
|
@@ -47,6 +48,9 @@ require 'ec2/right_ec2_ebs'
|
|
47
48
|
require 'ec2/right_ec2_reserved_instances'
|
48
49
|
require 'ec2/right_ec2_vpc'
|
49
50
|
require 'ec2/right_ec2_monitoring'
|
51
|
+
require 'ec2/right_ec2_placement_groups'
|
52
|
+
require 'ec2/right_ec2_windows_mobility'
|
53
|
+
require 'ec2/right_ec2_tags'
|
50
54
|
require 'elb/right_elb_interface'
|
51
55
|
require 'acw/right_acw_interface'
|
52
56
|
require 'as/right_as_interface'
|
@@ -60,18 +64,14 @@ require 'sdb/right_sdb_interface'
|
|
60
64
|
require 'acf/right_acf_interface'
|
61
65
|
require 'acf/right_acf_streaming_interface'
|
62
66
|
require 'acf/right_acf_origin_access_identities'
|
67
|
+
require 'acf/right_acf_invalidations'
|
63
68
|
require 'rds/right_rds_interface'
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
TINY = 0 unless defined?(TINY)
|
71
|
-
|
72
|
-
STRING = [MAJOR, MINOR, TINY].join('.') unless defined?(STRING)
|
73
|
-
end
|
74
|
-
end
|
69
|
+
require 'iam/right_iam_interface'
|
70
|
+
require 'iam/right_iam_groups'
|
71
|
+
require 'iam/right_iam_users'
|
72
|
+
require 'iam/right_iam_access_keys'
|
73
|
+
require 'iam/right_iam_mfa_devices'
|
74
|
+
require 'route_53/right_route_53_interface'
|
75
75
|
|
76
76
|
#-
|
77
77
|
|
@@ -0,0 +1,630 @@
|
|
1
|
+
# Copyright (c) 2007-2011 RightScale Inc
|
2
|
+
#
|
3
|
+
# Permission is hereby granted, free of charge, to any person obtaining
|
4
|
+
# a copy of this software and associated documentation files (the
|
5
|
+
# "Software"), to deal in the Software without restriction, including
|
6
|
+
# without limitation the rights to use, copy, modify, merge, publish,
|
7
|
+
# distribute, sublicense, and/or sell copies of the Software, and to
|
8
|
+
# permit persons to whom the Software is furnished to do so, subject to
|
9
|
+
# the following conditions:
|
10
|
+
#
|
11
|
+
# The above copyright notice and this permission notice shall be
|
12
|
+
# included in all copies or substantial portions of the Software.
|
13
|
+
#
|
14
|
+
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
15
|
+
# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
16
|
+
# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
17
|
+
# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
18
|
+
# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
19
|
+
# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
20
|
+
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
21
|
+
#
|
22
|
+
|
23
|
+
module RightAws
|
24
|
+
|
25
|
+
# = RightAws::Route53Interface -- Amazon Route 53 web service interface.
|
26
|
+
#
|
27
|
+
# The RightAws::Route53Interface class provides a complete interface to Amazon Route 53: a web
|
28
|
+
# service that enables you to manage your DNS service.
|
29
|
+
#
|
30
|
+
# For explanations of the semantics of each call, please refer to Amazon's documentation at
|
31
|
+
# http://aws.amazon.com/documentation/route53/
|
32
|
+
#
|
33
|
+
# Examples:
|
34
|
+
#
|
35
|
+
# # Create Route53 handler
|
36
|
+
# r53 = RightAws::Route53Interface.new(AWS_ACCESS_KEY_ID, AWS_SECRET_ACCESS_KEY)
|
37
|
+
#
|
38
|
+
# #------------------------
|
39
|
+
# # Create Hosted Zone
|
40
|
+
# #------------------------
|
41
|
+
#
|
42
|
+
# hosted_zone_config = {
|
43
|
+
# :name => 'my-awesome-site.com.',
|
44
|
+
# :config => {
|
45
|
+
# :comment => 'My test site!'
|
46
|
+
# }
|
47
|
+
# }
|
48
|
+
# r53.create_hosted_zone(hosted_zone_config) #=>
|
49
|
+
# {:name_servers=>
|
50
|
+
# ["ns-1115.awsdns-11.org",
|
51
|
+
# "ns-696.awsdns-23.net",
|
52
|
+
# "ns-1963.awsdns-53.co.uk",
|
53
|
+
# "ns-362.awsdns-45.com"],
|
54
|
+
# :aws_id=>"/hostedzone/Z1K6NCF0EB26FB",
|
55
|
+
# :caller_reference=>"1295424990-710392-gqMuw-KcY8F-LFlrB-SQhp9",
|
56
|
+
# :config=>{:comment=>"My test site!"},
|
57
|
+
# :change_info=>
|
58
|
+
# {:status=>"PENDING",
|
59
|
+
# :aws_id=>"/change/C23QGMT8XTCAJY",
|
60
|
+
# :submitted_at=>"2011-01-19T08:16:31.046Z"},
|
61
|
+
# :name=>"my-awesome-site.com."}
|
62
|
+
#
|
63
|
+
# # List Hosted Zones
|
64
|
+
# r53.list_hosted_zones #=> []
|
65
|
+
# [{:aws_id=>"/hostedzone/Z1K6NCF0EB26FB",
|
66
|
+
# :caller_reference=>"1295424990-710392-gqMuw-KcY8F-LFlrB-SQhp9",
|
67
|
+
# :config=>{:comment=>"My test site!"},
|
68
|
+
# :name=>"my-awesome-site.com."}]
|
69
|
+
#
|
70
|
+
# #--------------------------------
|
71
|
+
# # Manage DNS Records and Changes
|
72
|
+
# #--------------------------------
|
73
|
+
#
|
74
|
+
# # Create DNS Records
|
75
|
+
# resource_record_sets = [ { :name => 'www1.my-awesome-site.com.',
|
76
|
+
# :type => 'NS',
|
77
|
+
# :ttl => 600,
|
78
|
+
# :resource_records => 'www.mysite.com' },
|
79
|
+
# { :name => 'www2.my-awesome-site.com.',
|
80
|
+
# :type => 'A',
|
81
|
+
# :ttl => 600,
|
82
|
+
# :resource_records => ['10.0.0.1'] } ]
|
83
|
+
# r53.create_resource_record_sets("/hostedzone/Z1K6NCF0EB26FB", resource_record_sets, 'my first set of records') #=>
|
84
|
+
# { :status=>"PENDING",
|
85
|
+
# :aws_id=>"/change/C2C6IGNRTKA0AY",
|
86
|
+
# :submitted_at=>"2011-01-19T08:29:26.160Z" }
|
87
|
+
#
|
88
|
+
# # Delete DNS records
|
89
|
+
# r53.delete_resource_record_sets("/hostedzone/Z1K6NCF0EB26FB", resource_record_sets, 'I dont need them any more') #=>
|
90
|
+
# { :status=>"PENDING",
|
91
|
+
# :aws_id=>"/change/C1CYJ10EZBFLO7",
|
92
|
+
# :submitted_at=>"2011-01-19T08:26:41.220Z" }
|
93
|
+
#
|
94
|
+
# # Create or delete DNS records (:action key must be provided):
|
95
|
+
# resource_record_sets = [ { :action => :create,
|
96
|
+
# :name => 'www1.my-awesome-site.com.',
|
97
|
+
# :type => 'NS',
|
98
|
+
# :ttl => 600,
|
99
|
+
# :resource_records => 'www.mysite.com' },
|
100
|
+
# { :action => :delete,
|
101
|
+
# :name => 'www2.my-awesome-site.com.',
|
102
|
+
# :type => 'A',
|
103
|
+
# :ttl => 600,
|
104
|
+
# :resource_records => ['10.0.0.1'] } ]
|
105
|
+
# r53.change_resource_record_sets("/hostedzone/Z1K6NCF0EB26FB", resource_record_sets, 'do change records')
|
106
|
+
# { :status=>"PENDING",
|
107
|
+
# :aws_id=>"/change/C2PWXVECN794LK",
|
108
|
+
# :submitted_at=>"2011-01-19T08:31:33.301Z" }
|
109
|
+
#
|
110
|
+
# # List DNS Records
|
111
|
+
# r53.list_resource_record_sets("/hostedzone/Z1K6NCF0EB26FB") #=>
|
112
|
+
# [{:type=>"NS",
|
113
|
+
# :ttl=>172800,
|
114
|
+
# :resource_records=>
|
115
|
+
# ["ns-1115.awsdns-11.org.",
|
116
|
+
# "ns-696.awsdns-23.net.",
|
117
|
+
# "ns-1963.awsdns-53.co.uk.",
|
118
|
+
# "ns-362.awsdns-45.com."],
|
119
|
+
# :name=>"my-awesome-site.com."},
|
120
|
+
# {:type=>"SOA",
|
121
|
+
# :ttl=>900,
|
122
|
+
# :resource_records=>
|
123
|
+
# ["ns-1115.awsdns-11.org. awsdns-hostmaster.amazon.com. 1 7200 900 1209600 86400"],
|
124
|
+
# :name=>"my-awesome-site.com."},
|
125
|
+
# {:type=>"NS",
|
126
|
+
# :ttl=>600,
|
127
|
+
# :resource_records=>["www.mysite.com"],
|
128
|
+
# :name=>"www1.my-awesome-site.com."}]
|
129
|
+
#
|
130
|
+
# # Get Change info
|
131
|
+
# r53.get_change("/change/C2C6IGNRTKA0AY")
|
132
|
+
# {:status=>"INSYNC",
|
133
|
+
# :aws_id=>"/change/C2C6IGNRTKA0AY",
|
134
|
+
# :submitted_at=>"2011-01-19T08:29:26.160Z"}
|
135
|
+
#
|
136
|
+
# #------------------------
|
137
|
+
# # Delete Hosted Zone
|
138
|
+
# #------------------------
|
139
|
+
#
|
140
|
+
# # Get a list of DNS records I have created (the first 2 records were added by Amazon and cannot be deleted)
|
141
|
+
# resource_record_sets = r53.list_resource_record_sets("/hostedzone/Z1K6NCF0EB26FB")
|
142
|
+
# resource_record_sets.shift
|
143
|
+
# resource_record_sets.shift
|
144
|
+
#
|
145
|
+
# # Delete them all
|
146
|
+
# delete_resource_record_sets("/hostedzone/Z1K6NCF0EB26FB", resource_record_sets, 'kill all records I have created') #=>
|
147
|
+
# { :status=>"PENDING",
|
148
|
+
# :aws_id=>"/change/C6NCO8Z50MHXV",
|
149
|
+
# :submitted_at=>"2011-01-19T08:46:37.307Z" }
|
150
|
+
#
|
151
|
+
# # Delete Hosted Zone
|
152
|
+
# r53.delete_hosted_zone("/hostedzone/Z1K6NCF0EB26FB") #=>
|
153
|
+
# { :status=>"PENDING",
|
154
|
+
# :aws_id=>"/change/C3OJ31D4V5P2LU",
|
155
|
+
# :submitted_at=>"2011-01-19T08:46:37.530Z" }
|
156
|
+
#
|
157
|
+
class Route53Interface < RightAwsBase
|
158
|
+
|
159
|
+
include RightAwsBaseInterface
|
160
|
+
|
161
|
+
API_VERSION = "2010-10-01"
|
162
|
+
DEFAULT_HOST = "route53.amazonaws.com"
|
163
|
+
DEFAULT_PATH = '/'
|
164
|
+
DEFAULT_PROTOCOL = 'https'
|
165
|
+
DEFAULT_PORT = 443
|
166
|
+
|
167
|
+
@@bench = AwsBenchmarkingBlock.new
|
168
|
+
def self.bench_xml
|
169
|
+
@@bench.xml
|
170
|
+
end
|
171
|
+
def self.bench_service
|
172
|
+
@@bench.service
|
173
|
+
end
|
174
|
+
|
175
|
+
# Create a new handle to an Route53 account. All handles share the same per process or per thread
|
176
|
+
# HTTP connection to Amazon Route53. Each handle is for a specific account. The params have the
|
177
|
+
# following options:
|
178
|
+
# * <tt>:endpoint_url</tt> a fully qualified url to Amazon API endpoint (this overwrites: :server, :port, :service, :protocol).
|
179
|
+
# * <tt>:server</tt>: Route53 service host, default: DEFAULT_HOST
|
180
|
+
# * <tt>:port</tt>: Route53 service port, default: DEFAULT_PORT
|
181
|
+
# * <tt>:protocol</tt>: 'http' or 'https', default: DEFAULT_PROTOCOL
|
182
|
+
# * <tt>:logger</tt>: for log messages, default: RAILS_DEFAULT_LOGGER else STDOUT
|
183
|
+
# * <tt>:signature_version</tt>: The signature version : '0','1' or '2'(default)
|
184
|
+
#
|
185
|
+
def initialize(aws_access_key_id=nil, aws_secret_access_key=nil, params={})
|
186
|
+
init({ :name => 'ROUTE_53',
|
187
|
+
:default_host => ENV['ROUTE_53_URL'] ? URI.parse(ENV['ROUTE_53_URL']).host : DEFAULT_HOST,
|
188
|
+
:default_port => ENV['ROUTE_53_URL'] ? URI.parse(ENV['ROUTE_53_URL']).port : DEFAULT_PORT,
|
189
|
+
:default_service => ENV['ROUTE_53_URL'] ? URI.parse(ENV['ROUTE_53_URL']).path : DEFAULT_PATH,
|
190
|
+
:default_protocol => ENV['ROUTE_53_URL'] ? URI.parse(ENV['ROUTE_53_URL']).scheme : DEFAULT_PROTOCOL,
|
191
|
+
:default_api_version => ENV['ROUTE_53_API_VERSION'] || API_VERSION },
|
192
|
+
aws_access_key_id || ENV['AWS_ACCESS_KEY_ID'] ,
|
193
|
+
aws_secret_access_key|| ENV['AWS_SECRET_ACCESS_KEY'],
|
194
|
+
params)
|
195
|
+
end
|
196
|
+
|
197
|
+
#-----------------------------------------------------------------
|
198
|
+
# Requests
|
199
|
+
#-----------------------------------------------------------------
|
200
|
+
|
201
|
+
# Generates request hash for REST API.
|
202
|
+
def generate_request(method, path, params={}, body=nil, headers={}) # :nodoc:
|
203
|
+
# Params
|
204
|
+
params.delete_if{ |key, val| val.right_blank? }
|
205
|
+
unless params.right_blank?
|
206
|
+
path += "?" + params.to_a.collect{ |key,val| "#{AwsUtils::amz_escape(key)}=#{AwsUtils::amz_escape(val.to_s)}" }.join("&")
|
207
|
+
end
|
208
|
+
# Headers
|
209
|
+
headers['content-type'] ||= 'text/xml' if body
|
210
|
+
headers['date'] = Time.now.httpdate
|
211
|
+
# Auth
|
212
|
+
signature = AwsUtils::sign(@aws_secret_access_key, headers['date'])
|
213
|
+
headers['X-Amzn-Authorization'] = "AWS3-HTTPS AWSAccessKeyId=#{@aws_access_key_id},Algorithm=HmacSHA1,Signature=#{signature}"
|
214
|
+
# Request
|
215
|
+
path = "#{@params[:service]}#{@params[:api_version]}/#{path}"
|
216
|
+
request = "Net::HTTP::#{method.capitalize}".right_constantize.new(path)
|
217
|
+
request.body = body if body
|
218
|
+
# Set request headers
|
219
|
+
headers.each { |key, value| request[key.to_s] = value }
|
220
|
+
# prepare output hash
|
221
|
+
{ :request => request,
|
222
|
+
:server => @params[:server],
|
223
|
+
:port => @params[:port],
|
224
|
+
:protocol => @params[:protocol] }
|
225
|
+
end
|
226
|
+
|
227
|
+
# Sends request to Amazon and parses the response.
|
228
|
+
# Raises AwsError if any banana happened.
|
229
|
+
def request_info(request, parser, &block) # :nodoc:
|
230
|
+
request_info_impl(:acf_connection, @@bench, request, parser, &block)
|
231
|
+
end
|
232
|
+
|
233
|
+
def incrementally_list_hosted_zones(path, parser, params={}, &block) # :nodoc:
|
234
|
+
opts = {}
|
235
|
+
opts['MaxItems'] = params[:max_items] if params[:max_items]
|
236
|
+
opts['Marker'] = params[:marker] if params[:marker]
|
237
|
+
last_response = nil
|
238
|
+
loop do
|
239
|
+
link = generate_request('GET', path, opts)
|
240
|
+
last_response = request_info(link, parser.new(:logger => @logger))
|
241
|
+
opts['Marker'] = last_response[:next_marker]
|
242
|
+
break unless block && block.call(last_response) && !last_response[:next_marker].right_blank?
|
243
|
+
end
|
244
|
+
last_response
|
245
|
+
end
|
246
|
+
|
247
|
+
def incrementally_list_resource_records(path, parser, params={}, &block) # :nodoc:
|
248
|
+
opts = {}
|
249
|
+
opts[:maxitems] = params.delete(:max_items) if params[:max_items]
|
250
|
+
last_response = nil
|
251
|
+
loop do
|
252
|
+
link = generate_request('GET', path, opts)
|
253
|
+
last_response = request_info(link, parser.new(:logger => @logger))
|
254
|
+
opts[:maxitems] = last_response[:max_items]
|
255
|
+
opts[:name] = last_response[:next_record_name]
|
256
|
+
opts[:type] = last_response[:next_record_type]
|
257
|
+
break unless block && block.call(last_response) && last_response[:is_truncated]
|
258
|
+
end
|
259
|
+
last_response
|
260
|
+
end
|
261
|
+
|
262
|
+
def expand_hosted_zone_id(aws_id) # :nodoc:
|
263
|
+
aws_id[%r{^/hostedzone/}] ? aws_id : "/hostedzone/#{aws_id}"
|
264
|
+
end
|
265
|
+
|
266
|
+
def expand_change_id(aws_id) # :nodoc:
|
267
|
+
aws_id[%r{^/change/}] ? aws_id : "/change/#{aws_id}"
|
268
|
+
end
|
269
|
+
|
270
|
+
def hosted_zone_config_to_xml(config) # :nodoc:
|
271
|
+
config[:caller_reference] ||= AwsUtils::generate_call_reference
|
272
|
+
hosted_zone_config = ''
|
273
|
+
unless config[:config].right_blank?
|
274
|
+
hosted_zone_config = " <HostedZoneConfig>\n" +
|
275
|
+
" <Comment>#{AwsUtils::xml_escape config[:config][:comment]}</Comment>\n" +
|
276
|
+
" </HostedZoneConfig>\n"
|
277
|
+
end
|
278
|
+
# XML
|
279
|
+
"<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n" +
|
280
|
+
"<CreateHostedZoneRequest xmlns=\"https://#{@params[:server]}/doc/#{API_VERSION}/\">\n" +
|
281
|
+
" <Name>#{config[:name]}</Name>\n" +
|
282
|
+
" <CallerReference>#{config[:caller_reference]}</CallerReference>\n" +
|
283
|
+
hosted_zone_config +
|
284
|
+
"</CreateHostedZoneRequest>\n"
|
285
|
+
end
|
286
|
+
|
287
|
+
def resource_record_sets_to_xml(resource_record_changes, comment) # :nodoc:
|
288
|
+
# Comment
|
289
|
+
xml_comment = comment.right_blank? ? '' : " <Comment>#{AwsUtils::xml_escape(comment)}</Comment>\n"
|
290
|
+
# Changes
|
291
|
+
xml_changes = ''
|
292
|
+
resource_record_changes.each do |change|
|
293
|
+
xml_resource_records = Array(change[:resource_records]).map{|record| " <ResourceRecord><Value>#{AwsUtils::xml_escape(record)}</Value></ResourceRecord>\n" }.join('')
|
294
|
+
xml_changes += " <Change>\n" +
|
295
|
+
" <Action>#{AwsUtils::xml_escape(change[:action].to_s.upcase)}</Action>\n" +
|
296
|
+
" <ResourceRecordSet>\n" +
|
297
|
+
" <Name>#{AwsUtils::xml_escape(change[:name])}</Name>\n" +
|
298
|
+
" <Type>#{AwsUtils::xml_escape(change[:type].to_s.upcase)}</Type>\n" +
|
299
|
+
" <TTL>#{AwsUtils::xml_escape(change[:ttl].to_s)}</TTL>\n" +
|
300
|
+
" <ResourceRecords>\n" +
|
301
|
+
xml_resource_records +
|
302
|
+
" </ResourceRecords>\n" +
|
303
|
+
" </ResourceRecordSet>\n" +
|
304
|
+
" </Change>\n"
|
305
|
+
end
|
306
|
+
# XML
|
307
|
+
"<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n" +
|
308
|
+
"<ChangeResourceRecordSetsRequest xmlns=\"https://#{@params[:server]}/doc/#{API_VERSION}/\">\n" +
|
309
|
+
" <ChangeBatch>\n" +
|
310
|
+
xml_comment +
|
311
|
+
" <Changes>\n" +
|
312
|
+
xml_changes +
|
313
|
+
" </Changes>\n" +
|
314
|
+
" </ChangeBatch>\n" +
|
315
|
+
"</ChangeResourceRecordSetsRequest>\n"
|
316
|
+
end
|
317
|
+
|
318
|
+
|
319
|
+
#-----------------------------------------------------------------
|
320
|
+
# Hosted Zones
|
321
|
+
#-----------------------------------------------------------------
|
322
|
+
|
323
|
+
# List your hosted zones.
|
324
|
+
#
|
325
|
+
# r53.list_hosted_zones #=>
|
326
|
+
# [{:config=>{:comment=>"KD1, description"},
|
327
|
+
# :aws_id=>"/hostedzone/Z2P714ENJN23PN",
|
328
|
+
# :caller_reference=>"1295424990-710392-gqMuw-KcY8F-LFlrB-SQhp9",
|
329
|
+
# :name=>"patch-island.com."},
|
330
|
+
# {:config=>{:comment=>"My awesome site!"},
|
331
|
+
# :aws_id=>"/hostedzone/ZWEC7PPVACGQ4",
|
332
|
+
# :caller_reference=>"1295422234-657482-hfkeo-JFKid-Ldfle-Sdrty",
|
333
|
+
# :name=>"mysite.patch-island.com."}, ...]
|
334
|
+
#
|
335
|
+
# PS: http://docs.amazonwebservices.com/Route53/latest/APIReference/API_ListHostedZones.html
|
336
|
+
#
|
337
|
+
def list_hosted_zones
|
338
|
+
result = []
|
339
|
+
incrementally_list_hosted_zones('hostedzone', ListHostedZonesParser) do |response|
|
340
|
+
result += response[:items]
|
341
|
+
true
|
342
|
+
end
|
343
|
+
result
|
344
|
+
end
|
345
|
+
|
346
|
+
# Create new hosted zone
|
347
|
+
#
|
348
|
+
# config = {
|
349
|
+
# :name => 'mysite.patch-island.com.',
|
350
|
+
# :config => {
|
351
|
+
# :comment => 'My awesome site!'
|
352
|
+
# }
|
353
|
+
# }
|
354
|
+
# r53.create_hosted_zone(config) #=>
|
355
|
+
# {:config=>{:comment=>"My awesome site!"},
|
356
|
+
# :change_info=>
|
357
|
+
# {:status=>"PENDING",
|
358
|
+
# :aws_id=>"/change/C2NOTVGL7IOFFF",
|
359
|
+
# :submitted_at=>"2011-01-18T15:34:18.086Z"},
|
360
|
+
# :aws_id=>"/hostedzone/ZWEC7PPVACGQ4",
|
361
|
+
# :caller_reference=>"1295365357-227168-NfZ4P-VGHWi-Yq0p7-nuN6q",
|
362
|
+
# :name_servers=>
|
363
|
+
# ["ns-794.awsdns-35.net",
|
364
|
+
# "ns-459.awsdns-57.com",
|
365
|
+
# "ns-1537.awsdns-00.co.uk",
|
366
|
+
# "ns-1165.awsdns-17.org"],
|
367
|
+
# :name=>"mysite.patch-island.com."}
|
368
|
+
#
|
369
|
+
# PS: http://docs.amazonwebservices.com/Route53/latest/APIReference/index.html?API_CreateHostedZone.html
|
370
|
+
#
|
371
|
+
def create_hosted_zone(config)
|
372
|
+
config[:caller_reference] ||= AwsUtils::generate_unique_token
|
373
|
+
link = generate_request('POST', 'hostedzone', {}, hosted_zone_config_to_xml(config))
|
374
|
+
request_info(link, GetHostedZoneParser.new(:logger => @logger))
|
375
|
+
end
|
376
|
+
|
377
|
+
# Get your hosted zone.
|
378
|
+
#
|
379
|
+
# r53.get_hosted_zone("ZWEC7PPVACGQ4") #=>
|
380
|
+
# {:config=>{:comment=>"My awesome site!"},
|
381
|
+
# :aws_id=>"/hostedzone/ZWEC7PPVACGQ4",
|
382
|
+
# :caller_reference=>"1295422234-657482-hfkeo-JFKid-Ldfle-Sdrty",
|
383
|
+
# :name_servers=>
|
384
|
+
# ["ns-794.awsdns-35.net",
|
385
|
+
# "ns-459.awsdns-57.com",
|
386
|
+
# "ns-1537.awsdns-00.co.uk",
|
387
|
+
# "ns-1165.awsdns-17.org"],
|
388
|
+
# :name=>"mysite.patch-island.com."}
|
389
|
+
#
|
390
|
+
# PS: http://docs.amazonwebservices.com/Route53/latest/APIReference/API_GetHostedZone.html
|
391
|
+
#
|
392
|
+
def get_hosted_zone(hosted_zone_aws_id)
|
393
|
+
link = generate_request('GET', expand_hosted_zone_id(hosted_zone_aws_id))
|
394
|
+
request_info(link, GetHostedZoneParser.new(:logger => @logger))
|
395
|
+
end
|
396
|
+
|
397
|
+
# Delete hosted zone.
|
398
|
+
#
|
399
|
+
# r53.delete_hosted_zone("/hostedzone/Z2P714ENJN23PN") #=>
|
400
|
+
# {:status=>"PENDING",
|
401
|
+
# :submitted_at=>"2011-01-18T15:45:45.060Z",
|
402
|
+
# :aws_id=>"/change/C1PN1SDWZKPTAC"}
|
403
|
+
#
|
404
|
+
# PS: http://docs.amazonwebservices.com/Route53/latest/APIReference/API_DeleteHostedZone.html
|
405
|
+
#
|
406
|
+
def delete_hosted_zone(hosted_zone_aws_id)
|
407
|
+
link = generate_request('DELETE', expand_hosted_zone_id(hosted_zone_aws_id))
|
408
|
+
request_info(link, GetChangeParser.new(:logger => @logger))
|
409
|
+
end
|
410
|
+
|
411
|
+
#-----------------------------------------------------------------
|
412
|
+
# Resource Records Set
|
413
|
+
#-----------------------------------------------------------------
|
414
|
+
|
415
|
+
# List your resource record sets.
|
416
|
+
# Options: :type, :name, :max_items
|
417
|
+
#
|
418
|
+
# r53.list_resource_record_sets("/hostedzone/ZWEC7PPVACGQ4") #=>
|
419
|
+
# {:items=>
|
420
|
+
# [{:type=>"NS",
|
421
|
+
# :ttl=>172800,
|
422
|
+
# :name=>"mysite.patch-island.com.",
|
423
|
+
# :resource_records=>
|
424
|
+
# ["ns-459.awsdns-57.com.",
|
425
|
+
# "ns-794.awsdns-35.net.",
|
426
|
+
# "ns-1165.awsdns-17.org.",
|
427
|
+
# "ns-1537.awsdns-00.co.uk."]},
|
428
|
+
# {:type=>"SOA",
|
429
|
+
# :ttl=>900,
|
430
|
+
# :name=>"mysite.patch-island.com.",
|
431
|
+
# :resource_records=>
|
432
|
+
# ["ns-794.awsdns-35.net. awsdns-hostmaster.amazon.com. 1 7200 900 1209600 86400"]},
|
433
|
+
# {:type=>"NS",
|
434
|
+
# :ttl=>600,
|
435
|
+
# :resource_records=>["xxx.mysite.com"],
|
436
|
+
# :name=>"m1.mysite.patch-island.com."}],
|
437
|
+
# :is_truncated=>false,
|
438
|
+
# :max_items=>100}
|
439
|
+
#
|
440
|
+
# PS: http://docs.amazonwebservices.com/Route53/latest/APIReference/API_ListResourceRecordSets.html
|
441
|
+
#
|
442
|
+
def list_resource_record_sets(hosted_zone_aws_id, options={})
|
443
|
+
options = options.dup
|
444
|
+
result = []
|
445
|
+
incrementally_list_resource_records("#{expand_hosted_zone_id(hosted_zone_aws_id)}/rrset", ListResourceRecordSetsParser, options) do |response|
|
446
|
+
result += response[:items]
|
447
|
+
true
|
448
|
+
end
|
449
|
+
result
|
450
|
+
end
|
451
|
+
|
452
|
+
# Create or delete DNS records.
|
453
|
+
#
|
454
|
+
# resource_record_sets = { :action => :create,
|
455
|
+
# :name => 'm3.mysite.patch-island.com',
|
456
|
+
# :type => 'NS',
|
457
|
+
# :ttl => 600,
|
458
|
+
# :resource_records => 'xxx.mysite.com' },
|
459
|
+
# { :action => :delete,
|
460
|
+
# :name => 'm2.mysite.patch-island.com',
|
461
|
+
# :type => 'A',
|
462
|
+
# :ttl => 600,
|
463
|
+
# :resource_records => ['10.0.0.1'] }
|
464
|
+
# r53.change_resource_record_sets("/hostedzone/Z1K6NCF0EB26FB", resource_record_sets, 'KD: Comment#1') #=>
|
465
|
+
# {:status=>"PENDING",
|
466
|
+
# :submitted_at=>"2011-01-18T20:21:56.828Z",
|
467
|
+
# :aws_id=>"/change/C394PNLM1B2P08"}
|
468
|
+
#
|
469
|
+
# PS: resource_record_sets must have an :action key set (== :create or :delete)
|
470
|
+
# PPS: http://docs.amazonwebservices.com/Route53/latest/APIReference/API_ChangeResourceRecordSets.html
|
471
|
+
#
|
472
|
+
def change_resource_record_sets(hosted_zone_aws_id, resource_record_sets, comment = '')
|
473
|
+
link = generate_request('POST', "#{expand_hosted_zone_id(hosted_zone_aws_id)}/rrset", {}, resource_record_sets_to_xml(resource_record_sets, comment))
|
474
|
+
request_info(link, GetChangeParser.new(:logger => @logger))
|
475
|
+
end
|
476
|
+
|
477
|
+
# Create DNS records.
|
478
|
+
#
|
479
|
+
# resource_record_sets = { :name => 'm3.mysite.patch-island.com',
|
480
|
+
# :type => 'NS',
|
481
|
+
# :ttl => 600,
|
482
|
+
# :resource_records => 'xxx.mysite.com' },
|
483
|
+
# { :name => 'm2.mysite.patch-island.com',
|
484
|
+
# :type => 'A',
|
485
|
+
# :ttl => 600,
|
486
|
+
# :resource_records => ['10.0.0.1'] }
|
487
|
+
# r53.create_resource_record_sets("/hostedzone/Z1K6NCF0EB26FB", resource_record_sets, 'KD: Comment#1') #=>
|
488
|
+
# {:status=>"PENDING",
|
489
|
+
# :submitted_at=>"2011-01-18T20:21:56.828Z",
|
490
|
+
# :aws_id=>"/change/C394PNLM1B2P08"}
|
491
|
+
#
|
492
|
+
# PS: http://docs.amazonwebservices.com/Route53/latest/APIReference/API_ChangeResourceRecordSets.html
|
493
|
+
#
|
494
|
+
def create_resource_record_sets(hosted_zone_aws_id, resource_record_sets, comment = '')
|
495
|
+
resource_record_sets.each{|rrs| rrs[:action] = :create}
|
496
|
+
change_resource_record_sets(hosted_zone_aws_id, resource_record_sets, comment)
|
497
|
+
end
|
498
|
+
|
499
|
+
# Delete DNS records.
|
500
|
+
#
|
501
|
+
# resource_record_sets = { :name => 'm3.mysite.patch-island.com',
|
502
|
+
# :type => 'NS',
|
503
|
+
# :ttl => 600,
|
504
|
+
# :resource_records => 'xxx.mysite.com' },
|
505
|
+
# { :name => 'm2.mysite.patch-island.com',
|
506
|
+
# :type => 'A',
|
507
|
+
# :ttl => 600,
|
508
|
+
# :resource_records => ['10.0.0.1'] }
|
509
|
+
# r53.create_resource_record_sets("/hostedzone/Z1K6NCF0EB26FB", resource_record_sets, 'KD: Comment#1') #=>
|
510
|
+
# {:status=>"PENDING",
|
511
|
+
# :submitted_at=>"2011-01-18T20:21:56.828Z",
|
512
|
+
# :aws_id=>"/change/C394PNLM1B2P08"}
|
513
|
+
#
|
514
|
+
# PS: http://docs.amazonwebservices.com/Route53/latest/APIReference/API_ChangeResourceRecordSets.html
|
515
|
+
#
|
516
|
+
def delete_resource_record_sets(hosted_zone_aws_id, resource_record_sets, comment = '')
|
517
|
+
resource_record_sets.each{|rrs| rrs[:action] = :delete}
|
518
|
+
change_resource_record_sets(hosted_zone_aws_id, resource_record_sets, comment)
|
519
|
+
end
|
520
|
+
|
521
|
+
|
522
|
+
# Get the current state of a change request.
|
523
|
+
#
|
524
|
+
# r53.get_change("/change/C1PN1SDWZKPTAC") #=>
|
525
|
+
# {:status=>"INSYNC",
|
526
|
+
# :aws_id=>"/change/C1PN1SDWZKPTAC",
|
527
|
+
# :submitted_at=>"2011-01-18T15:45:45.060Z"}
|
528
|
+
#
|
529
|
+
# PS: http://docs.amazonwebservices.com/Route53/latest/APIReference/API_GetChange.html
|
530
|
+
#
|
531
|
+
def get_change(change_aws_id)
|
532
|
+
link = generate_request('GET', expand_change_id(change_aws_id))
|
533
|
+
request_info(link, GetChangeParser.new(:logger => @logger))
|
534
|
+
end
|
535
|
+
|
536
|
+
#-----------------------------------------------------------------
|
537
|
+
# Hosted Zones
|
538
|
+
#-----------------------------------------------------------------
|
539
|
+
|
540
|
+
class ListHostedZonesParser < RightAWSParser # :nodoc:
|
541
|
+
def reset
|
542
|
+
@result = { :items => [] }
|
543
|
+
end
|
544
|
+
def tagstart(name, attributes)
|
545
|
+
case name
|
546
|
+
when 'HostedZone' then @item = { :config => {} }
|
547
|
+
end
|
548
|
+
end
|
549
|
+
def tagend(name)
|
550
|
+
case name
|
551
|
+
when 'IsTruncated' then @result[:is_truncated] = @text == 'true'
|
552
|
+
when 'NextMarker' then @result[:next_marker] = @text
|
553
|
+
when 'MaxItems' then @result[:max_items] = @text.to_i
|
554
|
+
when 'Id' then @item[:aws_id] = @text
|
555
|
+
when 'Name' then @item[:name] = @text
|
556
|
+
when 'CallerReference' then @item[:caller_reference] = @text
|
557
|
+
when 'HostedZone' then @result[:items] << @item
|
558
|
+
else
|
559
|
+
case full_tag_name
|
560
|
+
when %r{/Config/Comment$} then @item[:config][:comment] = @text
|
561
|
+
end
|
562
|
+
end
|
563
|
+
end
|
564
|
+
end
|
565
|
+
|
566
|
+
class GetHostedZoneParser < RightAWSParser # :nodoc:
|
567
|
+
def reset
|
568
|
+
@result = {}
|
569
|
+
end
|
570
|
+
def tagend(name)
|
571
|
+
case full_tag_name
|
572
|
+
when %r{/HostedZone/Id} then @result[:aws_id] = @text
|
573
|
+
when %r{/HostedZone/Name} then @result[:name] = @text
|
574
|
+
when %r{/HostedZone/CallerReference} then @result[:caller_reference] = @text
|
575
|
+
when %r{/Config/Comment$} then (@result[:config] ||= {})[:comment] = AwsUtils::xml_unescape(@text)
|
576
|
+
when %r{/ChangeInfo/Id$} then (@result[:change_info] ||= {})[:aws_id] = @text
|
577
|
+
when %r{/ChangeInfo/Status$} then (@result[:change_info] ||= {})[:status] = @text
|
578
|
+
when %r{/ChangeInfo/SubmittedAt$} then (@result[:change_info] ||= {})[:submitted_at] = @text
|
579
|
+
when %r{/DelegationSet/NameServers/NameServer$} then (@result[:name_servers] ||= []) << @text
|
580
|
+
end
|
581
|
+
end
|
582
|
+
end
|
583
|
+
|
584
|
+
#-----------------------------------------------------------------
|
585
|
+
# Resource Records Set
|
586
|
+
#-----------------------------------------------------------------
|
587
|
+
|
588
|
+
class ListResourceRecordSetsParser < RightAWSParser # :nodoc:
|
589
|
+
def reset
|
590
|
+
@result = { :items => [] }
|
591
|
+
end
|
592
|
+
def tagstart(name, attributes)
|
593
|
+
case name
|
594
|
+
when 'ResourceRecordSet' then @item = {}
|
595
|
+
end
|
596
|
+
end
|
597
|
+
def tagend(name)
|
598
|
+
case name
|
599
|
+
when 'IsTruncated' then @result[:is_truncated] = @text == 'true'
|
600
|
+
when 'NextRecordName' then @result[:next_record_name] = @text
|
601
|
+
when 'NextRecordType' then @result[:next_record_type] = @text
|
602
|
+
when 'MaxItems' then @result[:max_items] = @text.to_i
|
603
|
+
when 'Type' then @item[:type] = @text
|
604
|
+
when 'Name' then @item[:name] = @text
|
605
|
+
when 'TTL' then @item[:ttl] = @text.to_i
|
606
|
+
when 'ResourceRecordSet' then @result[:items] << @item
|
607
|
+
else
|
608
|
+
case full_tag_name
|
609
|
+
when %r{/ResourceRecord/Value} then (@item[:resource_records] ||= []) << @text
|
610
|
+
end
|
611
|
+
end
|
612
|
+
end
|
613
|
+
end
|
614
|
+
|
615
|
+
class GetChangeParser < RightAWSParser # :nodoc:
|
616
|
+
def reset
|
617
|
+
@result = { }
|
618
|
+
end
|
619
|
+
def tagend(name)
|
620
|
+
case name
|
621
|
+
when 'Id' then @result[:aws_id] = @text
|
622
|
+
when 'Status' then @result[:status] = @text
|
623
|
+
when 'SubmittedAt' then @result[:submitted_at] = @text
|
624
|
+
end
|
625
|
+
end
|
626
|
+
end
|
627
|
+
|
628
|
+
end
|
629
|
+
|
630
|
+
end
|