dnsmadeeasy-api 0.9

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.
@@ -0,0 +1,6 @@
1
+ Manifest
2
+ README.rdoc
3
+ Rakefile
4
+ bin/dme
5
+ lib/dnsmadeeasy/api.rb
6
+ lib/dnsmadeeasy/exceptions.rb
@@ -0,0 +1,37 @@
1
+ =begin rdoc
2
+ = DnsMadeEasy/API
3
+
4
+ Ruby client for DNSMadeEasy API.
5
+
6
+ == Installation
7
+
8
+ # gem install environment
9
+
10
+ == Usage
11
+
12
+ require "rubygems"
13
+ require "dnsmadeeasy/api"
14
+
15
+ api_key = <your dnsmadeeasy api key>
16
+ secret_ket = <your dnsmadeeasy secret key>
17
+ api = DnsMadeEasy::Api(api_key, secret_key)
18
+ api.list_records "sigfig.com"
19
+
20
+ To run in sandbox mode (you need an account and api key at sandbox.dnsmadeeasy.com).
21
+ This is a great way to test your application without changing your production DNS entries.
22
+
23
+ api = DnsMadeEasy::Api(api_key, secret_key, true)
24
+ api.list_records "sigfig.com"
25
+
26
+ == Command line tool
27
+
28
+ The client comes with a command line tool "dme". Use "dme --help" to see how to use the command.
29
+ The command line tool requires that your api credentials be stored in /etc/dnsmadeeasy/api.keys as
30
+ api_key=<api_key>
31
+ secret_key=<secret_key>
32
+
33
+ The command line tool also allows the running of queries in the sandbox mode. To do so, create
34
+ /etc/dnsmadeeasy/api_sandbox.keys with your sandbox api key and secret key and use the --sandbox option
35
+ with every command.
36
+
37
+ =end
@@ -0,0 +1,17 @@
1
+ require "rubygems"
2
+ require "rake"
3
+ require "echoe"
4
+
5
+ Echoe.new("dnsmadeeasy-api", "0.9") do |p|
6
+ p.description = "Ruby client for DNSMadeEasy API."
7
+ p.summary = "Ruby client for DNSMadeEasy API."
8
+ p.url = "http://rubygems.org/gems/dnsmadeeasy-api"
9
+ p.author = "Nitesh Goel"
10
+ p.email = "nitesh@wikinvest.com"
11
+ p.ignore_pattern = ["tmp/*", "script/*"]
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
+ p.runtime_dependencies = ["rest-client", "json"]
14
+ p.development_dependencies = ["rake", "echoe"]
15
+ end
16
+
17
+ Dir["#{File.dirname(__FILE__)}/tasks/*.rake"].sort.each { |ext| load ext }
data/bin/dme ADDED
@@ -0,0 +1,244 @@
1
+ #!/usr/bin/env ruby
2
+ require "rubygems"
3
+ require "dnsmadeeasy/api"
4
+ require "json"
5
+ require "optparse"
6
+
7
+ class Array
8
+ def to_s
9
+ join(", ")
10
+ end
11
+ end
12
+
13
+ module DnsMadeEasy
14
+ class Printer
15
+ attr_accessor :json
16
+
17
+ def initialize(json=false)
18
+ @json = json
19
+ end
20
+
21
+ def help_text
22
+ valid_commands = {
23
+ "list-domains" => "List all domains in the account",
24
+ "delete-domains" => "Delete all domains in the account",
25
+ "create-domain" => "Create a new domain entry",
26
+ "delete-domain" => "Delete a domain entry",
27
+ "describe-domain" => "Describe a domain entry",
28
+ "list-records" => "List records for a domain",
29
+ "create-record" => "Create a new dns record",
30
+ "delete-record" => "Delete a dns record",
31
+ "update-record" => "Update an existing dns record",
32
+ "describe-record" => "Describe an existing dns record"
33
+ }
34
+ help = "Usage: dme command [options]"
35
+ help << "\nValid commands\n"
36
+ valid_commands.each do |name, description|
37
+ help << "\t#{name.ljust(18)}=> #{description}\n"
38
+ end
39
+ return help
40
+ end
41
+
42
+ def show_error(message)
43
+ if @json
44
+ output = { "error" => message }
45
+ puts output.to_json
46
+ else
47
+ puts "ERROR: #{message}"
48
+ end
49
+ exit 1
50
+ end
51
+
52
+ def say_bye(message)
53
+ puts message
54
+ exit 0
55
+ end
56
+
57
+ def show_response(response)
58
+ if @json
59
+ if response.is_a?(TrueClass) || response.is_a?(FalseClass)
60
+ response = { :success => response }
61
+ end
62
+ puts response.to_json
63
+ elsif response.is_a?(TrueClass) || response.is_a?(FalseClass)
64
+ if response
65
+ puts "Done"
66
+ else
67
+ puts "Not done"
68
+ end
69
+ elsif response.instance_of?(Array) && response[0].instance_of?(String)
70
+ response.each do |x|
71
+ puts x
72
+ end
73
+ else
74
+ table_fields = {}
75
+ response = [response] if response.instance_of?(Hash)
76
+ response.each do |x|
77
+ x.each do |key, value|
78
+ table_fields[key] ||= []
79
+ table_fields[key] << value
80
+ end
81
+ end
82
+ max_widths = {}
83
+ table_fields.each do |key, values|
84
+ max_width = values.inject(key.to_s.length) { |length, s| [length, s.to_s.length].max }
85
+ max_widths[key] = max_width
86
+ end
87
+ #puts max_widths.inspect
88
+ row = []
89
+ table_fields.to_a.each do |column|
90
+ row[0] ||= []
91
+ row[0] << column[0].to_s.upcase.ljust(max_widths[column[0]])
92
+ column[1].each_index do |x|
93
+ row[x+1] ||= []
94
+ row[x+1] << column[1][x].to_s.ljust(max_widths[column[0]])
95
+ end
96
+ end
97
+ #puts row.inspect
98
+ #exit
99
+ row.map! { |x| "| #{x.join(' | ')} |" }
100
+ rows = row.length
101
+ row_length = row[0].length
102
+ divider = "-"*row_length
103
+ row.each_index do |x|
104
+ if x.zero?
105
+ puts divider
106
+ puts row[x]
107
+ puts divider
108
+ elsif x == rows-1
109
+ puts row[x]
110
+ puts divider
111
+ else
112
+ puts row[x]
113
+ end
114
+ end
115
+ end
116
+ end
117
+ end
118
+ end
119
+
120
+ printer = DnsMadeEasy::Printer.new
121
+
122
+ # process input
123
+ domain = nil
124
+ options = {}
125
+ force = false
126
+ record_id = nil
127
+ sandbox = false
128
+ optparse = OptionParser.new do |opts|
129
+ opts.banner = printer.help_text + "\nOptions\n"
130
+ opts.on("-f", "--force", "Force operation") do
131
+ force = true
132
+ end
133
+ opts.on("-j", "--json", "Format output as json") do
134
+ printer.json = true
135
+ end
136
+ opts.on("-s", "--sandbox", "Run the sandbox api") do
137
+ sandbox = true
138
+ end
139
+ opts.on("-d", "--domain DOMAIN", "Domain Name") do |d|
140
+ domain = d
141
+ end
142
+ opts.on("-n", "--name HOSTNAME", "Hostname") do |h|
143
+ options[:name] = h
144
+ end
145
+ opts.on("-v", "--value VALUE", "The destination of the entry (IP/relative hostname/hostname)") do |v|
146
+ options[:data] = v
147
+ end
148
+ opts.on("-g", "--gtd GTD", "GTD Location") do |g|
149
+ options[:gtdLocation] = g
150
+ end
151
+ opts.on("-t", "--type TYPE", "The type of dns record") do |t|
152
+ options[:type] = t.upcase.to_sym
153
+ end
154
+ opts.on("-l", "--ttl TTL", "Time to live") do |l|
155
+ options[:ttl] = l
156
+ end
157
+ opts.on("-r", "--record RECORD", "Record id") do |r|
158
+ record_id = r
159
+ end
160
+ end
161
+
162
+ optparse.parse!
163
+
164
+ auth_file = sandbox ? "/etc/dnsmadeeasy/api_sandbox.keys" : "/etc/dnsmadeeasy/api.keys"
165
+ begin
166
+ auth_contents = File.read(auth_file)
167
+ auth_hash = Hash[auth_contents.split("\n").map { |x| x.split("=") }]
168
+ api_key = auth_hash["api_key"]
169
+ secret_key = auth_hash["secret_key"]
170
+ if api_key.nil? || secret_key.nil?
171
+ throw new StandardError
172
+ end
173
+ rescue StandardError => e
174
+ puts e.inspect
175
+ printer.show_error "Please create a file #{auth_file} with the following information\napi_key=<your api key>\nsecret_key=<your secret key>"
176
+ end
177
+
178
+ api = DnsMadeEasy::Api.new(api_key, secret_key, sandbox)
179
+
180
+ command = ARGV.shift
181
+
182
+ begin
183
+ case command
184
+ when "list-domains"
185
+ printer.show_response api.list_domains
186
+ when "delete-domains"
187
+ unless force
188
+ puts "The following domains are listed in your account:"
189
+ printer.show_response api.list_domains
190
+ puts "Are you sure you want to delete all domains? (yes/no)"
191
+ response = STDIN.gets.chomp.downcase
192
+ unless response.downcase == "yes"
193
+ printer.say_bye "Domains not deleted"
194
+ end
195
+ end
196
+ printer.show_response api.delete_domains!
197
+ when "create-domain"
198
+ printer.show_error "Please specify a domain name" if domain.nil?
199
+ printer.show_response api.create_domain!(domain)
200
+ when "delete-domain"
201
+ printer.show_error "Please specify a domain name" if domain.nil?
202
+ unless force
203
+ puts "Are you sure you want to delete #{domain}? (yes/no)"
204
+ response = STDIN.gets.chomp.downcase
205
+ unless response.downcase == "yes"
206
+ printer.say_bye "Domain #{domain} not deleted"
207
+ end
208
+ end
209
+ printer.show_response api.delete_domain!(domain)
210
+ when "describe-domain"
211
+ printer.show_error "Please specify a domain name" if domain.nil?
212
+ printer.show_response api.describe_domain(domain)
213
+ when "list-records"
214
+ printer.show_error "Please specify a domain name" if domain.nil?
215
+ printer.show_response api.list_records(domain, options)
216
+ when "create-record"
217
+ printer.show_error "Please specify a domain name" if domain.nil?
218
+ printer.show_response api.create_record!(domain, options)
219
+ when "delete-record"
220
+ printer.show_error "Please specify a domain name" if domain.nil?
221
+ printer.show_response api.describe_record(domain, record_id)
222
+ unless force
223
+ puts "Are you sure you want to delete this record? (yes/no)"
224
+ response = STDIN.gets.chomp.downcase
225
+ unless response.downcase == "yes"
226
+ printer.say_bye "Record not deleted"
227
+ end
228
+ end
229
+ printer.show_response api.delete_record!(domain, record_id)
230
+ when "update-record"
231
+ printer.show_error "Please specify a domain name" if domain.nil?
232
+ printer.show_response api.update_record!(domain, record_id, options)
233
+ when "describe-record"
234
+ printer.show_error "Please specify a domain name" if domain.nil?
235
+ printer.show_response api.describe_record(domain, record_id)
236
+ when "help"
237
+ help_for_command = ARGV.shift
238
+
239
+ else
240
+ printer.show_error "Please enter a valid command"
241
+ end
242
+ rescue DnsMadeEasy::RequestFailedError => e
243
+ printer.show_error e.message
244
+ end
@@ -0,0 +1,46 @@
1
+ # -*- encoding: utf-8 -*-
2
+
3
+ Gem::Specification.new do |s|
4
+ s.name = %q{dnsmadeeasy-api}
5
+ s.version = "0.9"
6
+
7
+ s.required_rubygems_version = Gem::Requirement.new(">= 1.2") if s.respond_to? :required_rubygems_version=
8
+ s.authors = [%q{Nitesh Goel}]
9
+ s.date = %q{2011-07-06}
10
+ s.description = %q{Ruby client for DNSMadeEasy API.}
11
+ s.email = %q{nitesh@wikinvest.com}
12
+ s.executables = [%q{dme}]
13
+ s.extra_rdoc_files = [%q{README.rdoc}, %q{bin/dme}, %q{lib/dnsmadeeasy/api.rb}, %q{lib/dnsmadeeasy/exceptions.rb}]
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}]
15
+ s.homepage = %q{http://rubygems.org/gems/dnsmadeeasy-api}
16
+ s.post_install_message = %q{Create /etc/dnsmadeeasy/api.keys and/or /etc/dnsmadeeasy/api_sandbox.keys with the following information
17
+ api_key=<your api key>
18
+ secret_key=<your secret key>
19
+ to use the dme binary.}
20
+ s.rdoc_options = [%q{--line-numbers}, %q{--inline-source}, %q{--title}, %q{Dnsmadeeasy-api}, %q{--main}, %q{README.rdoc}]
21
+ s.require_paths = [%q{lib}]
22
+ s.rubyforge_project = %q{dnsmadeeasy-api}
23
+ s.rubygems_version = %q{1.8.5}
24
+ s.summary = %q{Ruby client for DNSMadeEasy API.}
25
+
26
+ if s.respond_to? :specification_version then
27
+ s.specification_version = 3
28
+
29
+ if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
30
+ s.add_runtime_dependency(%q<rest-client>, [">= 0"])
31
+ s.add_runtime_dependency(%q<json>, [">= 0"])
32
+ s.add_development_dependency(%q<rake>, [">= 0"])
33
+ s.add_development_dependency(%q<echoe>, [">= 0"])
34
+ else
35
+ s.add_dependency(%q<rest-client>, [">= 0"])
36
+ s.add_dependency(%q<json>, [">= 0"])
37
+ s.add_dependency(%q<rake>, [">= 0"])
38
+ s.add_dependency(%q<echoe>, [">= 0"])
39
+ end
40
+ else
41
+ s.add_dependency(%q<rest-client>, [">= 0"])
42
+ s.add_dependency(%q<json>, [">= 0"])
43
+ s.add_dependency(%q<rake>, [">= 0"])
44
+ s.add_dependency(%q<echoe>, [">= 0"])
45
+ end
46
+ end
@@ -0,0 +1,275 @@
1
+ require "rubygems"
2
+ require "time"
3
+ require "openssl"
4
+ require "rest_client"
5
+ require "json"
6
+ require File.dirname(__FILE__)+"/exceptions"
7
+
8
+ =begin rdoc
9
+ = DnsMadeEasy/API
10
+
11
+ Ruby client for DNSMadeEasy API.
12
+
13
+ == Installation
14
+
15
+ # gem install environment
16
+
17
+ == Usage
18
+
19
+ require "rubygems"
20
+ require "dnsmadeeasy/api"
21
+
22
+ api_key = <your dnsmadeeasy api key>
23
+ secret_ket = <your dnsmadeeasy secret key>
24
+ api = DnsMadeEasy::Api(api_key, secret_key)
25
+ api.list_records "sigfig.com"
26
+
27
+ To run in sandbox mode (you need an account and api key at sandbox.dnsmadeeasy.com).
28
+ This is a great way to test your application without changing your production DNS entries.
29
+
30
+ api = DnsMadeEasy::Api(api_key, secret_key, true)
31
+ api.list_records "sigfig.com"
32
+
33
+ == Command line tool
34
+
35
+ The client comes with a command line tool "dme". Use "dme --help" to see how to use the command.
36
+ The command line tool requires that your api credentials be stored in /etc/dnsmadeeasy/api.keys as
37
+ api_key=<api_key>
38
+ secret_key=<secret_key>
39
+
40
+ The command line tool also allows the running of queries in the sandbox mode. To do so, create
41
+ /etc/dnsmadeeasy/api_sandbox.keys with your sandbox api key and secret key and use the --sandbox option
42
+ with every command.
43
+
44
+ =end
45
+
46
+ module DnsMadeEasy
47
+ TTL_ONE_HOUR = 3600
48
+ TTL_HALF_HOUR = 1800
49
+ TTL_FIVE_MINS = 300
50
+ TTL_ONE_DAY = 86400
51
+ TTL_ONE_WEEK = 604800
52
+
53
+ class Api
54
+ # Initialize the class with the api key, the secret key, and an optional
55
+ # flag to run the queries in DNSMadeEasy's sandbox mode
56
+ def initialize(api_key, secret_key, sandbox=false)
57
+ @api_key = api_key
58
+ @secret_key = secret_key
59
+ @sandbox = sandbox
60
+ end
61
+
62
+ # List all domains in the account.
63
+ # Returns an array of domain names in the account.
64
+ # Throws DnsMadeEasy::AuthorizationFailedError
65
+ def list_domains
66
+ begin
67
+ response = RestClient.get request_url, headers
68
+ response_hash = JSON.parse(response)
69
+ return response_hash.has_key?("list") ? response_hash["list"] : []
70
+ rescue RestClient::Forbidden => e
71
+ raise DnsMadeEasy::AuthorizationFailedError
72
+ end
73
+ end
74
+
75
+ # Delete all domains in the account.
76
+ # Returns true or throws an exception.
77
+ # Throws DnsMadeEasy::AuthorizationFailedError
78
+ def delete_domains!
79
+ begin
80
+ response = RestClient.delete request_url, headers
81
+ return true
82
+ rescue RestClient::Forbidden => e
83
+ raise DnsMadeEasy::AuthorizationFailedError
84
+ end
85
+ end
86
+
87
+ # Create a new domain entry.
88
+ # Returns a hash of the newly created domain entry.
89
+ # Throws DnsMadeEasy::InvalidDomainNameError, DnsMadeEasy::DuplicateDomainError, or DnsMadeEasy::AuthorizationFailedError
90
+ def create_domain!(domain)
91
+ begin
92
+ response = RestClient.put request_url(:path => "#{domain}"), {}, headers
93
+ 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
+ end
104
+ end
105
+
106
+ # Delete a domain entry.
107
+ # Returns true or throws an exception.
108
+ # Throws DnsMadeEasy::UnknownDomainError, DnsMadeEasy::RequestFailedError, or DnsMadeEasy::AuthorizationFailedError
109
+ def delete_domain!(domain)
110
+ begin
111
+ 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
120
+ end
121
+ end
122
+
123
+ # Describe a domain entry.
124
+ # Returns a hash of the domain entry.
125
+ # Throws DnsMadeEasy::UnknownDomainError or DnsMadeEasy::AuthorizationFailedError
126
+ def describe_domain(domain)
127
+ begin
128
+ response = RestClient.get request_url(:path => "#{domain}"), headers
129
+ return JSON.parse(response)
130
+ rescue RestClient::ResourceNotFound => e
131
+ raise DnsMadeEasy::UnknownDomainError, domain
132
+ rescue RestClient::Forbidden => e
133
+ raise DnsMadeEasy::AuthorizationFailedError
134
+ end
135
+ end
136
+
137
+ # List records for a domain.
138
+ # Returns an array of hashes, each hash representing a dns entry.
139
+ # Throws DnsMadeEasy::UnknownDomainError or DnsMadeEasy::AuthorizationFailedError
140
+ def list_records(domain, filter={})
141
+ begin
142
+ response = RestClient.get request_url(:path => "#{domain}/records", :query => filter), headers
143
+ return JSON.parse(response)
144
+ rescue RestClient::ResourceNotFound => e
145
+ raise DnsMadeEasy::UnknownDomainError, domain
146
+ rescue RestClient::Forbidden => e
147
+ raise DnsMadeEasy::AuthorizationFailedError
148
+ end
149
+ end
150
+
151
+ # Create a new dns record
152
+ # record should be a hash with the following values:
153
+ #
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
159
+ #
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.
165
+ #
166
+ # Returns a hash of the newly created dns entry.
167
+ # Throws DnsMadeEasy::InvalidRecordError, DnsMadeEasy::UnknownDomainError, or DnsMadeEasy::AuthorizationFailedError
168
+ def create_record!(domain, record)
169
+ validate_record(record)
170
+ request_data = {
171
+ :gtdLocation => "DEFAULT"
172
+ }.merge(record)
173
+ begin
174
+ response = RestClient.post request_url(:path => "#{domain}/records"), request_data.to_json, headers(:content_type => "application/json")
175
+ 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
+ end
183
+ end
184
+
185
+ # Delete a dns record.
186
+ # Returns true or throws an exception.
187
+ # Throws DnsMadeEasy::UnknownRecordError, or DnsMadeEasy::AuthorizationFailedError
188
+ def delete_record!(domain, record_id)
189
+ begin
190
+ 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
196
+ end
197
+ end
198
+
199
+ # Update an existing dns record
200
+ # Returns the latest hash of the dns entry.
201
+ # Throws DnsMadeEasy::InvalidRecordError, DnsMadeEasy::UnknownRecordError, or DnsMadeEasy::AuthorizationFailedError
202
+ def update_record!(domain, record_id, record)
203
+ begin
204
+ response = RestClient.put request_url(:path => "#{domain}/records/#{record_id}"), record.to_json, headers(:content_type => "application/json")
205
+ 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
+ end
213
+ end
214
+
215
+ # Describe an existing dns record.
216
+ # Returns a hash of the dns entry.
217
+ # Throws DnsMadeEasy::UnknownRecordError, or DnsMadeEasy::AuthorizationFailedError
218
+ def describe_record(domain, record_id)
219
+ begin
220
+ response = RestClient.get request_url(:path => "#{domain}/records/#{record_id}"), headers
221
+ 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
226
+ end
227
+ end
228
+
229
+ private
230
+
231
+ # Validate a dns record entry
232
+ def validate_record(record)
233
+ # check missing fields
234
+ required_fields = [:ttl, :data, :type, :name]
235
+ required_fields.each do |field|
236
+ raise DnsMadeEasy::InvalidRecordError, "Missing field #{field}" unless record.has_key?(field)
237
+ end
238
+
239
+ # check record types
240
+ 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])
242
+
243
+ # check non empty fields
244
+ non_empty_fields = [:ttl, :data]
245
+ non_empty_fields.each do |field|
246
+ raise DnsMadeEasy::InvalidRecordError, "Field #{field} cannot be empty" if record[:data].empty?
247
+ raise DnsMadeEasy::InvalidRecordError, "Field #{field} cannot be nil" if record[:data].nil?
248
+ end
249
+ end
250
+
251
+ # Create the api request url
252
+ def request_url(info={})
253
+ request_url = @sandbox ? "http://api.sandbox.dnsmadeeasy.com/V1.2/domains" : "http://api.dnsmadeeasy.com/V1.2/domains"
254
+ request_url = "#{request_url}/#{info[:path]}" if info.has_key?(:path)
255
+ if info.has_key?(:query) && !info[:query].empty?
256
+ query = info[:query].to_a.map { |x| "#{x[0]}=#{x[1]}" }.join("&")
257
+ request_url = "#{request_url}?#{query}"
258
+ end
259
+ return request_url
260
+ end
261
+
262
+ # Return the api request headers
263
+ def headers(more_headers={})
264
+ time_now = Time.now.httpdate
265
+ hmac = OpenSSL::HMAC.hexdigest('sha1', @secret_key, time_now)
266
+ default_headers = {
267
+ :"x-dnsme-hmac" => hmac,
268
+ :"x-dnsme-requestDate"=> time_now,
269
+ :"x-dnsme-apiKey" => @api_key,
270
+ :accept => "application/json"
271
+ }
272
+ return default_headers.merge( more_headers )
273
+ end
274
+ end
275
+ end
@@ -0,0 +1,44 @@
1
+ module DnsMadeEasy
2
+ # Generic request failure error
3
+ class RequestFailedError < StandardError
4
+ end
5
+
6
+ # Error raised when authorization fails
7
+ class AuthorizationFailedError < RequestFailedError
8
+ def initialize
9
+ super "Could not authorize request with the given api key and secret key"
10
+ end
11
+ end
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
32
+ end
33
+
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"
38
+ end
39
+ end
40
+
41
+ # Error raised when an invalid dns entry is being created
42
+ class InvalidRecordError < RequestFailedError
43
+ end
44
+ end
metadata ADDED
@@ -0,0 +1,138 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: dnsmadeeasy-api
3
+ version: !ruby/object:Gem::Version
4
+ hash: 25
5
+ prerelease:
6
+ segments:
7
+ - 0
8
+ - 9
9
+ version: "0.9"
10
+ platform: ruby
11
+ authors:
12
+ - Nitesh Goel
13
+ autorequire:
14
+ bindir: bin
15
+ cert_chain: []
16
+
17
+ date: 2011-07-06 00:00:00 Z
18
+ dependencies:
19
+ - !ruby/object:Gem::Dependency
20
+ name: rest-client
21
+ prerelease: false
22
+ requirement: &id001 !ruby/object:Gem::Requirement
23
+ none: false
24
+ requirements:
25
+ - - ">="
26
+ - !ruby/object:Gem::Version
27
+ hash: 3
28
+ segments:
29
+ - 0
30
+ version: "0"
31
+ type: :runtime
32
+ version_requirements: *id001
33
+ - !ruby/object:Gem::Dependency
34
+ name: json
35
+ prerelease: false
36
+ requirement: &id002 !ruby/object:Gem::Requirement
37
+ none: false
38
+ requirements:
39
+ - - ">="
40
+ - !ruby/object:Gem::Version
41
+ hash: 3
42
+ segments:
43
+ - 0
44
+ version: "0"
45
+ type: :runtime
46
+ version_requirements: *id002
47
+ - !ruby/object:Gem::Dependency
48
+ name: rake
49
+ prerelease: false
50
+ requirement: &id003 !ruby/object:Gem::Requirement
51
+ none: false
52
+ requirements:
53
+ - - ">="
54
+ - !ruby/object:Gem::Version
55
+ hash: 3
56
+ segments:
57
+ - 0
58
+ version: "0"
59
+ type: :development
60
+ version_requirements: *id003
61
+ - !ruby/object:Gem::Dependency
62
+ name: echoe
63
+ prerelease: false
64
+ requirement: &id004 !ruby/object:Gem::Requirement
65
+ none: false
66
+ requirements:
67
+ - - ">="
68
+ - !ruby/object:Gem::Version
69
+ hash: 3
70
+ segments:
71
+ - 0
72
+ version: "0"
73
+ type: :development
74
+ version_requirements: *id004
75
+ description: Ruby client for DNSMadeEasy API.
76
+ email: nitesh@wikinvest.com
77
+ executables:
78
+ - dme
79
+ extensions: []
80
+
81
+ extra_rdoc_files:
82
+ - README.rdoc
83
+ - bin/dme
84
+ - lib/dnsmadeeasy/api.rb
85
+ - lib/dnsmadeeasy/exceptions.rb
86
+ files:
87
+ - Manifest
88
+ - README.rdoc
89
+ - Rakefile
90
+ - bin/dme
91
+ - lib/dnsmadeeasy/api.rb
92
+ - lib/dnsmadeeasy/exceptions.rb
93
+ - dnsmadeeasy-api.gemspec
94
+ homepage: http://rubygems.org/gems/dnsmadeeasy-api
95
+ licenses: []
96
+
97
+ post_install_message: |-
98
+ Create /etc/dnsmadeeasy/api.keys and/or /etc/dnsmadeeasy/api_sandbox.keys with the following information
99
+ api_key=<your api key>
100
+ secret_key=<your secret key>
101
+ to use the dme binary.
102
+ rdoc_options:
103
+ - --line-numbers
104
+ - --inline-source
105
+ - --title
106
+ - Dnsmadeeasy-api
107
+ - --main
108
+ - README.rdoc
109
+ require_paths:
110
+ - lib
111
+ required_ruby_version: !ruby/object:Gem::Requirement
112
+ none: false
113
+ requirements:
114
+ - - ">="
115
+ - !ruby/object:Gem::Version
116
+ hash: 3
117
+ segments:
118
+ - 0
119
+ version: "0"
120
+ required_rubygems_version: !ruby/object:Gem::Requirement
121
+ none: false
122
+ requirements:
123
+ - - ">="
124
+ - !ruby/object:Gem::Version
125
+ hash: 11
126
+ segments:
127
+ - 1
128
+ - 2
129
+ version: "1.2"
130
+ requirements: []
131
+
132
+ rubyforge_project: dnsmadeeasy-api
133
+ rubygems_version: 1.8.5
134
+ signing_key:
135
+ specification_version: 3
136
+ summary: Ruby client for DNSMadeEasy API.
137
+ test_files: []
138
+