dnsmadeeasy-api 0.9 → 0.9.5
Sign up to get free protection for your applications and to get access to all the features.
- data/README.rdoc +10 -4
- data/Rakefile +2 -2
- data/bin/dme +32 -11
- data/dnsmadeeasy-api.gemspec +3 -3
- data/lib/dnsmadeeasy/api.rb +178 -97
- data/lib/dnsmadeeasy/exceptions.rb +8 -23
- metadata +5 -4
data/README.rdoc
CHANGED
@@ -12,8 +12,8 @@ Ruby client for DNSMadeEasy API.
|
|
12
12
|
require "rubygems"
|
13
13
|
require "dnsmadeeasy/api"
|
14
14
|
|
15
|
-
api_key =
|
16
|
-
|
15
|
+
api_key = "your-12345-api-67890-key"
|
16
|
+
secret_key = "your-12345-secret-67890-key"
|
17
17
|
api = DnsMadeEasy::Api(api_key, secret_key)
|
18
18
|
api.list_records "sigfig.com"
|
19
19
|
|
@@ -23,6 +23,12 @@ This is a great way to test your application without changing your production DN
|
|
23
23
|
api = DnsMadeEasy::Api(api_key, secret_key, true)
|
24
24
|
api.list_records "sigfig.com"
|
25
25
|
|
26
|
+
The api calls throw the following exceptions:
|
27
|
+
* BadRequestError: For cases when there is missing information or the api limits have been exceeded
|
28
|
+
* ResourceNotFoundError: For cases when a request is made for an unknown domain or record
|
29
|
+
* AuthorizationFailedError: For cases when the request cannot be authorized
|
30
|
+
* InvalidRecordError: When a record to be created or updated is not well formed
|
31
|
+
|
26
32
|
== Command line tool
|
27
33
|
|
28
34
|
The client comes with a command line tool "dme". Use "dme --help" to see how to use the command.
|
@@ -33,5 +39,5 @@ The command line tool requires that your api credentials be stored in /etc/dnsma
|
|
33
39
|
The command line tool also allows the running of queries in the sandbox mode. To do so, create
|
34
40
|
/etc/dnsmadeeasy/api_sandbox.keys with your sandbox api key and secret key and use the --sandbox option
|
35
41
|
with every command.
|
36
|
-
|
37
|
-
=end
|
42
|
+
|
43
|
+
=end
|
data/Rakefile
CHANGED
@@ -2,12 +2,12 @@ require "rubygems"
|
|
2
2
|
require "rake"
|
3
3
|
require "echoe"
|
4
4
|
|
5
|
-
Echoe.new("dnsmadeeasy-api", "0.9") do |p|
|
5
|
+
Echoe.new("dnsmadeeasy-api", "0.9.5") do |p|
|
6
6
|
p.description = "Ruby client for DNSMadeEasy API."
|
7
7
|
p.summary = "Ruby client for DNSMadeEasy API."
|
8
8
|
p.url = "http://rubygems.org/gems/dnsmadeeasy-api"
|
9
9
|
p.author = "Nitesh Goel"
|
10
|
-
p.email = "nitesh@
|
10
|
+
p.email = "nitesh@sigfig.com"
|
11
11
|
p.ignore_pattern = ["tmp/*", "script/*"]
|
12
12
|
p.install_message = "Create /etc/dnsmadeeasy/api.keys and/or /etc/dnsmadeeasy/api_sandbox.keys with the following information\napi_key=<your api key>\nsecret_key=<your secret key>\nto use the dme binary."
|
13
13
|
p.runtime_dependencies = ["rest-client", "json"]
|
data/bin/dme
CHANGED
@@ -27,6 +27,7 @@ module DnsMadeEasy
|
|
27
27
|
"describe-domain" => "Describe a domain entry",
|
28
28
|
"list-records" => "List records for a domain",
|
29
29
|
"create-record" => "Create a new dns record",
|
30
|
+
"delete-records" => "Delete multiple dns records",
|
30
31
|
"delete-record" => "Delete a dns record",
|
31
32
|
"update-record" => "Update an existing dns record",
|
32
33
|
"describe-record" => "Describe an existing dns record"
|
@@ -56,9 +57,7 @@ module DnsMadeEasy
|
|
56
57
|
|
57
58
|
def show_response(response)
|
58
59
|
if @json
|
59
|
-
|
60
|
-
response = { :success => response }
|
61
|
-
end
|
60
|
+
response = { :data => response }
|
62
61
|
puts response.to_json
|
63
62
|
elsif response.is_a?(TrueClass) || response.is_a?(FalseClass)
|
64
63
|
if response
|
@@ -70,7 +69,7 @@ module DnsMadeEasy
|
|
70
69
|
response.each do |x|
|
71
70
|
puts x
|
72
71
|
end
|
73
|
-
|
72
|
+
elsif !response.empty?
|
74
73
|
table_fields = {}
|
75
74
|
response = [response] if response.instance_of?(Hash)
|
76
75
|
response.each do |x|
|
@@ -184,7 +183,9 @@ begin
|
|
184
183
|
when "list-domains"
|
185
184
|
printer.show_response api.list_domains
|
186
185
|
when "delete-domains"
|
187
|
-
|
186
|
+
if force
|
187
|
+
printer.show_response api.delete_domains!
|
188
|
+
else
|
188
189
|
puts "The following domains are listed in your account:"
|
189
190
|
printer.show_response api.list_domains
|
190
191
|
puts "Are you sure you want to delete all domains? (yes/no)"
|
@@ -192,21 +193,25 @@ begin
|
|
192
193
|
unless response.downcase == "yes"
|
193
194
|
printer.say_bye "Domains not deleted"
|
194
195
|
end
|
196
|
+
api.delete_domains!
|
197
|
+
puts "Done"
|
195
198
|
end
|
196
|
-
printer.show_response api.delete_domains!
|
197
199
|
when "create-domain"
|
198
200
|
printer.show_error "Please specify a domain name" if domain.nil?
|
199
201
|
printer.show_response api.create_domain!(domain)
|
200
202
|
when "delete-domain"
|
201
203
|
printer.show_error "Please specify a domain name" if domain.nil?
|
202
|
-
|
204
|
+
if force
|
205
|
+
printer.show_response api.delete_domain!(domain)
|
206
|
+
else
|
203
207
|
puts "Are you sure you want to delete #{domain}? (yes/no)"
|
204
208
|
response = STDIN.gets.chomp.downcase
|
205
209
|
unless response.downcase == "yes"
|
206
210
|
printer.say_bye "Domain #{domain} not deleted"
|
207
211
|
end
|
212
|
+
api.delete_domain!(domain)
|
213
|
+
puts "Done"
|
208
214
|
end
|
209
|
-
printer.show_response api.delete_domain!(domain)
|
210
215
|
when "describe-domain"
|
211
216
|
printer.show_error "Please specify a domain name" if domain.nil?
|
212
217
|
printer.show_response api.describe_domain(domain)
|
@@ -219,23 +224,39 @@ begin
|
|
219
224
|
when "delete-record"
|
220
225
|
printer.show_error "Please specify a domain name" if domain.nil?
|
221
226
|
printer.show_response api.describe_record(domain, record_id)
|
222
|
-
|
227
|
+
if force
|
228
|
+
printer.show_response api.delete_record!(domain, record_id)
|
229
|
+
else
|
223
230
|
puts "Are you sure you want to delete this record? (yes/no)"
|
224
231
|
response = STDIN.gets.chomp.downcase
|
225
232
|
unless response.downcase == "yes"
|
226
233
|
printer.say_bye "Record not deleted"
|
227
234
|
end
|
235
|
+
api.delete_record!(domain, record_id)
|
236
|
+
puts "Done"
|
228
237
|
end
|
229
|
-
printer.show_response api.delete_record!(domain, record_id)
|
230
238
|
when "update-record"
|
231
239
|
printer.show_error "Please specify a domain name" if domain.nil?
|
232
240
|
printer.show_response api.update_record!(domain, record_id, options)
|
233
241
|
when "describe-record"
|
234
242
|
printer.show_error "Please specify a domain name" if domain.nil?
|
235
243
|
printer.show_response api.describe_record(domain, record_id)
|
244
|
+
when "delete-records"
|
245
|
+
printer.show_error "Please specify a domain name" if domain.nil?
|
246
|
+
printer.show_response api.list_records(domain, options)
|
247
|
+
if force
|
248
|
+
printer.show_response api.delete_records!(domain, options)
|
249
|
+
else
|
250
|
+
puts "Are you sure you want to delete these records? (yes/no)"
|
251
|
+
response = STDIN.gets.chomp.downcase
|
252
|
+
unless response.downcase == "yes"
|
253
|
+
printer.say_bye "Records not deleted"
|
254
|
+
end
|
255
|
+
api.delete_records!(domain, options)
|
256
|
+
puts "Done"
|
257
|
+
end
|
236
258
|
when "help"
|
237
259
|
help_for_command = ARGV.shift
|
238
|
-
|
239
260
|
else
|
240
261
|
printer.show_error "Please enter a valid command"
|
241
262
|
end
|
data/dnsmadeeasy-api.gemspec
CHANGED
@@ -2,13 +2,13 @@
|
|
2
2
|
|
3
3
|
Gem::Specification.new do |s|
|
4
4
|
s.name = %q{dnsmadeeasy-api}
|
5
|
-
s.version = "0.9"
|
5
|
+
s.version = "0.9.5"
|
6
6
|
|
7
7
|
s.required_rubygems_version = Gem::Requirement.new(">= 1.2") if s.respond_to? :required_rubygems_version=
|
8
8
|
s.authors = [%q{Nitesh Goel}]
|
9
|
-
s.date = %q{2011-07-
|
9
|
+
s.date = %q{2011-07-07}
|
10
10
|
s.description = %q{Ruby client for DNSMadeEasy API.}
|
11
|
-
s.email = %q{nitesh@
|
11
|
+
s.email = %q{nitesh@sigfig.com}
|
12
12
|
s.executables = [%q{dme}]
|
13
13
|
s.extra_rdoc_files = [%q{README.rdoc}, %q{bin/dme}, %q{lib/dnsmadeeasy/api.rb}, %q{lib/dnsmadeeasy/exceptions.rb}]
|
14
14
|
s.files = [%q{Manifest}, %q{README.rdoc}, %q{Rakefile}, %q{bin/dme}, %q{lib/dnsmadeeasy/api.rb}, %q{lib/dnsmadeeasy/exceptions.rb}, %q{dnsmadeeasy-api.gemspec}]
|
data/lib/dnsmadeeasy/api.rb
CHANGED
@@ -19,8 +19,8 @@ Ruby client for DNSMadeEasy API.
|
|
19
19
|
require "rubygems"
|
20
20
|
require "dnsmadeeasy/api"
|
21
21
|
|
22
|
-
api_key =
|
23
|
-
|
22
|
+
api_key = "your-12345-api-67890-key"
|
23
|
+
secret_key = "your-12345-secret-67890-key"
|
24
24
|
api = DnsMadeEasy::Api(api_key, secret_key)
|
25
25
|
api.list_records "sigfig.com"
|
26
26
|
|
@@ -30,6 +30,12 @@ This is a great way to test your application without changing your production DN
|
|
30
30
|
api = DnsMadeEasy::Api(api_key, secret_key, true)
|
31
31
|
api.list_records "sigfig.com"
|
32
32
|
|
33
|
+
The api calls throw the following exceptions:
|
34
|
+
* BadRequestError: For cases when there is missing information or the api limits have been exceeded
|
35
|
+
* ResourceNotFoundError: For cases when a request is made for an unknown domain or record
|
36
|
+
* AuthorizationFailedError: For cases when the request cannot be authorized
|
37
|
+
* InvalidRecordError: When a record to be created or updated is not well formed
|
38
|
+
|
33
39
|
== Command line tool
|
34
40
|
|
35
41
|
The client comes with a command line tool "dme". Use "dme --help" to see how to use the command.
|
@@ -40,7 +46,7 @@ The command line tool requires that your api credentials be stored in /etc/dnsma
|
|
40
46
|
The command line tool also allows the running of queries in the sandbox mode. To do so, create
|
41
47
|
/etc/dnsmadeeasy/api_sandbox.keys with your sandbox api key and secret key and use the --sandbox option
|
42
48
|
with every command.
|
43
|
-
|
49
|
+
|
44
50
|
=end
|
45
51
|
|
46
52
|
module DnsMadeEasy
|
@@ -60,169 +66,224 @@ module DnsMadeEasy
|
|
60
66
|
end
|
61
67
|
|
62
68
|
# List all domains in the account.
|
63
|
-
#
|
64
|
-
#
|
69
|
+
#
|
70
|
+
# Returns an array of domain names in the account, e.g.
|
71
|
+
# ["sigfig.com", "wikinvest.com"]
|
65
72
|
def list_domains
|
66
|
-
|
73
|
+
execute_with_caution do
|
67
74
|
response = RestClient.get request_url, headers
|
68
75
|
response_hash = JSON.parse(response)
|
69
76
|
return response_hash.has_key?("list") ? response_hash["list"] : []
|
70
|
-
rescue RestClient::Forbidden => e
|
71
|
-
raise DnsMadeEasy::AuthorizationFailedError
|
72
77
|
end
|
73
78
|
end
|
74
79
|
|
75
80
|
# Delete all domains in the account.
|
76
|
-
#
|
77
|
-
#
|
81
|
+
#
|
82
|
+
# Returns an array of domains deleted, e.g.
|
83
|
+
# ["sigfig.com", "wikinvest.com"]
|
78
84
|
def delete_domains!
|
79
|
-
|
85
|
+
execute_with_caution do
|
86
|
+
domains = list_domains
|
80
87
|
response = RestClient.delete request_url, headers
|
81
|
-
return
|
82
|
-
rescue RestClient::Forbidden => e
|
83
|
-
raise DnsMadeEasy::AuthorizationFailedError
|
88
|
+
return domains
|
84
89
|
end
|
85
90
|
end
|
86
91
|
|
87
92
|
# Create a new domain entry.
|
88
|
-
|
89
|
-
#
|
93
|
+
|
94
|
+
# Returns a hash of the newly created domain entry, e.g.
|
95
|
+
# { "name" => "sigfig.com", "nameServer" => ["ns66.dnsmadeeasy.com", "ns99.dnsmadeeasy.com"], "gtdEnabled" => true }
|
90
96
|
def create_domain!(domain)
|
91
|
-
|
97
|
+
execute_with_caution :domain => domain do
|
92
98
|
response = RestClient.put request_url(:path => "#{domain}"), {}, headers
|
93
99
|
return JSON.parse(response)
|
94
|
-
rescue RestClient::BadRequest => e
|
95
|
-
error = JSON.parse(e.http_body)
|
96
|
-
if error["error"][0] == "Invalid domain name."
|
97
|
-
raise DnsMadeEasy::InvalidDomainNameError, domain
|
98
|
-
else
|
99
|
-
raise DnsMadeEasy::DuplicateDomainError, domain
|
100
|
-
end
|
101
|
-
rescue RestClient::Forbidden => e
|
102
|
-
raise DnsMadeEasy::AuthorizationFailedError
|
103
100
|
end
|
104
101
|
end
|
105
102
|
|
106
103
|
# Delete a domain entry.
|
107
|
-
|
108
|
-
#
|
104
|
+
|
105
|
+
# Returns a hash of the deleted domain entry, e.g.
|
106
|
+
# { "name" => "sigfig.com", "nameServer" => ["ns66.dnsmadeeasy.com", "ns99.dnsmadeeasy.com"], "gtdEnabled" => true }
|
109
107
|
def delete_domain!(domain)
|
110
|
-
|
108
|
+
execute_with_caution :domain => domain do
|
109
|
+
description = describe_domain(domain)
|
111
110
|
response = RestClient.delete request_url(:path => "#{domain}"), headers
|
112
|
-
return
|
113
|
-
rescue RestClient::ResourceNotFound => e
|
114
|
-
raise DnsMadeEasy::UnknownDomainError, domain
|
115
|
-
rescue RestClient::BadRequest => e
|
116
|
-
error = JSON.parse(e.http_body)
|
117
|
-
raise DnsMadeEasy::RequestFailedError, error["error"][0]
|
118
|
-
rescue RestClient::Forbidden => e
|
119
|
-
raise DnsMadeEasy::AuthorizationFailedError
|
111
|
+
return description
|
120
112
|
end
|
121
113
|
end
|
122
114
|
|
123
115
|
# Describe a domain entry.
|
124
|
-
|
125
|
-
#
|
116
|
+
|
117
|
+
# Returns a hash of the domain entry, e.g.
|
118
|
+
# { "name" => "sigfig.com", "nameServer" => ["ns66.dnsmadeeasy.com", "ns99.dnsmadeeasy.com"], "gtdEnabled" => true }
|
126
119
|
def describe_domain(domain)
|
127
|
-
|
120
|
+
execute_with_caution :domain => domain do
|
128
121
|
response = RestClient.get request_url(:path => "#{domain}"), headers
|
129
122
|
return JSON.parse(response)
|
130
|
-
rescue RestClient::ResourceNotFound => e
|
131
|
-
raise DnsMadeEasy::UnknownDomainError, domain
|
132
|
-
rescue RestClient::Forbidden => e
|
133
|
-
raise DnsMadeEasy::AuthorizationFailedError
|
134
123
|
end
|
135
124
|
end
|
136
125
|
|
137
126
|
# List records for a domain.
|
138
|
-
#
|
139
|
-
#
|
127
|
+
#
|
128
|
+
# The filter parameter allows you to list a list a subset of records filtered by a criteria. Available filters:
|
129
|
+
# * { :name => "www" }: Lists all entries for host "www"
|
130
|
+
# * { :type => :A }: Lists all A records
|
131
|
+
# * { :gtdLocation => :EUROPE } List all entries for EUROPE Traffic Director
|
132
|
+
#
|
133
|
+
# Returns an array of hashes, each hash representing a dns entry, e.g.
|
134
|
+
# [
|
135
|
+
# { "name" => "", "type" => "A", "data" => "127.0.0.1", "ttl" => 7200, "id" => 12345, "gtdLocation" => "DEFAULT" }
|
136
|
+
# { "name" => "www", "type" => "CNAME", data => "sigfig.com.", "ttl" => 7200, id => 23456, "gtdLocation" => "DEFAULT" }
|
137
|
+
# ]
|
140
138
|
def list_records(domain, filter={})
|
141
|
-
|
139
|
+
execute_with_caution :domain => domain do
|
142
140
|
response = RestClient.get request_url(:path => "#{domain}/records", :query => filter), headers
|
143
141
|
return JSON.parse(response)
|
144
|
-
rescue RestClient::ResourceNotFound => e
|
145
|
-
raise DnsMadeEasy::UnknownDomainError, domain
|
146
|
-
rescue RestClient::Forbidden => e
|
147
|
-
raise DnsMadeEasy::AuthorizationFailedError
|
148
142
|
end
|
149
143
|
end
|
150
144
|
|
151
|
-
# Create a new dns record
|
152
|
-
#
|
145
|
+
# Create a new dns record.
|
146
|
+
#
|
147
|
+
# Record should be a hash with the following values:
|
153
148
|
#
|
154
|
-
# :name =>
|
155
|
-
# :type =>
|
156
|
-
# :data =>
|
157
|
-
# :gtdLocation =>
|
158
|
-
# :ttl =>
|
149
|
+
# :name => Hostname. E.g. www, or empty string for root domain
|
150
|
+
# :type => Record type. E.g. :A, :CNAME, :MX, :TXT, :SRV, :NS, :AAAA, :HTTPRED, :PTR
|
151
|
+
# :data => Public name. E.g. "66.88.99.44" or "ec2-gibberish.amazonaws.com."
|
152
|
+
# :gtdLocation => Global Traffic Director location. Values: DEFAULT, US_EAST, US_WEST, EUROPE (optional, defaults to DEFAULT)
|
153
|
+
# :ttl => Time to live. The amount of time a record will be cached before being refreshed. E.g. 300
|
159
154
|
#
|
160
|
-
#
|
161
|
-
#
|
162
|
-
#
|
163
|
-
# :
|
164
|
-
#
|
155
|
+
# Here's a list of possible data values, with the record type they are used with:
|
156
|
+
# * A: <host IP>
|
157
|
+
# * AAAA: <IPv6 host IP>
|
158
|
+
# * CNAME: <target name>
|
159
|
+
# * HTTPRED: <redirection URL>
|
160
|
+
# * MX: <priority> <target name>
|
161
|
+
# * NS: <name server>
|
162
|
+
# * PTR: <target name>
|
163
|
+
# * SRV: <priority> <weight> <port> <target name>
|
164
|
+
# * TXT: <text value>
|
165
165
|
#
|
166
|
-
#
|
167
|
-
#
|
166
|
+
# N.B. for CNAME, MX, NS, PTR, and SRV records, the domain name of the dns record is automatically
|
167
|
+
# appended to the given data unless the data ends with a "." So, to map, say mail to mail.google.com,
|
168
|
+
# use "mail.google.com." as the data value. By the same logic, to map "www.sigfig.com" to, say, "server1.sigfig.com",
|
169
|
+
# just use "server1" as the data value or "server1.sigfig.com."; don't give "server1.sigfig.com" because that'll
|
170
|
+
# essentially resolve to server1.sigfig.com.sigfig.com.
|
171
|
+
#
|
172
|
+
# Returns a hash of the newly created dns entry, e.g.
|
173
|
+
# { "name" => "www", "type" => "CNAME", data => "sigfig.com.", "ttl" => 7200, id => 23456, "gtdLocation" => "DEFAULT" }
|
168
174
|
def create_record!(domain, record)
|
169
175
|
validate_record(record)
|
170
176
|
request_data = {
|
171
177
|
:gtdLocation => "DEFAULT"
|
172
178
|
}.merge(record)
|
173
|
-
|
179
|
+
execute_with_caution :domain => domain do
|
174
180
|
response = RestClient.post request_url(:path => "#{domain}/records"), request_data.to_json, headers(:content_type => "application/json")
|
175
181
|
return JSON.parse(response)
|
176
|
-
rescue RestClient::BadRequest => e
|
177
|
-
raise DnsMadeEasy::InvalidRecordError, e.http_body
|
178
|
-
rescue RestClient::ResourceNotFound => e
|
179
|
-
raise DnsMadeEasy::UnknownDomainError, domain
|
180
|
-
rescue RestClient::Forbidden => e
|
181
|
-
raise DnsMadeEasy::AuthorizationFailedError
|
182
182
|
end
|
183
183
|
end
|
184
184
|
|
185
185
|
# Delete a dns record.
|
186
|
-
#
|
187
|
-
#
|
186
|
+
#
|
187
|
+
# Returns a hash of the deleted dns entry, e.g.
|
188
|
+
# { "name" => "", "type" => "A", "data" => "127.0.0.1", "ttl" => 7200, "id" => 12345, "gtdLocation" => "DEFAULT" }
|
188
189
|
def delete_record!(domain, record_id)
|
189
|
-
|
190
|
+
execute_with_caution :domain => domain, :record => record_id do
|
191
|
+
record = describe_record(domain, record_id)
|
190
192
|
response = RestClient.delete request_url(:path => "#{domain}/records/#{record_id}"), headers
|
191
|
-
return
|
192
|
-
|
193
|
-
|
194
|
-
|
195
|
-
|
193
|
+
return record
|
194
|
+
end
|
195
|
+
end
|
196
|
+
|
197
|
+
# Delete multiple records for a domain.
|
198
|
+
#
|
199
|
+
# The filter parameter allows you to list a list a subset of records filtered by a criteria. Available filters:
|
200
|
+
# * { :name => "www" }: Lists all entries for host "www"
|
201
|
+
# * { :type => :A }: Lists all A records
|
202
|
+
# * { :gtdLocation => :EUROPE } List all entries for EUROPE Traffic Director
|
203
|
+
#
|
204
|
+
# N.B. Given that there are limits to the number of api requests, the amoticity of this action is not guaranteed.
|
205
|
+
# This means that it is possible under certain circumstances that not all records that match the given criteria
|
206
|
+
# will be deleted.
|
207
|
+
#
|
208
|
+
# Returns an array of hashes, each hash representing a deleted dns entry, e.g.
|
209
|
+
# [
|
210
|
+
# { "name" => "", "type" => "A", "data" => "127.0.0.1", "ttl" => 7200, "id" => 12345, "gtdLocation" => "DEFAULT" }
|
211
|
+
# { "name" => "www", "type" => "CNAME", data => "sigfig.com.", "ttl" => 7200, id => 23456, "gtdLocation" => "DEFAULT" }
|
212
|
+
# ]
|
213
|
+
# An empty array is returned if no deletions are made.
|
214
|
+
def delete_records!(domain, filter={})
|
215
|
+
record_list = list_records(domain, filter)
|
216
|
+
unless record_list.empty?
|
217
|
+
if record_list.size == 1
|
218
|
+
delete_record!(domain, record_list[0]["id"])
|
219
|
+
elsif requests_remaining >= record_list.size
|
220
|
+
record_list.each do |record|
|
221
|
+
delete_record!(domain, record["id"])
|
222
|
+
end
|
223
|
+
else
|
224
|
+
raise DnsMadeEasy::BadRequestError, "Not enough requests remaining to complete the operation"
|
225
|
+
end
|
196
226
|
end
|
227
|
+
return record_list
|
197
228
|
end
|
198
229
|
|
199
|
-
# Update an existing dns record
|
200
|
-
#
|
201
|
-
#
|
230
|
+
# Update an existing dns record.
|
231
|
+
#
|
232
|
+
# Record should be a hash with the following values:
|
233
|
+
#
|
234
|
+
# :name => Hostname. E.g. www, or empty string for root domain
|
235
|
+
# :type => Record type. E.g. :A, :CNAME, :MX, :TXT, :SRV, :NS, :AAAA, :HTTPRED, :PTR
|
236
|
+
# :data => Public name. E.g. "66.88.99.44" or "ec2-gibberish.amazonaws.com."
|
237
|
+
# :gtdLocation => Global Traffic Director location. Values: DEFAULT, US_EAST, US_WEST, EUROPE (optional, defaults to DEFAULT)
|
238
|
+
# :ttl => Time to live. The amount of time a record will be cached before being refreshed. E.g. 300
|
239
|
+
#
|
240
|
+
# Here's a list of possible data values, with the record type they are used with:
|
241
|
+
# * A: <host IP>
|
242
|
+
# * AAAA: <IPv6 host IP>
|
243
|
+
# * CNAME: <target name>
|
244
|
+
# * HTTPRED: <redirection URL>
|
245
|
+
# * MX: <priority> <target name>
|
246
|
+
# * NS: <name server>
|
247
|
+
# * PTR: <target name>
|
248
|
+
# * SRV: <priority> <weight> <port> <target name>
|
249
|
+
# * TXT: <text value>
|
250
|
+
#
|
251
|
+
# N.B. for CNAME, MX, NS, PTR, and SRV records, the domain name of the dns record is automatically
|
252
|
+
# appended to the given data unless the data ends with a "." So, to map, say mail to mail.google.com,
|
253
|
+
# use "mail.google.com." as the data value. By the same logic, to map "www.sigfig.com" to, say, "server1.sigfig.com",
|
254
|
+
# just use "server1" as the data value or "server1.sigfig.com."; don't give "server1.sigfig.com" because that'll
|
255
|
+
# essentially resolve to server1.sigfig.com.sigfig.com.
|
256
|
+
#
|
257
|
+
# Returns a hash of the newly updated dns entry, e.g.
|
258
|
+
# { "name" => "www", "type" => "CNAME", data => "sigfig.com.", "ttl" => 7200, id => 23456, "gtdLocation" => "DEFAULT" }
|
202
259
|
def update_record!(domain, record_id, record)
|
203
|
-
|
260
|
+
validate_record(record)
|
261
|
+
execute_with_caution :domain => domain, :record => record_id do
|
204
262
|
response = RestClient.put request_url(:path => "#{domain}/records/#{record_id}"), record.to_json, headers(:content_type => "application/json")
|
205
263
|
return describe_record(domain, record_id)
|
206
|
-
rescue RestClient::BadRequest => e
|
207
|
-
raise DnsMadeEasy::InvalidRecordError, e.http_body
|
208
|
-
rescue RestClient::ResourceNotFound => e
|
209
|
-
raise DnsMadeEasy::UnknownRecordError.new(domain, record_id)
|
210
|
-
rescue RestClient::Forbidden => e
|
211
|
-
raise DnsMadeEasy::AuthorizationFailedError
|
212
264
|
end
|
213
265
|
end
|
214
266
|
|
215
267
|
# Describe an existing dns record.
|
268
|
+
#
|
216
269
|
# Returns a hash of the dns entry.
|
217
|
-
#
|
270
|
+
# { "name" => "www", "type" => "CNAME", data => "sigfig.com.", "ttl" => 7200, id => 23456, "gtdLocation" => "DEFAULT" }
|
218
271
|
def describe_record(domain, record_id)
|
219
|
-
|
272
|
+
execute_with_caution :domain => domain, :record => record_id do
|
220
273
|
response = RestClient.get request_url(:path => "#{domain}/records/#{record_id}"), headers
|
221
274
|
return JSON.parse(response)
|
222
|
-
|
223
|
-
|
224
|
-
|
225
|
-
|
275
|
+
end
|
276
|
+
end
|
277
|
+
|
278
|
+
# Return the umber of api requests remaining.
|
279
|
+
def requests_remaining
|
280
|
+
begin
|
281
|
+
execute_with_caution do
|
282
|
+
response = RestClient.get request_url, headers
|
283
|
+
return response.headers[:x_dnsme_requestsremaining].to_i if response.headers.has_key?(:x_dnsme_requestsremaining)
|
284
|
+
end
|
285
|
+
rescue DnsMadeEasy::BadRequestError => e
|
286
|
+
return 0
|
226
287
|
end
|
227
288
|
end
|
228
289
|
|
@@ -238,8 +299,14 @@ module DnsMadeEasy
|
|
238
299
|
|
239
300
|
# check record types
|
240
301
|
acceptable_types = [:A, :CNAME, :MX, :TXT, :SRV, :NS, :AAAA, :HTTPRED, :PTR]
|
241
|
-
raise DnsMadeEasy::InvalidRecordError, "Invalid record type #{record[:type]}" unless acceptable_types.include?(record[:type])
|
302
|
+
raise DnsMadeEasy::InvalidRecordError, "Invalid record type #{record[:type]}" unless acceptable_types.include?(record[:type].to_sym)
|
242
303
|
|
304
|
+
# check gtd location
|
305
|
+
acceptable_location = [:DEFAULT, :US_EAST, :US_WEST, :EUROPE]
|
306
|
+
if record.has_key?(:gtdLocation) && acceptable_location.include?(record[:gtdLocation].to_sym)
|
307
|
+
raise DnsMadeEasy::InvalidRecordError, "Invalid gtd location #{record[:gtdLocation]}"
|
308
|
+
end
|
309
|
+
|
243
310
|
# check non empty fields
|
244
311
|
non_empty_fields = [:ttl, :data]
|
245
312
|
non_empty_fields.each do |field|
|
@@ -271,5 +338,19 @@ module DnsMadeEasy
|
|
271
338
|
}
|
272
339
|
return default_headers.merge( more_headers )
|
273
340
|
end
|
341
|
+
|
342
|
+
# Execute a block and handle all the errors it may throw
|
343
|
+
def execute_with_caution(namespace={})
|
344
|
+
begin
|
345
|
+
return yield
|
346
|
+
rescue RestClient::BadRequest => e
|
347
|
+
error = JSON.parse(e.http_body)
|
348
|
+
raise DnsMadeEasy::BadRequestError, error["error"][0]
|
349
|
+
rescue RestClient::ResourceNotFound => e
|
350
|
+
raise DnsMadeEasy::ResourceNotFoundError, namespace
|
351
|
+
rescue RestClient::Forbidden => e
|
352
|
+
raise DnsMadeEasy::AuthorizationFailedError
|
353
|
+
end
|
354
|
+
end
|
274
355
|
end
|
275
356
|
end
|
@@ -10,31 +10,16 @@ module DnsMadeEasy
|
|
10
10
|
end
|
11
11
|
end
|
12
12
|
|
13
|
-
# Error raised when
|
14
|
-
|
15
|
-
|
16
|
-
super "Domain #{domain} does not exist."
|
17
|
-
end
|
18
|
-
end
|
19
|
-
|
20
|
-
# Error raised when an invalid domain is being created
|
21
|
-
class InvalidDomainNameError < RequestFailedError
|
22
|
-
def initialize(domain)
|
23
|
-
super "Domain #{domain} is not valid."
|
24
|
-
end
|
25
|
-
end
|
26
|
-
|
27
|
-
# Error raised when a duplicate domain is being created
|
28
|
-
class DuplicateDomainError < RequestFailedError
|
29
|
-
def initialize(domain)
|
30
|
-
super "Domain #{domain} already exists."
|
31
|
-
end
|
13
|
+
# Error raised when the request is bad. Likely causes are exceeding api limits,
|
14
|
+
# creating an existing domain/record, or creating a mal-formed record.
|
15
|
+
class BadRequestError < RequestFailedError
|
32
16
|
end
|
33
17
|
|
34
|
-
# Error raised when an unknown
|
35
|
-
class
|
36
|
-
def initialize(
|
37
|
-
|
18
|
+
# Error raised when actions are performed against an unknown resource (domain or record)
|
19
|
+
class ResourceNotFoundError < RequestFailedError
|
20
|
+
def initialize(resource)
|
21
|
+
flattened_resource = resource.to_a.map { |x| "#{x[0]}: #{x[1]}" }.join(", ")
|
22
|
+
super "Could not find resource - #{flattened_resource}"
|
38
23
|
end
|
39
24
|
end
|
40
25
|
|
metadata
CHANGED
@@ -1,12 +1,13 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: dnsmadeeasy-api
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
hash:
|
4
|
+
hash: 49
|
5
5
|
prerelease:
|
6
6
|
segments:
|
7
7
|
- 0
|
8
8
|
- 9
|
9
|
-
|
9
|
+
- 5
|
10
|
+
version: 0.9.5
|
10
11
|
platform: ruby
|
11
12
|
authors:
|
12
13
|
- Nitesh Goel
|
@@ -14,7 +15,7 @@ autorequire:
|
|
14
15
|
bindir: bin
|
15
16
|
cert_chain: []
|
16
17
|
|
17
|
-
date: 2011-07-
|
18
|
+
date: 2011-07-07 00:00:00 Z
|
18
19
|
dependencies:
|
19
20
|
- !ruby/object:Gem::Dependency
|
20
21
|
name: rest-client
|
@@ -73,7 +74,7 @@ dependencies:
|
|
73
74
|
type: :development
|
74
75
|
version_requirements: *id004
|
75
76
|
description: Ruby client for DNSMadeEasy API.
|
76
|
-
email: nitesh@
|
77
|
+
email: nitesh@sigfig.com
|
77
78
|
executables:
|
78
79
|
- dme
|
79
80
|
extensions: []
|