dnsmadeeasy-api 0.9 → 0.9.5

Sign up to get free protection for your applications and to get access to all the features.
@@ -12,8 +12,8 @@ Ruby client for DNSMadeEasy API.
12
12
  require "rubygems"
13
13
  require "dnsmadeeasy/api"
14
14
 
15
- api_key = <your dnsmadeeasy api key>
16
- secret_ket = <your dnsmadeeasy secret key>
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@wikinvest.com"
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
- if response.is_a?(TrueClass) || response.is_a?(FalseClass)
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
- else
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
- unless force
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
- unless force
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
- unless force
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
@@ -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-06}
9
+ s.date = %q{2011-07-07}
10
10
  s.description = %q{Ruby client for DNSMadeEasy API.}
11
- s.email = %q{nitesh@wikinvest.com}
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}]
@@ -19,8 +19,8 @@ Ruby client for DNSMadeEasy API.
19
19
  require "rubygems"
20
20
  require "dnsmadeeasy/api"
21
21
 
22
- api_key = <your dnsmadeeasy api key>
23
- secret_ket = <your dnsmadeeasy secret key>
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
- # Returns an array of domain names in the account.
64
- # Throws DnsMadeEasy::AuthorizationFailedError
69
+ #
70
+ # Returns an array of domain names in the account, e.g.
71
+ # ["sigfig.com", "wikinvest.com"]
65
72
  def list_domains
66
- begin
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
- # Returns true or throws an exception.
77
- # Throws DnsMadeEasy::AuthorizationFailedError
81
+ #
82
+ # Returns an array of domains deleted, e.g.
83
+ # ["sigfig.com", "wikinvest.com"]
78
84
  def delete_domains!
79
- begin
85
+ execute_with_caution do
86
+ domains = list_domains
80
87
  response = RestClient.delete request_url, headers
81
- return true
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
- # Returns a hash of the newly created domain entry.
89
- # Throws DnsMadeEasy::InvalidDomainNameError, DnsMadeEasy::DuplicateDomainError, or DnsMadeEasy::AuthorizationFailedError
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
- begin
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
- # Returns true or throws an exception.
108
- # Throws DnsMadeEasy::UnknownDomainError, DnsMadeEasy::RequestFailedError, or DnsMadeEasy::AuthorizationFailedError
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
- begin
108
+ execute_with_caution :domain => domain do
109
+ description = describe_domain(domain)
111
110
  response = RestClient.delete request_url(:path => "#{domain}"), headers
112
- return true
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
- # Returns a hash of the domain entry.
125
- # Throws DnsMadeEasy::UnknownDomainError or DnsMadeEasy::AuthorizationFailedError
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
- begin
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
- # Returns an array of hashes, each hash representing a dns entry.
139
- # Throws DnsMadeEasy::UnknownDomainError or DnsMadeEasy::AuthorizationFailedError
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
- begin
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
- # record should be a hash with the following values:
145
+ # Create a new dns record.
146
+ #
147
+ # Record should be a hash with the following values:
153
148
  #
154
- # :name => hostname, e.g. www
155
- # :type => e.g. :A, :CNAME, :MX, :TXT, :SRV, :NS, :AAAA, :HTTPRED, :PTR
156
- # :data => publicname, e.g. "66.88.99.44" or "ec2-gibberish.amazonaws.com"
157
- # :gtdLocation => "DEFAULT", (optional, defaults to DEFAULT)
158
- # :ttl => time to live, e.g. 300
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
- # for :CNAME record type, the domain name is automatically added to the entry unless
161
- # the :data field ends in a .
162
- # e.g., for domain sigfig.com,
163
- # :data => "blog.google.com" for a cname entry resolves to blog.google.com.sigfig.com
164
- # but :data => "blog.google.com." resolves to blog.google.com.
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
- # Returns a hash of the newly created dns entry.
167
- # Throws DnsMadeEasy::InvalidRecordError, DnsMadeEasy::UnknownDomainError, or DnsMadeEasy::AuthorizationFailedError
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
- begin
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
- # Returns true or throws an exception.
187
- # Throws DnsMadeEasy::UnknownRecordError, or DnsMadeEasy::AuthorizationFailedError
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
- begin
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 true
192
- rescue RestClient::ResourceNotFound => e
193
- raise DnsMadeEasy::UnknownRecordError.new(domain, record_id)
194
- rescue RestClient::Forbidden => e
195
- raise DnsMadeEasy::AuthorizationFailedError
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
- # Returns the latest hash of the dns entry.
201
- # Throws DnsMadeEasy::InvalidRecordError, DnsMadeEasy::UnknownRecordError, or DnsMadeEasy::AuthorizationFailedError
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
- begin
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
- # Throws DnsMadeEasy::UnknownRecordError, or DnsMadeEasy::AuthorizationFailedError
270
+ # { "name" => "www", "type" => "CNAME", data => "sigfig.com.", "ttl" => 7200, id => 23456, "gtdLocation" => "DEFAULT" }
218
271
  def describe_record(domain, record_id)
219
- begin
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
- rescue RestClient::ResourceNotFound => e
223
- raise DnsMadeEasy::UnknownRecordError.new(domain, record_id)
224
- rescue RestClient::Forbidden => e
225
- raise DnsMadeEasy::AuthorizationFailedError
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 actions are performed on an domain not listed in the account
14
- class UnknownDomainError < RequestFailedError
15
- def initialize(domain)
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 record is being modified or deleted
35
- class UnknownRecordError < RequestFailedError
36
- def initialize(domain, record_id)
37
- super "Record id #{record_id} and/or domain #{domain} does not exist"
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: 25
4
+ hash: 49
5
5
  prerelease:
6
6
  segments:
7
7
  - 0
8
8
  - 9
9
- version: "0.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-06 00:00:00 Z
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@wikinvest.com
77
+ email: nitesh@sigfig.com
77
78
  executables:
78
79
  - dme
79
80
  extensions: []